我用Dec++编写的程序代码编写规范该以怎样形式保存

编写单片机C语言代码的技巧和经验
摘要:   下面发一些我在网上看到的单片机C语言代码编写技巧和自己的一些经验来和大家分享;  1、如果可以的话少用库函数,便于不同的mcu和编译器间的移植  2、选择合适的算法和数据结构  应该熟悉算法语言,知道各 ...
  下面发一些我在网上看到的C语言代码编写技巧和自己的一些经验来和大家分享;  1、如果可以的话少用库函数,便于不同的mcu和编译器间的移植  2、选择合适的算法和数据结构  应该熟悉算法语言,知道各种算法的优缺点,具体资料请参见相应的参考资料,有很多计算机书籍上都有介绍。将比较慢的顺序查找法用较快的二分查找或乱序查找法代替,插入排序或冒泡排序法用快速排序、合并排序或根排序代替,都可以大大提高程序执行的效率。选择一种合适的数据结构也很重要,比如你在一堆随机存放的数中使用了大量的插入和删除指令,那使用链表要快得多。数组与指针语句具有十分密码的关系,一般来说,指针比较灵活简洁,而数组则比较直观,容易理解。对于大部分的编译器,使用指针比使用数组生成的代码更短,执行效率更高。但是在Keil中则相反,使用数组比使用的指针生成的代码更短。  3、使用尽量小的数据类型  能够使用字符型(char)定义的变量,就不要使用整型(int)变量来定义;能够使用整型变量定义的变量就不要用长整型(long int),能不使用浮点型(float)变量就不要使用浮点型变量。当然,在定义变量后不要超过变量的作用范围,如果超过变量的范围赋值,C编译器并不报错,但程序运行结果却错了,而且这样的错误很难发现。在ICCAVR中,可以在Options中设定使用printf参数,尽量使用基本型参数(%c、%d、%x、%X、%u和%s格式说明符),少用长整型参数(%ld、%lu、%lx和%lX格式说明符),至于浮点型的参数(%f)则尽量不要使用,其它C编译器也一样。在其它条件不变的情况下,使用%f参数,会使生成的代码的数量增加很多,执行速度降低。  4、使用自加、自减指令  通常使用自加、自减指令和复合赋值表达式(如a-=1及a+=1等)都能够生成高质量的程序代码,编译器通常都能够生成inc和dec之类的指令,而使用a=a+1或a=a-1之类的指令,有很多C编译器都会生成二到三个字节的指令。在AVR单片适用的ICCAVR、GCCAVR、IAR等C编译器以上几种书写方式生成的代码是一样的,也能够生成高质量的inc和dec之类的的代码。  5、减少运算的强度  可以使用运算量小但功能相同的表达式替换原来复杂的的表达式。如下:  (1)、求余运算。  a=a%8;  可以改为:  a=a&7;  说明:位操作只需一个指令周期即可完成,而大部分的C编译器的“%”运算均是调用子程序来完成,代码长、执行速度慢。通常,只要求是求2n方的余数,均可使用位操作的方法来代替。  (2)、平方运算  a=pow(a,2.0);  可以改为:  a=a*a;  说明:在有内置硬件乘法器的单片机中(如51系列),乘法运算比求平方运算快得多,因为浮点数的求平方是通过调用子程序来实现的,在自带硬件乘法器的AVR单片机中,如ATMega163中,乘法运算只需2个时钟周期就可以完成。既使是在没有内置硬件乘法器的AVR单片机中,乘法运算的子程序比平方运算的子程序代码短,执行速度快。  如果是求3次方,如:  a=pow(a,3.0);  更改为:  a=a*a*a;  则效率的改善更明显。  (3)、用移位实现乘除法运算  a=a*4;  b=b/4;  可以改为:  a=a&&2;  b=b&&2;  说明:通常如果需要乘以或除以2n,都可以用移位的方法代替。在ICCAVR中,如果乘以2n,都可以生成左移的代码,而乘以其它的整数或除以任何数,均调用乘除法子程序。用移位的方法得到代码比调用乘除法子程序生成的代码效率高。实际上,只要是乘以或除以一个整数,均可以用移位的方法得到结果,如:  a=a*9  可以改为:  a=(a&&3)+a  6、循环  (1)、循环语  对于一些不需要循环变量参加运算的任务可以把它们放到循环外面,这里的任务包括表达式、函数的调用、指针运算、数组访问等,应该将没有必要执行多次的操作全部集合在一起,放到一个init的初始化程序中进行。  (2)、延时函数:  通常使用的延时函数均采用自加的形式:  void delay (void)  {    for (i=0;i&1000;i++)  ;  }  将其改为自减延时函数:  void delay (void)  {    for (i=1000;i&0;i--)  ;  }  两个函数的延时效果相似,但几乎所有的C编译对后一种函数生成的代码均比前一种代码少1~3个字节,因为几乎所有的MCU均有为0转移的指令,采用后一种方式能够生成这类指令。在使用while循环时也一样,使用自减指令控制循环会比使用自加指令控制循环生成的代码更少1~3个字母。但是在循环中有通过循环变量“i”读写数组的指令时,使用预减循环时有可能使数组超界,要引起注意。  (3)while循环和do…while循环  用while循环时有以下两种循环形式:    i=0;  while (i&1000)  {  i++;  //用户程序  }  或:    i=1000;  do  i--;  //用户程序  while (i&0);  在这两种循环中,使用do…while循环编译后生成的代码的长度短于while循环。  7、查表  在程序中一般不进行非常复杂的运算,如浮点数的乘除及开方等,以及一些复杂的数学模型的插补运算,对这些即消耗时间又消费资源的运算,应尽量使用查表的方式,并且将数据表置于程序存储区。如果直接生成所需的表比较困难,也尽量在启了,减少了程序执行过程中重复计算的工作量。  比如使用在线汇编及将字符串和一些常量保存在程序存储器中,均有利于优化  C语言宏定义技巧(常用宏定义)  写好C语言,漂亮的宏定义很重要,使用宏定义可以防止出错,提高可移植性,可读性,方便性 等等。下面列举一些成熟软件中常用得宏定义。。。。。。  CODE:  1,防止一个头文件被重复包含  #ifndef COMDEF_H  #define COMDEF_H  //头文件内容  #endif  2,重新定义一些类型,防止由于各种平台和编译器的不同,而产生的类型字节数差异,方便移植。  typedef u /* Boolean value type. */  typedef unsigned long int uint32; /* Unsigned 32 bit value */  typedef unsigned short uint16; /* Unsigned 16 bit value */  typedef unsigned char uint8; /* Unsigned 8 bit value */  typedef signed long int int32; /* Signed 32 bit value */  typedef signed short int16; /* Signed 16 bit value */  typedef signed char int8; /* Signed 8 bit value */  //下面的不建议使用  typede /* Unsigned 8 bit value type. */  typedef /* Unsinged 16 bit value type. */  typedef /* Unsigned 32 bit value type. */  typedef unsigned char uint1; /* Unsigned 8 bit value type. */  typedef unsigned short uint2; /* Unsigned 16 bit value type. */  typedef unsigned long uint4; /* Unsigned 32 bit value type. */  typedef signed char int1; /* Signed 8 bit value type. */  typedef signed short int2; /* Signed 16 bit value type. */  typedef long int int4; /* Signed 32 bit value type. */  typedef signed long sint31; /* Signed 32 bit value */  typedef signed short sint15; /* Signed 16 bit value */  typedef signed char sint7; /* Signed 8 bit value */  3,得到指定地址上的一个字节或字  #define MEM_B( x ) ( *( (byte *) (x) ) )  #define MEM_W( x ) ( *( (word *) (x) ) )  4,求最大值和最小值  #define MAX( x, y ) ( ((x) & (y)) ? (x) : (y) )  #define MIN( x, y ) ( ((x) & (y)) ? (x) : (y) )  5,得到一个field在结构体(struct)中的偏移量  #define FPOS( type, field )  /*lint -e545 */ ( (dword) &(( type *) 0)-& field ) /*lint +e545 */  6,得到一个结构体中field所占用的字节数  #define FSIZ( type, field ) sizeof( ((type *) 0)-&field )  7,按照LSB格式把两个字节转化为一个Word  #define FLIPW( ray ) ( (((word) (ray)[0]) * 256) + (ray)[1] )
刚表态过的朋友 ()
上一篇:下一篇:
|| ( 渝ICP备号)
Powered by &
这里是—这里可以学习 —这里是。
栏目导航:汇编语言的题:用汇编语言编写程序1+2×3+3×4+4×5+.......+54×53.会的麻烦写下。很急,谢了_百度知道
汇编语言的题:用汇编语言编写程序1+2×3+3×4+4×5+.......+54×53.会的麻烦写下。很急,谢了
提问者采纳
..;3-1..,53xor dx.,dxmov bx.,3div bxsub ax,0..1+2×3+3×4+4×5+.+53×54=53*54*55&#47.,1sbb dx..+53×54=-1+1*2+2×3+3×4+4×5+.mov ax.,axinc bxmul bxinc bxmul bxmov bx....
其他类似问题
按默认排序
其他2条回答
i&n;for(int i=2;int sumint n
1、编两个通用过程完成将AX中存放的二进制数转换成压缩型BCD码以及将BCD码转换成二进制数。; 本程序通过编译,运行正确。Code
Assume CS:Code,DS:Code; -----------------------------------------; 功能:将AX中的二进制数转换成压缩型BCD码; 入口:AX=16位二进制数(因为压缩BCD码最大为:9999H,所以,AX的二进制值不能大于270FH); 出口:AX=转换后的压缩型BCD码Binary_BCD Proc Near
@@Temp_Save,0
@@Temp_Save[2],0 ;将临时两个字存储单元置0
di,@@Temp_Save[3]
cld@@Divide:
[di],保存余数
test ax,0ffffh
ax,@@Temp_Save[2]
xchg ah,al
ax,@@Temp_Save
xchg ah,al
ret@@Temp_Save dw
Binary_BCD EndP; -----------------------------------------; 功能:将AX中的压缩型BCD码转换成二进制数; 入口:AX=压缩型BCD码; 出口:AX=转换后的16位二进制数BCD_Binary Proc Near
xchg ah,al
xchg dh,dl
xchg dh,dl
retBCD_Binary EndP; -----------------------------------------Start:
push cs使数据段、附加段与代码段同段
call Binary_BCD ;将AX中的二进制数转换成压缩型BCD码
call BCD_B将AX中的压缩型BCD码转换成二进制数Exit_Proc: mov
ah,4结束程序
S编译到此结束2、在附加段中有一个数组,首地址为BUFF,数组中第一个字节存放了数组的长度.编一个程序在数组中查找0,找到后把它从数组中删去,后续项向前压缩,其余部分补0。; 本程序通过编译,运行正确Code
Assume CS:Code,DS:CodeBUFF
10,56,78,35,0,89,51,63,0,76,123Start:
push cs使数据段、附加段与代码段同段
si,BUFF ;数组首地址→si读数组长度
push ax数组长度→cxFind_Zero:数组元素读入累加器al
al,0 ;是否为0
Next_O不是0,跳转,处理下一个元素; -----------------------------------------; 找到0,把它从数组中删去,后续项向前压缩,其余部分补0。
byte ptr [si-1],0
si; -----------------------------------------Next_One: loop Find_ZeroExit_Proc: mov
ah,4结束程序
S编译到此结束3.编程序统计学生的数学成绩,分别归类90分~99分,80分~89分,70分~79分,60~69,及60分以下,并将各段的人数送入内存单元中。; 本程序通过编译,运行正确Code
Assume CS:Code,DS:Code; -----------------------------------------; 功能:输出回车换行enter_CTLF proc Near
retenter_CTLF endp ; -----------------------------------------; 功能:把AL中的二进制无符号数转换成显式的十进制ASCII码; 入口:AL=二进制数;di=转换后的ASCII保存地址; 出口:无Dec_ASCII Proc
di,@@Temp_Save[3]
cld@@Divide:
test al,0ffh
byte ptr [di],'$'
ret@@Temp_Save db
Dec_ASCII EndP; -----------------------------------------Score
56,69,84,82,73,88,99,63,100,80,0,10,80,100,90,73,43,60,63,72,88,42,58,99,100,89,65,61,74,84,79,2,60,61,62,62,66,82,79,71,62,63 ; 成绩单Elements equ
($-Score)/Type S元素个数Score_Tab
6 dup(0) ; 各分数段计数Resault
'00---59: 'Temp_STr db
4 dup ('$')Score100 db
'====100: 'Start:
push cs使数据段、附加段与代码段同段
si,S 成绩首地址
cx,E成绩数目
dl,10 ; 用于除10Read_Score: 提取成绩 除10
al,5 ; &5,及格
al,5 ; &=5,不及格
al,5 ; 减5,分数段计数地址偏移量
Score_Tab[bx] ; 计数增1
Read_S 循环,统计下一个成绩; 显示统计结果
si,Score_T各分数段计数数组首地址
di,Temp_STr
dx,R 统计结果字符串地址List_Resault:读入计数值
call Dec_ASCII
ah,9 ; 显示统计结果
call enter_CTLF
xchg ah,al
word ptr Resault,ax
xchg ah,al
word ptr Resault[5],ax
loop List_Resault
si,Score100
di,Resault
cx,Temp_STr
si读入计数值
call Dec_ASCII
ah,9 ; 显示统计结果
21hExit_Proc: mov
ah,4结束程序
S编译到此结束
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁您现在的位置: &
编写出优秀C语言代码的秘诀
编写出优秀C语言代码的秘诀
  1、使用自加、自减指令&&& &&& 通常使用自加、自减指令和复合赋值表达式(如a-=1及a+=1等)都能够生成高质量的程序代码,编译器通常都能够生成inc和dec之类的指令,而使用a=a+1或a=a-1之类的指令,有很多C编译器都会生成二到三个字节的指令。在AVR单片适用的ICCAVR、GCCAVR、IAR等C编译器以上几种书写方式生成的代码是一样的,也能够生成高质量的inc和dec之类的的代码。&&& &&& 2、查表&&& &&& 在程序中一般不进行非常复杂的运算,如浮点数的乘除及开方等,以及一些复杂的数学模型的插补运算,对这些即消耗时间又消费资源的运算,应尽量使用查表的方式,并且将数据表置于程序存储区。如果直接生成所需的表比较困难,也尽量在启了,减少了程序执行过程中重复计算的工作量。&&& &&& 3、选择合适的算法和数据结构&&& &&& 需要熟悉算法语言,知道各种算法的优缺点。将比较慢的顺序查找法用较快的二分查找或乱序查找法代替,插入排序或冒泡排序法用快速排序、合并排序或根排序代替,都可以大大提高程序执行的效率选择一种合适的数据结构也很重要,一般来说,指针比较灵活简洁,而数组则比较直观,容易理解。对于大部分的编译器,使用指针比使用数组生成的代码更短,执行效率更高。但是在Keil中则相反,使用数组比使用的指针生成的代码更短&&& &&& 4、使用尽量小的数据类型&&& &&& 能够使用字符型(char)定义的变量,就不要使用整型(int)变量来定义;能够使用整型变量定义的变量就不要用长整型(long int),能不使用浮点型(float)变量就不要使用浮点型变量。当然,在定义变量后不要超过变量的作用范围,如果超过变量的范围赋值,C编译器并不报错,但程序运行结果却错了,而且这样的错误很难发现。&&& &&& 5、减少运算的强度&&& &&& 可以使用运算量小但功能相同的表达式替换原来复杂的的表达式。如下:&&& &&& (1)、求余运算。&&& &&& 如:a=a%8;可以改为:a=a&7;&&& &&& 说明:位操作只需一个指令周期即可完成,而大部分的C编译器的"%"运算均是调用子程序来完成,代码长、执行速度慢。通常,只要求是求2n方的余数,均可使用位操作的方法来代替。&&& &&& (2)、平方运算&&& &&& 如:a=pow(a,2.0);可以改为:a=a*a;&&& &&& 说明:在有内置硬件乘法器的单片机中(如51系列),乘法运算比求平方运算快得多,因为浮点数的求平方是通过调用子程序来实现的,在自带硬件乘法器的AVR 单片机中,如ATMega163中,乘法运算只需2个时钟周期就可以完成。既使是在没有内置硬件乘法器的AVR单片机中,乘法运算的子程序比平方运算的子程序代码短,执行速度快。&&& &&& 如果是求3次方,如:a=pow(a,3.0);更改为:a=a*a*a;&&& &&& 则效率的改善更明显。&&& &&& (3)、用移位实现乘除法运算&&& &&& 如:a=a*4;b=b/4;可以改为:a=a《2;b=b》2;&&& &&& 说明:通常如果需要乘以或除以2n,都可以用移位的方法代替。在ICCAVR中,如果乘以2n,都可以生成左移的代码,而乘以其它的整数或除以任何数,均调用乘除法子程序。用移位的方法得到代码比调用乘除法子程序生成的代码效率高。实际上,只要是乘以或除以一个整数,均可以用移位的方法得到结果,如:a=a*9可以改为:a=(a《3)+a&&& &&& 6、循环&&& &&& (1)、循环语&&& &&& 对于一些不需要循环变量参加运算的任务可以把它们放到循环外面,这里的任务包括表达式、函数的调用、指针运算、数组访问等,应该将没有必要执行多次的操作全部集合在一起,放到一个init的初始化程序中进行。&&& &&& (2)、延时函数:&&& &&& 通常使用的延时函数均采用自加的形式:&&& &&& 两个函数的延时效果相似,但几乎所有的C编译对后一种函数生成的代码均比前一种代码少1~3个字节,因为几乎所有的MCU均有为0转移的指令,采用后一种方式能够生成这类指令。在使用while循环时也一样,使用自减指令控制循环会比使用自加指令控制循环生成的代码更少1~3个字母。但是在循环中有通过循环变量"i"读写数组的指令时,使用预减循环时有可能使数组超界,要引起注意。&&& &&& (3)while循环和do…while循环&&& &&& 用while循环时有以下两种循环形式:&&& &&& 在这两种循环中,使用do…while循环编译后生成的代码的长度短于while循环。&&& &&& 7、其它&&& &&& 比如使用在线汇编及将字符串和一些常量保存在程序存储器中,均有利于优化。
&&&主编推荐
&&&热门试卷
&&&最新视频
&&&热门阅读
&&&最新问答
&&&&&&&&&&&&&&&
希赛网 版权所有 & &&&&湘教QS2-164&&增值电信业务经营许可证湘B2-}

我要回帖

更多关于 代码编写规范 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信