c语言优化技巧
1,变量类型的定义
不同的数据类型所生成的机器代码长度相差很多,变量类型选取的范围越小运行速度越快,占用的内存越少。能够使用字符型(char)定义的变量,就不要使用整型(int)变量来定义;能够使用整型变量定义的变量就不要用长整型(long int),能不使用浮点型(float)变量就不要使用浮点型变量。相同类型的数据类型,有无符号对机器代码长度也有影响。因此我们应按照实际需要合理的选用数据类型。当然,在定义变量后不要超过变量的作用范围,如果超过变量的范围赋值,C编译器并不报错,但程序运行结果却错了,而且这样的错误很难发现
2,算法优化
算法优化指对程序时空复杂度的优化:在 PC 机上进行程序设计时一般不必过多关注程序代码的长短,只需考虑功能的实现,但嵌入式系统就必须考虑系统的硬件资源,在程序设计时,应尽量采用生成代码短的算法,在不影响程序功能实现的情况下优化算法
3,适当的使用宏
在C程序中使用宏代码可以提高程序的执行效率。宏代码本身不是函数,但使用起来像函数。函数调用要使用系统的栈来保存数据,同时 CPU 在函数调用时需要保存和恢复当前的现场,进行进栈和出栈操作,所以函数调用也需要 CPU时间。而宏定义就没有这个问题:宏定义仅仅作为预先写好的代码嵌入到当前程序中,不产生函数调用,所占用的仅仅是一些空间,省去了参数压栈,生成汇编语言的 call 调用,返回参数,执行 return等过程,从而提高了程序的执行速度。虽然宏破坏了程序的可读性,使排错更加麻烦,但对于嵌入式系统,为了达到要求的性能,嵌入代码常常是必须的做法。
此外,我们还要避免不必要的函数调用,请看下面的代码:
请注意,这两个函数的功能相似。然而,第一个函数调用strlen函数多次,而第二个函数只调用函数strlen一次。因此第二个函数性能明显比第一个好。
[plain] view plain copy print?
void str_print( char *str )
{
int i;
for ( i = 0; i < strlen ( str ); i++ )
{
printf("%c",str[ i ] );
}
}
void str_print1 ( char *str )
{
int len;
len = strlen ( str );
for ( i = 0; i < len; i++ )
{
printf("%c",str[ i ] );
}
}
4,提高循环语言的效率
在 C 语言中循环语句使用频繁,提高循环体效率的基本办法就是降低循环体的复杂性:
(1) 在多重循环中,应将最长的循环放在最内层,最短的循环放在最外层。这样可以减少 CPU跨切循环的次数。如例 1-1 的效率比 1-2 的效率要低:
[plain] view plain copy print?
for (j = 0; j < 30; j++)
{
for (i = 0; i < 10; i++)
{……}
} // 例子 1-1
for (i = 0; i < 10; i++)
{
for (j = 0; j < 30; j++)
{……}
} // 例子 2-2 程序部简洁但效率高
5,提高 switch 语句的效率
switch 语句是 C 语言中常用的选择语句, 在编译时会产生if- else- if 嵌套代码,并按照顺序进行比较,发现匹配时,就跳转到满足条件的语句执行。
当 switch 语句中的 case 标号很多时,为了减少比较的次数,可以把发生频率相对高的条件放到第一位或者把整个 switch 语句转化嵌套 switch 语句。把发生频率高的 case 标号放在最外层的 switch 语句中,发生相对频率相对低的 case 标号放在另外的 switch 语句中。如例 3 中,把发生率高的case 标号放在外层的 switch 语句中,把发生频率低的放在缺省的(default)内层 switch 语句中。
[plain] view plain copy print?
switch (表达式)
{
case 值1:
语句1: break;
case 值2:
语句2:break;
……
/*把发生频率低的放在内层的switch语句中*/
default:
switch (表达式)
{
case 值n:
语句n: break;
case 值m:
语句m: break;
……
}
}
例子3 使用嵌套switch语句提高程序执行效率。
6,采用数学方法优化程序
数学是计算机之母,没有数学的依据和基础,就没有计算机的发展,所以在编写程序的时候,采用一些数学方法会对程序的执行效率有数量级的提高。有时候这个问题常常被大家忽略, 对于没有经验的程序员来说更是如此。例如:求 1~100 的和:
sum = 100*(100+1)/2;
数学公式: (a1 + an)*n/2
使用C语言的位操作可以减少除法和取模的运算。在计算机程序中数据的位是可以操作的最小数据单位,理论上可以用“位运算”来完成所有的运算和操作。因而,灵活的位操作可以有效地提高程序运行的效率。比如用用位操作区代替除法:比如:128 / 8 ->> 128 >> 3;
优化算法和数据结构对提高代码的效率有很大的帮助。当然有时候时间效率和空间效率是对立的,此时应分析哪个更重要, 做出适当的折中。另外,在进行优化的时候不要片面的追求紧凑的代码,因为紧凑的代码并不能产生高效率的机器码。
7,选择好的无限循环
在编程中,我们常常需要用到无限循环,常用的两种方法是while (1) 和 for (;;)。这两种方法效果完全一样,但那一种更好呢?然我们看看它们编译后的代码:
编译前:
while (1);
编译后:
-
mov eax,1
-
test eax,eax
-
je foo+23h
-
jmp foo+18h
编译前:
for (;;);
编译后:
jmp foo+23h
显然,for (;;)指令少,不占用寄存器,而且没有判断,跳转,比while (1)好。