1、从循环提取不变代码;
2、采用后置条件的循环代替前置条件的循环,例如采用do{}while()代替while,因为少了一条跳转指令,也就少了一次流水线的刷新;
3、尽量采用减1指令代替加1指令;
4、适当考虑循环展开,例如:
for(i=0;i<20; i++)
{
m[i]= 0;
}
for(i=0;i<20; i+=2) //可以减少一半循环次数和一半条件判断
{
m[i]= 0;
m[i+1]= 0;
}
5、逻辑或表达式,可以将为真概率较高的表达式放在前面,逻辑与表达式,可以将为假概率较高的表达式放在前面。
6、用移位代替除法 m=n/8-> m=n>>3;
用位操作代替求模 m=n%8-> m=n&7;
用移位代替乘法 m=n*8-> m=n<<3;
上述三种方法建议不要手动使用,因为编译器能够帮我们完成优化,而且前者的可读性可能更高。但是,如果是与变量进行类似运算,并且变量的值是2的n次方,则可以采用这三种方法优化。
7、提前公共表达式。
8、用指针代替数组元素的访问,在多数情况下,可以用指针运算代替数组索引,这样常常能够产生又快又短的代码。指针方法的优点是array地址装入p以后,每次只需要针对p进行操作,而数组索引每次都需要基于array和下标进行运算。
9、使用查表代替计算。
10、使用内联函数。
11、如何函数定义相同,可以使用如下方法减少代码大小。
(V1<V2)? (F1:F2)(a1, a2, a3)
12、如果case值跨度比较大,建议不要采用switch语句而是采用if语句。
13、尽量使用无符号变量,GCC针对无符号的除法比有符号的除法在优化时能够生成更加简洁的代码。
14、x=y?y:z-> x=y? :z,少了一次对y的操作。
15、不要将正常值和错误标志混在一起返回,正常值用输出参数获得,而错误标志采用return语句返回。
16、不要估计数据类型大小,必须使用sizeof得到大小。
17、函数定义时,将目的参数放在前面,源参数放在后面。
18、使用if语句时,将正常情况放在前面,异常情况放在后面。
19、不要修改函数参数的输入值。
20、不要省略switch后面的最后一个分之的break。
21、如果一个任务需要不断检查全局变量A值是否变化,而且这个全局变量的值可能被其它任务修改,则定义这个全局变量是要用volatile。
22、公共库函数应该具有可重入性。
×只使用自动局部变量,没有使用任何静态局部变量、全局变量和全局资源。
×访问静态局部变量、全局变量和资源时使用保护措施,一般使用信号灯保护。
×没有调用不具备可重入性的函数。
23、中断可以看做一种多任务情况,它比一般多任务情况下面的函数更为严格,中断的程序除了需要具备可重入性以外,还不能执行任何可能被阻塞的函数。
24、如何中断程序和非中断程序共享某个全局变量或者资源,他们之间不能使用信号灯进行保护,而是需要使用中断屏蔽/允许的方式保护。