多语言展示
当前在线:491今日阅读:26今日分享:39

教你如何利用C语言来优化程序

程序进行优化,通常是指优化程序代码或程序履行速度。优化代码和优化速度实践上是一个予盾的共同,通常是优化了代码的尺度,就会带来履行时刻的添加,若是优化了程序的履行速度,通常会带来代码添加的副作用,很难鱼与熊掌兼得,只能在描绘时把握一个平衡点。一、程序布局的优化 1、程序的书写布局尽管书写格局并不会影响生成的代码质量,但是在实践编写程序时仍是大概尊循必定的书写规矩,一个书写明晰、明晰的程序,有利于今后的保护。在书写程序时,特别是关于While、for、do…while、if…elst、switch…case等句子或这些句子嵌套组合时,应选用“缩格”的书写办法, 2、标识符程序中运用的用户标识符除要遵从标识符的命名规矩以外,通常不要用代数符号(如a、b、x1、y1)作为变量名,应挑选具有有关意义的英文单词(或缩写)或汉语拼音作为标识符,以添加程序的可读性,如:count、number1、red、work等。 3、程序布局C言语是一种高档程序描绘言语,供给了非常齐备的规范化流程操控布局。因而在选用C言语描绘单片机运用体系程序时,首要要注意尽可能选用布局化的程序描绘办法,这样可使整个运用体系程序布局明晰,便于调试和保护。于一个较大的运用程序,通常将整个程序按功用分红若干个模块,不相同模块完结不相同的功用。各个模块可以别离编写,乃至还可以由不相同的程序员编写,通常单个模块完结的功用较为简略,描绘和调试也相对简单一些。在C言语中,一个函数就可以认为是一个模块。所谓程序模块化,不仅是要将整个程序划分红若干个功用模块,更重要的是,还大概注意坚持各个模块之间变量的相对独立性,即坚持模块的独立性,尽量少运用全局变量等。关于一些常用的功用模块,还可以封装为一个运用程序库,以便需求时可以直接调用。但是在运用模块化时,若是将模块分红太细太小,又会致使程序的履行功率变低(进入和退出一个函数时保护和康复寄存器占用了一些时刻)。 4、界说常数在程序化描绘过程中,关于常常运用的一些常数,若是将它直接写到程序中去,一旦常数的数值发生变化,就有必要逐个找出程序中一切的常数,并逐个进行修正,这样必然会下降程序的可保护性。因而,应尽量当选用预处理指令办法来界说常数,而且还可以防止输入过错。 5、削减判别句子可以运用条件编译(ifdef)的当地就运用条件编译而不运用if句子,有利于削减编译生成的代码的长度,可以不必判别句子则少用判别用句子。 6、表达式关于一个表达式中各种运算履行的优先次序不太清晰或简单混杂的当地,应当选用圆括号清晰指定它们的优先次序。一个表达式通常不能写得太杂乱,若是表达式太杂乱,时刻久了今后,自个也不简单看得懂,不利于今后的保护。 7、函数关于程序中的函数,在运用之前,应对函数的类型进行阐明,对函数类型的阐明有必要确保它与本来界说的函数类型共同,关于没有参数和没有返回值类型的函数应加上“void”阐明。若是果需求缩短代码的长度,可以将程序中一些公共的程序段界说为函数,在Keil中的高档别优化即是这样的。若是需求缩短程序的履行时刻,在程序调试完毕后,将有些函数用宏界说来替代。注意,大概在程序调试完毕后再界说宏,由于大多数编译体系在宏打开之后才会报错,这样会添加排错的难度。 8、尽量少用全局变量,多用局部变量。由于全局变量是放在数据存储器中,界说一个全局变量,MCU就少一个可以运用的数据存储器空间,若是界说了太多的全局变量,会致使编译器无满足的内存可以分配。而局部变量大多定坐落MCU内部的寄存器中,在绝大多数MCU中,运用寄存器操作速度比数据存储器快,指令也更多更灵敏,有利于生成质量更高的代码,而且局部变量所的占用的寄存器和数据存储器在不相同的模块中可以重复运用。 9、设定适宜的编译程序选项许多编译程序有几种不相同的优化选项,在运用前应了解各优化选项的意义,然后选用最适宜的一种优化办法。通常情况下一旦选用最高档优化,编译程序会近乎病态地寻求代码优化,可能会影响程序的正确性,致使程序运转犯错。因而应了解所运用的编译器,应晓得哪些参数在优化时会受到影响,哪些参数不会受到影响。在ICCAVR中,有“Default”和“Enable Code Compression”两个优化选项。在CodeVisionAVR中,“Tiny”和“small”两种内存方法。在IAR中,共有7种不相同的内存方法选项。在GCCAVR中优化选项更多,一不小心更简单选到不恰当的选项。二、代码的优化 1、挑选适宜的算法和数据布局大概了解算法言语,晓得各种算法的优缺点,详细材料请拜见相应的参考材料,有许多核算机书本上都有介绍。将对比慢的次序查找法用较快的二分查找或乱序查找法替代,刺进排序或冒泡排序法用疾速排序、兼并排序或根排序替代,都可以大大提高程序履行的功率。.挑选一种适宜的数据布局也很重要,比方你在成堆随机寄存的数中运用了许多的刺进和删去指令,那运用链表要快得多。数组与指针句子具有非常暗码的联系,通常来说,指针对比灵敏简练,而数组则对比直观,简单了解。关于大有些的编译器,运用指针比运用数组生成的代码更短,履行功率更高。但是在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)+a6、循环(1)、循环语 关于一些不需求循环变量参与运算的使命可以把它们放到循环外面,这里的使命包含表达式、函数的调用、指针运算、数组拜访等,大概将没有必要履行屡次的操作悉数调集在一起,放到一个init的初始化程序中进行。(2)、延时函数: 通常运用的延时函数均选用自加的办法: void delay (void) {unsigned int i; for (i=0;i<1000;i++) ; }将其改为自减延时函数: void delay (void) {unsigned int i; for (i=1000;i>0;i--) ; }两个函数的延时作用类似,但简直一切的C编译对后一种函数生成的代码均比前一种代码少1~3个字节,由于简直一切的MCU均有为0搬运的指令,选用后一种办法可以生成这类指令。在运用while循环时也相同,运用自减指令操控循环会比运用自加指令操控循环生成的代码更少1~3个字母。但是在循环中有经过循环变量“i”读写数组的指令时,运用预减循环时有可能使数组超界,要导致注意。(3)while循环和do…while循环用while循环时有以下两种循环办法:unsigned int i; i=0; while (i<1000) { i++; //用户程序 }或:unsigned int i; i=1000; do i--; //用户程序 while (i>0);在这两种循环中,运用do…while循环编译后生成的代码的长度短于while循环。 7、查表在程序中通常不进行非常杂乱的运算,如浮点数的乘除及开方等,以及一些杂乱的数学模型的插补运算,对这些即耗费时刻又花费资源的运算,应尽量运用查表的办法,而且将数据表置于程序存储区。若是直接生成所需的表对比艰难,也尽量在启动时先核算,然后在数据存储器中生成所需的表,后以在程序运转直接查表就可以了,削减了程序履行过程中重复核算的工作量。 8、其它比方运用在线汇编及将字符串和一些常量保存在程序存储器中,均有利于优化
推荐信息