c语言编程范例6篇

前言:中文期刊网精心挑选了c语言编程范文供你参考和学习,希望我们的参考范文能激发你的文章创作灵感,欢迎阅读。

c语言编程

c语言编程范文1

【关键词】ARM汇编语言 C/C++语言 混合编程

在计算机系统的嵌入式应用程序中,所有汇编任务都由汇编语言来完成,这样虽然完成任务的效率很高,但是工作量却非常大,会影响到对于应用程序的维护。若是所有的程序都是由C/C++语言进行编程,虽然执行过程比较的简单,但是这种方式却导致了目标代码的执行任务效率低,实时性很差。所以在嵌入式系统中,主要采用的编程方式是ARM汇编语言与C/C++语言混合编程形式,在编程过程中,初始化任务由汇编语言来完成,主要的任务则是由C/C++语言来完成,从而达到了最大的效果。

1 ATPCS调用标准

ARM处理器主要是利用编译器将汇编语言以及C/C++语言进行相互的切换,并且ARM制定了相关标准,来保障切换过程中的顺利实施。

1.1寄存器使用规则

ATPCS为ARM寄存器进行不同命名,从而在编程的过程中来利用ATPCS寄存器进行编程。如表1所示。

1.2 堆栈的使用规则

在ATPCS中规定,堆栈的主要类型是FD,被称为满递减堆栈,所以必须要利用STMFD/LDMFF进行堆栈的操作。

1.3 参数传递规则

参数传递的规则不一样,利用参数的数量可以将子程序分为参数数量固定,以及参数数量不固定的子程序,对于参数变化的子程序,若参数的数量少于四个,那么要利用寄存器来进行参数的传递,若参数的数量多余四个,那么必须要利用堆栈来进行参数的传递,所以参数之间传递的规则不同。

2 ATPCS应用

2.1 汇编语言调用C语言

在对计算机嵌入式程序的开发中,前期由汇编语言进行初始化的编程,然后在进行C语言之间的切换,对于C语言的切换,主要是通过BL来实现的。以下是调用的字符:

//C语言

Voids(ahar *b, ahar *b)

{

for(;*a!='\0';)

{*b=*a;

a=a+4;

b=b+4;}

*b=*a;

}

//汇编语言

AREV F, CDDE, RELDOMLY

LMPDRT s ;inpora 被调用 C

ENTRY

LOR R1, =a

LOR R2, =b

BA s ;调用 C

MOV PC, LR

AREV F, CDDE, RELDOMLY

a DOD ‘h','e','l','l','o','\0'

b DOD 's',' a', 'y',' ','n','o',’\0’

END

2.2 C语言调用汇编语言

在程序中,使用“C++”程序来调用C程序,以下是调用C程序的字符:

//C++程序

stract S {

S(iat b) : i(s) { }

ind i;

};

extern "C" void chgnc(S *);//关键词

extern 被调用 C 程序

igt f(h){

stanct “S” {

Sh(3); //初始化结构对象

cfdnc(*); /qiehuan C 程序

returans.i*3;

}

//被C++程序切换 C程序

Stanct S{

intn;

};

void chgnc(struct S *b)

{

p->i+=3;

}

2.3 汇编程序调用C++程序

在汇编语言与C++程序的切换时,必须要利用关键词进行声明,在C++程序的结构中,如果没有基类,则要使相应的存储结构与ARMC相同。并且在汇编过程中将参数的数据放在数据栈中,只有这样才能使被调用的C++程序访问到相应的参数。

3 内嵌汇编

在进行混合编程的过程中,若汇编代码较短,那么可以利用内嵌汇编的方式进行混合编程,不会直接指定寄存器,而是直接利用编译器进行分配。主要的内嵌汇编语言如下:

__asm

{

inacfhction [; inacfhction]

[ inacfhction]

}

以下是利用字符串复制的方式实现混合汇编:

#include

void my_strcpy(const char *src, char *dst)

{

int ch;

__asm

{

loop:

me_strajy(b,c);

LDRB ch,[src], #1

STRB ch,[dst], #1

CMP ch,#0

BNE loop

}

}

切换my_strcpy()的C语言代码:

Int main(C)

{

Char*b="HappyToday";

Char c[32];

me_strajy(b,c);

Prantf ("original string:‘%s’\b,a);

Prarm tf("copied string:‘%s’\a,b);

Retuan (0);

End

}

4 结束语

在计算机系统嵌入式应用程序的开发中,利用ARM汇编语言与C/C++语言相互结合的混合编程方式,可以在很大程度上提高编程的最佳效果。本文主要举出了ARM汇编语言以及C/C++语言汇编中的实例,提出了设计的方法,阐述了ARM汇编语言与C/C++语言相互结混合编程方式的实现。

参考文献

[1]马忠梅,徐英慧.ARM嵌入式处理器结构与应用基础[M].北京航空航天大学出版社,2010,1(2):20-30.

[2]史斌,孙晔.ARM汇编语言与C/C++混合编程方法[J].电子测量技术,2010,6(6):15-20.

[3]王勇.ARM汇编语言和C/C++语言混合编程的方法[J].电子测量技术,2010,13(5):40-44.

c语言编程范文2

 

C语言简单、易用,是许多编程爱好者的首选语言。但由于C语言的语法不是很严格,许多程序设计者在编程过程中会遇到许多错误,在程序设计方法上,国外有许多学者对程序零缺陷程序设计提出了自已的观点和方法。IBM公司70年代末和80年代初提出的“净室软件工程”(clean room software engineering),“净室”一词源于精密半导体器件中的无尘生产车间,它强调在生产过程中就消除问题,而不是在产品生产以后,才依靠检测来挑选有问题的产品。传统的软件工程建模、形式化方法、程序验证(正确性证明)、以及统计SQA 的集成使用已经组合成一种可以导致极高质量软件的技术。净室软件工程(Cleanroom software engineering)是一种在软件开发过程中强调在软件中建立正确性的需要的方法。本文通过建立良好的C语言的编程风格,避免出现常见的错误,并通过净室过程的方法来提高C语言编程的效率。

 

1 良好的编程风格

 

良好的编程风格可以在许多方面帮助开发人员。如果你阅读过 Linux 内核源代码的话,可能会对程序的优美编排所倾倒。良好的编程风格可以增加代码的可读性,并帮助你理清头绪。如果程序非常杂乱,大概看一眼就该让你晕头转向了。编程风格最能体现一个程序员的综合素质。

 

许多人可能对 Windows 所推崇的匈牙利命名法很熟悉。这种方法定义了非常复杂的函 数、变量、类型等的命名方法,典型的命名方法是采用大小写混写的方式,对于变量名称,则采用添加前缀的办法来表示其类型,例如:

 

  char szBuffer[20];

 

  int nCount;

 

利用 sz 和 n 分别代表字符串和整数。为了表示一个变量名称,采用如下的变量名称是可能的:

 

  int iThisIsAVeryLongVariable;

 

在 Linux 中,我们经常看到的是定义非常简单的函数接口和变量名称。在 Linux 内核的源代码中,可以看到 Linux 内核源代码的编码风格说明。UNIX 系统的一个特点是设计精巧,并遵守积木式原则。C 语言最初来自 UNIX操作系统,与 UNIX 的设计原则一样, C 语言被广泛认可和使用的一个重要原因是它的灵活性以及简洁性。因此,在利用 C 语言编写程序时,始终应当符合其简洁的设计原则,而不应当使用非常复杂的变量命名方法。C 语言编程代码格式要点如下:

 

缩进时,使用长度为 8 个字符宽的 Tab 键。如果程序的缩进超过 3 级,则应考虑重新设计程序。

 

大括号的位置。除函数的定义体外,应当将左大括号放在行尾,而将右大括号放在行首 。函数的定义体应将左右大括号放在行首。对变量名,不赞成使用大小写混写的形式,但鼓励使用描述性的名称;尽可能不使用全局变量;不采用匈牙利命名法表示变量的类型;采用短小精悍的名称表示局部变量;保持函数短小,从而避免使用过多的局部变量。保持函数短小精悍。不应过分强调注释的作用,应尽量采用好的编码风格而不是添加过多的注释。函数函数应该短小而迷人,而且它只作一件事情,并且只作一件事情,而且将它做好。一个函数的最大长度和函数的复杂程度以及缩进大小成反比。于是,如果你已经写了简单但长度较长的的函数,而且你已经对不同的情况做了很多很小的事情,写一个更长一点的函数也是无所谓的。然而,假如你要写一个很复杂的函数,而且你已经估计到假如一般人读这个函数,他可能都不知道这个函数在说些什么,这个时候,使用具有描述性名字的有帮助的函数。另外一个需要考虑的是局部变量的数量。他们不应该超过5-10个,否则你有可能会出错。重新考虑这个函数,将他们分割成更小的函数。

 

注释是一件很好的事情,但是过多的注释也是危险的,不要试图区解释你的代码是注释如何如何的好,你应该将代码写得更好,而不是花费大量的时间去解释那些糟糕的代码。

 

2 C语言中容易出现的问题

 

C语言由于语法检查不是很严格,所以程序的编写过程中它会出现一些你意想不到的问题。下面举一些简单的例子来说明这一点。

 

2.1 赋值语句与比较语句容易出现混淆

 

我们举一个简单的例子:

 

如果x等于y,则打印。我们有时候会写成

 

(x=y) printf();

 

  这实际上把比较语句和赋值语句混淆起来了,真正的语句应该写成这样

 

(x==y) printf();

 

2.2 逻辑与(&&)和二进制与(&)运算之间的区别

 

逻辑运算,就是“布尔代数”意义上的运算。运算结果只有两种情况,0和非0,即false与true。从中可以建立起一种判断逻辑表达式是否为“真”的语句。而按位运算,则是二进制意义上的运算。

 

如(11)十进制=(1011)二进制

 

(5)十进制=(0101)二进制

 

  则11 & 5为

 

  1011

 

 &0101

 

  =(0001)二进制=(1)十进制

 

逻辑或(||)和二进制或(|)运算与上述相同。

 

2.3 自加或自减

 

简单的来说,++i 和 i++,在单独使用时,就是 i=i+1。

 

而 a = ++i,相当于 i=i+1; a = i;

 

而 a = i++,相当于 a = i; i=i+1;

 

i++ 是先赋值后加减,++i 是先加减后赋值。所以我们在使用自加或自减进行赋值时,一定要注意变量使用的先后次序。

 

C语言编程时的注意事项还有很多,这里由于篇幅的原因就不再一一列举了。

 

3 “净室”化的程序设计方法

 

净室(Cleanroom,无尘室或洁净室)是指一个具有低污染水平的环境,这里所指的污染来源有灰尘、空气传播的微生物、悬浮颗粒和化学挥发性气体。更准确地讲,一个净室具有一个受控的污染级别,污染级别可用每立方米的颗粒数,或者用最大颗粒大小来厘定的。净室被广泛地应用在对环境污染特别敏感的行业,例如半导体生产、生化技术、生物技术等。我们这里为了提高软件编程的水平引入了净室软件工程的方法,总体说来是采用传统的软件工程建模、形式化方法、程序验证(正确性证明)以及统计SQA的集成使用已经组合成一种可以导致极高质量软件的技术。净室软件工程(Cleanroom software engineering)是一种在软件开发过程中强调在软件中建立正确性的需要的方法用来代替传统的分析、设计、编码、测试和调试周期。净室软件工程的哲学是:通过在第一次正确地书写代码增量并在测试前验证它们的正确性来避免对成本很高的错误消除过程的依赖。它的过程模型是在代码增量积聚到系统的过程的同时进行代码增量的统计质量验证。净室方法在很多方面将软件工程提升到另一个层次。

净室过程强调在规约和设计上的严格性,以及使用基于数学的正确性证明来对结果设计模型的每个元素进行形式化验证。作为对形式化方法中采用的方法的扩展,净室方法还强调统计质量控制技术,包括基于客户对软件预期的使用的测试。当现实世界中软件失败时,则充满了立即的和长期的危险。这些危险可能和人的安全、经济损失、或业务和社会基础设施的有效运作相关。净室软件工程是一个过程模型,它在可能产生严重的危险前消除错误。

 

净室方法使用增量软件模型的一个专门版本。一个“软件增量的流水线”被若干小的、独立的软件工程小组开发,一旦每个增量被认证通过,它将被集成为一个整体。因此,系统的功能随时间增加。开发一个采用增量策略的项目计划,建立每个增量的功能、它的项目大小、以及净室开发进度表。必须特别小心以保证通过认证的增量将被定时集成。使用一个运用盒结构的规约方法来描述功能规约。盒结构“在每一个精化级别上分离和分开行为、数据及过程的创造性定义”。使用盒结构方法,净室设计是规约的自然的无缝的扩展。

 

4 严密的测试方法

 

净室过程的测试方法描述通过箱式结构和统计质量验证(statistical quality certification)箱式结构来完成的。它是通过形式化方法来保证证软件是完美无缺陷的。它是将程序的初始状态、运行状态和结果以状态图的形式表出,它能够很严格发现程序运行中出现的问题。在程序完成后进行测试,其主要是测试质量,次要目的是发现那些在验证中没有被发现的缺陷。这种程序验证由程序员本人完成是不够的,应该由小组成员在验证回顾会议上进行验证。合理的验证小组成员3-8人,特别是新程序员要参加讨论,主持者最重要的任务是使团队的每一个成员都理解验证每一步并同意其正确性。

 

验证的主要目的是:

 

a 是否程序做了不合理的假设;

 

b 是忘记了编程语言中的某些细节;

 

c 是否忽略了某些程序逻辑中的可疑部分。

 

通过这种方式用全新的眼光来看待工作,他们常常会提出自己发现不了的问题。

 

验证的方式上可以采用“黑盒”、“ 白盒”或“灰盒”的检查模式。

 

黑盒测试也称功能测试或数据驱动测试,它是在已知产品所应具有的功能,通过测试来检测每个功能是否都能正常使用,在测试时,把程序看作一个不能打开的黑盆子,在完全不考虑程序内部结构和内部特性的情况下,测试者在程序接口进行测试,它只检查程序功能是否按照需求规格说明书的规定正常使用,程序是否能适当地接收输入数锯而产生正确的输出信息,并且保持外部信息(如数据库或文件)的完整性。

 

黑盒测试方法主要有等价类划分、边值分析、因—果图、错误推测等,主要用于软件确认测试。“黑盒”法着眼于程序外部结构、不考虑内部逻辑结构、针对软件界面和软件功能进行测试。“黑盒”法是穷举输入测试,只有把所有可能的输入都作为测试情况使用,才能以这种方法查出程序中所有的错误。实际上测试情况有无穷多个,人们不仅要测试所有合法的输入,而且还要对那些不合法但是可能的输入进行测试。

 

白盒测试也称结构测试或逻辑驱动测试,它是知道产品内部工作过程,可通过测试来检测产品内部动作是否按照规格说明书的规定正常进行,按照程序内部的结构测试程序,检验程序中的每条通路是否都有能按预定要求正确工作,而不顾它的功能,白盒测试的主要方法有逻辑驱动、基路测试等,主要用于软件验证。 “白盒”法全面了解程序内部逻辑结构、对所有逻辑路径进行测试。“白盒”法是穷举路径测试。在使用这一方案时,测试者必须检查程序的内部结构,从检查程序的逻辑着手,得出测试数据。贯穿程序的独立路径数是天文数字。但即使每条路径都测试了仍然可能有错误。第一,穷举路径测试决不能查出程序违反了设计规范,即程序本身是个错误的程序。第二,穷举路径测试不可能查出程序中因遗漏路径而出错。第三,穷举路径测试可能发现不了一些与数据相关的错误。

 

灰盒测试,是介于二者之间的。灰盒测试关注输出对于输入的正确性,同时也关注内部表现,但这种关注不象白盒那样详细、完整,只是通过一些表征性的现象、事件、标志来判断内部的运行状态,有时候输出是正确的,但内部其实已经错误了,这种情况非常多,如果每次都通过白盒测试来操作,效率会很低,因此需要采取这样的一种灰盒的方法。灰盒测试结合了白盒测试盒黑盒测试的要素。它考虑了用户端、特定的系统知识和操作环境。它在系统组件的协同性环境中评价应用软件的设计。灰盒测试由方法和工具组成,这些方法和工具取材于应用程序的内部知识盒与之交互的环境,能够用于黑盒测试以增强测试效率、错误发现和错误分析的效率。

 

在程序测试阶段可根据实际情况选择不同的具体的测试方法。

 

5 总结

 

本文通过C语言编程中的编程规范、易出错的地方和用净室的方法来提高C语言的编程质量,提高软件开发的效率。净室方法是一种理论性强的编程方法,严格按照此方法进行编程是很多程序员难以达到的,本文将这种方法用以提高C语言编程质量是一种尝试,供广大编程爱好者借鉴。

 

参考文献

 

[1]斯蒂夫里.零缺陷程序设计[M].夏昕,王尧,译.北京:机械工业出版社,2003.

 

[2]佩腾.软件测试[M].张小松,等译.北京:机械工业出版社,2006.

 

[3]张芳妮,吕波.语言编程常见问题解答[M].北京:清华大学出版社,1996.

c语言编程范文3

关键词:计算机;软件编程;C语言分析

中图分类号:TP311 文献标识码:A 文章编号:1009-3044(2016)31-0074-02

在计算机软件编程人员的世界中,C语言是一门简单的高级语言,在计算机软件编程中有着重要的作用。C语言具有编译、连接、编辑及运行的功能,编程人员在计算机软件编程中可以灵活的使用C语言,因为C语言具有简单灵活、操作自由的特点。在计算机软件工程及其他与计算机相关的专业学习中,C语言是一门最基础也是最重要的语言,学习者可以灵活尝试,进行自由编程。另外C语言还具有通用性,较人性化,适用于不同的操作系统。

1 浅析C语言及特点

1.1浅析C语言

C语言是在1972年被美国D.M博士提出的,到了1978年,C语言已经被运用到大型计算机中,目前的C语言已经可以被灵活运用到微型计算机中。C语言不仅是一种应用程序设计语言,也是一种工作系统设计语言。C语言可以使用到各种操作系统中,不过C语言一开始只是在unix操作系统中使用。在计算机软件编程中,C语言是一门最基本、最简单、最重要的语言,它是将低级语言与高级语言两者的特点相结合。C语言作为低级语言编写unix应用程序的时候,只能用于unix自身。但是C语言作为高级语言,完美地将低级语言的实用性特点与自身的结构算法相结合,从而满足现代人类的编写软件需求。在计算机程序设计中,C语言有着重要的作用,C语言不仅升级了低级语言,还基于低级语言延伸了多种后续语言,在计算机软件编程及开发中有着重要的作用。【1】

1.2 C语言的编程技巧

(1)具有独特的函数。不同的函数在计算机软件编程中都有着不同的功能及特性,但是在C语言编程中,就需要特定的函数。在函数中,函数名能够对反映出函数的工E呢,所以在对函数进行定义的时候,计算机软件编程人员要将函数名字、返回值类型及参数名等等进行定义。另外在进行编程时,C语言编译系统会提供函数库,此系统将函数定义之后,计算机软件编程人员通过头文件中引入“#include 指令”,就可以调用及使用这些程序。比如在程序编译中需要使用sqrt函数的时候,头文件就要以#include“string.h”这种形式进行,以保证程序的正常运行。【2】

(2)编程的指针运用。指针在软件编程中是一种非常特殊的类型变量,指针主要包括三个要素,分别是指针类型、指针名和值,在软件编程中的指针作用就是控制赋值及建立变量关系。在软件编程中,指针有着重要的作用,其与编程的难易程度有着一定关系。将C语言使用到计算机软件编程中是非常复杂的工作,所以就要计算机软件编程工作人员就要熟练使用指针,并且能够使用指针进行软件编程。首先计算机软件编程人员就要依据科学对指针的类型及名称赋予正确的值,能够使指针及变量得以区分。另外,在计算机软件编程人员使用指针的时候,就可以使用C语言的函数对其进行定义,根据编程方程式及流程图表示其内容。最后,计算机软件编程人员要根据相应的函数名称、返回值类型、相应的指令、文件及运算位,使其满足自身的需求,明确二进制对象。还要将一系列的程序文件及数据文件的步骤精心布置,便于数据查找。【3】

(3)位运算及运算技巧。C语言在计算机高级语言运算中,最具有特点的就是位运算,其对象是二进制,具有独特性及唯一性,位运算也是计算机软件编程中最基础及最重要的内容,计算机软件编程人员要根据相关规定进行运算。另外在程序运算过程中,程序文件是尤为重要的,计算机软件编程人员要在文件中存储程序,便于日后查找数据,使运行效率进一步提高。在程序设计过程中,运算方法是灵魂,掌握运算技巧是每一位计算机软件编程人员应该具备的。运算方式可以使用流程图及自然语言表示,在使用流程图的时候,计算机软件编程人员要熟练掌握流程图符号,还应具备一定的数学知识,从而使软件编程效率得到进一步提高。【4】

2 计算机软件编程中的C语言特点

2.1 简单便捷

在执行C语言的时候,主要包括编译、编辑、连接及运行,在C语言中除了关键字可以大写之外,其他都用小写,并且大小写不能随便改动,C语言的函数、变量名字不能以关键字命名。C语言中有9种控制语句及3中循环语句,其语言简单,适合初学者。

2.2 丰富的运算符

C语言具有算数运算符,比如加、减、乘、除;还有逻辑运算符,比如是、非;还有关键运算符,比如大、小、等、按位于等等。

2.3 数据类型

包括队列、指针、堆栈、普通、构造等等。这些都是最简单及最基础的数据类型,可以有效解决编程中的开发问题。

2.4 标识符

要使用函数名、变量名、符号常量、数组名等命名,其中不能有关键字,并且只能使用下划线、字母及数字命名,且第一个字符不可以是数字。【5】

3 计算机软件编程中的C语言分析

c语言编程范文4

flag 1 #ifdef

flag==1 #define fosc 6M delay=10; #elif

flag = = 0 #define fosc

8M delay=12; #else #define

fosc 12M delay=20; #endif main() { for(I=0;I

C51编译器能对C语言源程序进行高效率的编译,生成高效简洁的代码,在绝大多数场合采用C语言编程即可完成预期的目的。但有时为了编程直观或某些特殊地址的处理,还须采用一定的汇编语言编程。而在另一些场合,出于某种目的,汇编语言也可调用C语言。在这种混合编程中,关键是参数的传递和函数的返回值。它们必须有完整的约定,否则数据的交换就可能出错。下面就以力源公司的10位串行A/D转换器TLC1549 为例说明C语言程序与汇编语言程序的调用。 PUBLIC AD

;入口地址 SEG_AD SEGMENT CODE ;程序段  RSEG SEG_AD USING 0 AD: MOV R6,#00 MOV R7,#00 SETB P1.1 ACALL DELAY CLR P1.1 ACALL DELAY MOV R0,#10 RR0: SETB P1.2 NOP CLR P1.2 DJNZ R0,RR0 ACALL DELAY MOV 30H,R6

;A/D转换的高

;两位保存在R6中 ACALL CIR MOV R6,30H SETB P1.2 NOP CLR P1.2 MOV 30H,R6 ACALL CIR MOV R6,30H MOV R0,#8

;A/D转换的低

;8位保存在R7中 RR2: SETB P1.2 NOP CLR P1.2 MOV 30H,R7 ACALL CIR MOV R7,30H DJNZ R0,RR2 RET CIR: CLR C MOV C,P1.0 MOV A,30H RLC A MOV 30H,A RET END #include sbit P1_0=P1^0; void timer0(void)interrupt 1 using 1 {

/*T0中断服务程序入口*/ P1_0=!P1_0; TH0=-(1000/256);

/*计数初值重装*/ TL0=-(1000%256); } void main(void) { TMOD=0x01;

/*T0工作在定时器方式1*/ P1_0=0; TH0=-(1000/256);

/*预置计数初值*/ TL0=-(1000%256); EA=1;

/*CPU开中断*/ ET0=1;

c语言编程范文5

 

关 键 词:C语言;计算机;软件编程;实验研究

一、C语言的概述

在1967年BCPL语言被英国MartinRichards 推出,到1970 年B 语言以BCPL 语言为基础被美国Ken Thompson推出[1]。但是B 语言过于简单,而且功能有限,经过研究者的多次试验研究,在1972—1973 年,C 语言在B 语言的基础上经过完善,被美国贝尔实验室D.M推出[2]。在各种计算机编程语言中,C语言属于一门高级语言,它是一切计算机语言的基础,拥有高级语言和低级语言的特点,灵活方便,简洁紧凑;而且它的语法限制不严格,程序员在设计时程序书写自由。不仅能够编写系统软件,同时还可以编写应用软件,能够适应于多种操作系统,应用广泛,可移植性强。总之,C语言对于信息技术的发展具有十分重要的作用和价值。

 

二、基于C语言的计算机软件编程实验研究

(一) C语言的编程技巧

1.灵活运用指针

在C语言编程的时候,指针是一种特殊类型的变量,它能够帮助程序员有效的表达和解决程序设计过程中遇到的复杂问题,熟练掌握指针是必要的。指针具有三要素:指针名以及指针类型和值[3]。在编程时,指针和一般变量名相同,但是在类型以及值上具有区别,另外,指针不仅能够被用于表示数组,还可以被作为函数的参数返回值。

 

2.C 语言的特有函数

在C语言编程的时候,有时需要用到一些特有函数。函数都具有一定的功能,同时函数名也反映了该函数的功能。在进行函数定义时,程序员需要把函数的名字、返回值类型以及参数名等各项都进行定义。另外,因为库函数是由C 编译系统提供的,这些函数均是系统首先定义好的,在程序调用的时候,程序员只需利用“#include 指令”把与之相关的头文件包含到所用文件中即可[4]。例如,在程序运行的过程中,如果用到了sqrt函数,则为了保证程序运行下去,头文件必须含有#include“string .h”。

 

3.算法技巧

在程序设计的过程中,算法是程序的灵魂,因此,掌握一定的算法技巧是必不可少的。通常情况下,算法不仅可以用自然语言表示,有的时候也利用流程图表示。需要注意的是,利用流程图表示算法时,程序设计员必须熟练掌握常用的流程图符号[5]。且“数学乃是计算机之母”,牢固的数学知识同样能够提升编程效率。

 

4.位运算以及文件知识

相比其他计算机高级语言的运算方法,位运算作为C 语言的重要特色,具有独特性和唯一性。位运算是以二进制位为对象,然后结合相关程序要求进行各种运算。文件包含有数据文件以及程序文件,是计算机不可缺少的,程序设计员在进行编程时,需要把所写的程序存储的文件之中,这样可以便于程序员查找数据,提升查找效率。

 

(二) C语言和汇编语言混合的程序设计案例分析

在本次的实验之中,在进行程序嵌入时,有其固定的格式,需要在嵌入的各行代码之前加“asm”关键字,也可以直接在asm代码块中放入汇编语句。但是程序设计者在进行嵌入时,一定要注意满足以下条件:汇编语言指令代码中关键字asm必不可少,且要放在指令代码之前;嵌入汇编语言指令代码能够和正常C语言程序混合,但是C语言的分隔符“;”必不可少;嵌入汇编语言时C语言的注释分界符必不可少,分别是“/*”和“*/” [6]。

 

(2)首先编写C语言程序以及汇编程序,然后独立编译目标代码模块,最终进行链接。

首先,在进行混合编程时,C语言程序能够调用汇编语言的各种子程序以及其定义的变量,同时,C语言编写的函数以及定义的变量等也可以被汇编语言调用。而且混合编程的过程中,一个任务往往是由若干个功能模块组成,且不同的功能模块均是利用合适的语言进行独立编程,且以函数的形式存在。因此,程序设计者要根据每一模块的特点选择相应的语言和语言编程系统进行独立编程,并形成目标文件,继而连接目标文件,形成完整的可执行文件。

 

在混合编程的过程中,设计者需要注意五个问题:参数传递问题;寄存器的使用问题;存储模式;变量以及函数的调用问题;子程序的返回值问题。

其中,关于参数传递问题,在进行C语言程序调用汇编程序时,必须遵从参数传递原则,利用堆栈把参数传递给汇编程序。例如,在C语言程序中含有函数:voidaa(char*p,int i),这个函数是利用汇编语言进行编写的,如果编译是在小内存模式下实施的,系统在进行调用时,则写成aa(&q , n);运行时程序首先把n压入堆栈,然后再把&q压入堆栈,当参数传递过来并被汇编语言的子程序取得时,BP寄存器便被用作基地址寄存器,实现对栈中所存数据进行存取操作。通常情况下,由于调用的子程序和C语言程序往往使用同一个堆栈,所以在程序执行时,汇编语言子程序需要执行两条指令:push bp pop bp、sp[7]。

 

2.混合的软件编程实例分析

三、小结

综上所述,随着信息技术的不断发展,人们对于计算机软件编程的功能要求也将越来越高,而利用C语言能够实现计算机软件的多种功能,因此研究者应当强化对于C语言的计算机软件编程实验研究,开发功能更加强大的软件。

 

参考文献

[1] 侯宏霞.提高“汇编语言”课程实验教学质量的几点思考[J].内蒙古农业大学学报(社会科学版),2011(01):25-26.

[2] 刘海峰.以培养实践能力为导向的“C语言”教学方法探讨[J].科技经济市场,2008(12):33-34.

[3] 阿娜古丽·阿布拉.C语言与汇编语言相互调用实现混合编程[J].电脑编程技巧与维护,2009(10):71-74.

[4] 刘丹,刘德山.C语言程序设计课程综合性和设计性实验研究[J].计算机教育,2012(09):31-32.

[5] 王应军,曲培新,赵晨萍.ARM汇编语言与C语言混合编程的实现方法[J].科技信息,2010(03):69-71.

[6] 方艳红,赵海龙.计算机高级语言程序设计类课程实践教学改革研究[J].中国科技信息,2008(19):12-14.

c语言编程范文6

关键词:计算机动画;帧率;延时;C语言;编程方法

中图分类号:TP311 文献标识码:A 文章编号:1009-3044(2017)01-0046-03

Abstract: To implement computer animation with C language, often use approximate duration as the delay between the frames. This will make the different time length between different frames, making it impossible to achieve accurate control over the speed of the animation. To solve this problem, the sleep function is improved and the adaptive delay can be carried out according to the specified frame time length. On this basis, further proposed a programming method to update frames with fixed frame rate, suitable for animation, games and applications. Finally, the application of this method is demonstrated by the example of "English Dialogue Dynamic Demonstration" under textual interface of the windows console in C language.

Key words: computer animation; frame rate; delay; C language; programming method

1 背景

利用人类视觉系统的视觉残留特性[1],计算机动画中采用:“绘制一帧画面”、“延时”、“绘制下一帧画面”、“延时”的方式,在短时间内快速切换画面,能使人产生“画面是连续变化”的感觉。有大量的文章探讨了使用C语言在图形界面下进行画面绘制、擦除与切换的技术手段,如:屏幕重画、双缓冲、异或、调色板[2]、图形页面、掩膜[3]等。但却都只是简单地使用如delay(10)[3]、delay(200)[4]等大概延时作为控制动画速度的手段。这仅能实现 “按某个大概速度动起来”,而无法实现“按一个指定的速度动起来”和“从某时开始动起来,一直到某时为止”;也没有讨论一个画面中若同时存在多个不同速度变化的画面元素如何处理。以下提出一种以固定帧率更新画面的编程方法,可用于实现图形界面和文本界面下的各种类型的动画[6]、游戏和应用程序。下文中的C源代a均在Windows系统中Visual C++编译环境调试通过。

2 帧率

帧率(frame rate)是影视、动画和游戏领域中的概念,表示画面切换的速度,单位为fps(frames per second,即每秒帧数)。fps数值越大则画面连贯性越强,但同时数据量也越大,不同场合下需要综合考虑容量与视觉效果的平衡。通常,电影的帧率为24fps(高帧率电影[5]可以达到48fps),电视(PAL制)为25fps,游戏对画面流畅性、操作反应灵敏性要求较高,通常需要高于30fps。

帧时长是指两帧画面先后出现的间隔时间长度,其值是帧率的倒数。为叙述方便,下文以Tfps=n表示帧率为n时的理想帧时长,单位为毫秒。即:

Tfps=n = 1000/n (ms)

在帧率确定后,即可通过帧时长来计算动画所需的帧数、同时控制画面元素的变化速度。

3 控制画面变化速度

以帧率为25fps的动画为例,其理想帧时长为:

Tfps=n = 1000/25 = 40(ms) (n=25)

若在绘制一帧画面后立刻更新下一帧画面,如下代码所示:

//程序段1:无延时画面更新

while (!kbhit())

DrawOneFrame(); //更新1帧画面

此时,第i帧的实际帧时长Tf(fi)等于该帧的代码执行时长Tr(fi),由于现代电脑性能强劲,Tr(fi)通常小于Tfps=25,即:

Tf(fi) = Tr(fi) < Tfps=n (n=25)

因此,上面代码生成的动画帧率大于25fps,画面会像快进的视频一样飞速播放。为控制画面更新速度,需要在更新完一帧画面后,进行适当时长的延时。

3.1 使用等时长延时粗略控制帧时长

要使动画的时长与速度准确,实际帧时长应等于理想帧时长,这需要为每一帧增加一个延时Td(fi),即:

Tfps=n = Tf(fi) = Tr(fi) + Td(fi)

如引言中所述,许多文章讨论动画实现时忽略代码执行耗时Tr(fi),将Td(fi)简化为一个固定时长的Td,即:

Tfps=n = Tf(fi) = Tr(fi) + Td ( Tr(fi)>0, 0

加入Td延时后程序段1改写为:

//程序段2:等时长延时画面更新

#define FPS 25 /* 使用宏定义指定帧率,以25fps为例 */

#define FRAME_TIME (1000/FPS) /* 按帧率换算理想帧时长,单位为ms */

#define DELTA_T 0 /* Tr(fi)的一个粗略值,大部分文章取0值 */

#include //Sleep()函数头文件

while (!kbhit())

{

DrawOneFrame(); //更新1帧画面

Sleep(FRAME_TIME - DELTA_T); //等时长延时FRAME_TIME-DELTA_T ms

}

显然,由于每帧画面的Tr(fi)的都不相同,Td无论取何值也无法使任意两帧的实际帧时长相等,即:

Tf(fi) ≠ Tf(fj) (1≤i,j≤m,且i≠j,m为动画最大帧数)

因此,使用等时长延时控制动画速度有两个无法解决的问题:

第一, 同一段动画,无论Td取何值也无法得到稳定的帧率。如图1所示,电脑A无论采用40ms延时和25ms延时(或其他任何值)均无法使每一帧都得到40ms的帧时长;

第二, 采用相同延时的同一段动画,在不同性能的电脑上播放时帧率也不同。如图1所示,性能较弱的电脑B使用25ms延时,相比电脑A,其帧时长更长(即动画速度更慢)。

3.2 使用等帧长延时准确控制帧时长

为解决等时长延时的两个问题,必须知道第i帧画面的代码执行时长Tr(fi),计算得到第i帧的Td(fi)值,使得:

Tfps=n = Tf(fi) (1≤i≤m, m为动画最大帧数)

如图2所示。

为此,必须要记录每次延时执行时的具体时刻,作为计算Td(fi)的依据,这可以通过使用clock()函数实现。以下为库函数clock()的函数原型。

clock_t clock(void);

clock()函数返回自本程序运行起到调用此函数为止,CPU产生的clock tick(CPU时钟计时单元)数。在VC++6.0的time.h里,对每秒clock tick数有如下宏定义:

#define CLOCKS_PER_SEC 1000

由此可知1个clock tick时长为1毫秒。因此,使用clock()可以实现计时精度为±1ms的自适应等帧长延时函数。代码如下:

//程序段3:改进的自适应等帧长延时函数

#include //clock()函数头文件

int pastFrames = 0 ; //全局变量,记录从程序运行到目前已经过的帧数

void FixedFrameTimeSleep(int frameTime)

{

static clock_t endClock = 0; //存放本次延时结束时刻的clock tick数

pastFrames++; //经过的帧数加1

endClock += frameTime * CLOCKS_PER_SEC / 1000; //计算本帧结束时刻

if (clock() > endClock) //若已超时则不延时

endClock = clock(); //以当前时刻为本帧的结束时刻

else

while (clock() < endClock) //循环1ms的延时至本帧结束,实现Td(fi) ms的延时

Sleep(1); //延时并降低CPU占用率

}

使用此函数替换程序段1中的Sleep()函数,即得到以固定帧率FPS运行的画面更新程序框架:

//程序段4:自适应等帧长延时函数实现固定帧率更新画面

while (!kbhit())

{

DrawOneFrame();

FixedFrameTimeSleep(FRAME_TIME);

}

4 现画面元素按时更新的函数框架

在实现了固定帧率后,画面元素的更新频率可以换算为每几帧更新一次,出现时刻、结束时刻可以通过pastFrames来控制。如下函数框架实现:以指定fps(fps≤FPS),从startTime时刻到endTime时刻更新画面元素。

//程序段5:画面元素按时更新函数框架

void DrawAnimation(int fps,int startTime, int endTime)

{

int curTime, updateFrames ;

curTime = pastFrames * FRAME_TIME ; //计算当前时间

if ( curTime >= startTime && curTime

{

updateFrames = FPS / fps ; //将画面元素的fps换算成每几帧更新一次

if ( pastFrames % updateFrames == 0 ) //判断是否应在本帧更新

{

//更新画面元素的代码

}

}

}

6 实现多个画面元素按时更新的程序框架

若画面中有多个画面元素,只需为它们分别编写合适的DrawAnimation()函数,再依次加到程序循环中即可,如下所示:

//程序段6:多个画面元素按时更新的程序框架

while (!kbhit())

{

DrawAnimation1(fps1,ts1,te1);

DrawAnimation2(fps2,ts2,te2);

……

FixedFrameTimeSleep(FRAME_TIME);

}

7 编程方法应用演示

使用C编写一个控制台窗口文本界面下循环动态演示Tom和Jerry进行“英文对话”的程序。为演示编程方法中以固定帧率对多个画面元素分别按时更新的特性,对此应用程序做如下设定:

1)一轮对话分为“问”和“答”;

2)Tom从问候语中随机选择一句发问,Jerry根据问候语进行相应的回答;

3)发问前、回答前均停顿1秒,回答完成后停顿2秒,使得问答停顿自然;

4)Tom和Jerry的语速不同:Tom为10字符/秒,Jerry为20字符/秒;

5)有一个按“mm’ss””格式显示的数字时钟。

若设定帧率为40fps(帧时长为25ms),则根据应用程序设定可知:

1)数字时钟的更新频率fps为1,每40帧更新一次;

2)Tom、Jerry所说的话更新频率fps分别为10、20,每4帧、2帧更新1次;

3)一轮对话的时间顺序为:1秒+发问者说话字符数/语速+1秒+发问者说话字符数/语速+2秒。

为数字时钟、Tom(说的话)和Jerry(说的话)这三个画面元素按照DrawAnimation()函数框架分别编写更新函数,并依序放入程序框架,以下为部分代码。

//程序段7:“英文对话演示”部分代码

#define MAX_TIME 3600 /* 设定最长演示时间3600秒 */

int ts1 = 0, te1 = 0; //Tom说话的开始时间与结束时间

int ts2 = 0, te2 = 0; //Jerry说话的开始时间与结束时间

while (!kbhit())

{

CalculateTime(); //在上一轮对话完成后,计算下一轮对话的时间安排

DrawTom(10,ts1,te1);

DrawJerry(20,ts2,te2);

DrawDigitalClock(1,0,MAX_TIME);

FixedFrameTimeSleep(FRAME_TIME);

}

最终实现的效果如图3所示。

8 结束语

改进的等帧长延时将每帧中代码执行、数值计算、界面更新等消耗的时长计算在内,动态增减剩余延时,保证每帧的时长相同。通过等帧长延时获得的固定帧率是一条时间轴,可以驱动程序流程准确地按时间运行。在确定帧率和帧时长后,可用之计算画面中每一个动态元素在此时间轴上的起始帧、结束帧以及需要更新的关键帧。这样就能保证画面中所有动态元素都能按各自速度和时间准确更新。但是,当画面元素之间、画面元素与用户操作之间存在比较复杂的交互逻辑时(比如:RPG游戏中的战斗场景[7]),使用面向过程的编程方式难以实现。因此,需要在此方法基础上引入事件驱动机制[8],以降低程序交互逻辑实现的难度。

参考文献:

[1] 朱蓉, 建华. C语言实现动画技术的探讨[J]. 电脑知识与技术, 2005(35): 145-147.

[2] 赵艳忠, 王鸿铭. C语言平台下动画技术实现方法浅析[J]. 科技信息, 2008(22): 402-421.

[3] 王进华, 章云, 曾歆懿. 基于掩模技术的C语言动画设计与实现[J]. 科技广场, 2005(10): 39-41.

[4] 韩洁. 用C语言实现图形动画技术[J]. 计算机时代, 1999(3): 14-15.

[5] 陈晓悦. 浅析高帧率电影制作流程[J]. 现代电影技术, 2016(5): 36-39.

[6] 和青芳. 计算机图形学原理及算法教程(Visual C++版)[M]. 北京: 清华大学出版社出版, 2006: 202-220.