嵌入式培训
达内IT学院
400-996-5531
目前,在嵌入式系统开发中可使用的语言很多,其中 C语言应用得最广泛。虽然用 C 语言编程具有许多优点,但基于嵌入式系统的C语言和标准 C语言又有很大区别。接下来小编结合嵌入式系统的特点和高手们的一些积累,给大家整理出在程序设计中代码优化的一些小技巧。
1、提高循环语言的效率
在 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 程序部简洁但效率高
2、提高 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语句提高程序执行效率。
3、避免使用标准库
使用 C语言标准库可以加快开发进度,但由于标准库需要设法处理用户所有可能遇到的情况,所以很多标准库代码很大。比如标准库中的 sprintf函数非常大。这个庞大的代码中有很大一部分用于处理浮点数,如果程序中不需要格式化浮点数值( 如%f),程序设计人员就可以根据实际情况用少量的代码实现这个功能。
4、采用数学方法优化程序
数学是计算机之母,没有数学的依据和基础,就没有计算机的发展,所以在编写程序的时候,采用一些数学方法会对程序的执行效率有数量级的提高。有时候这个问题常常被大家忽略, 对于没有经验的程序员来说更是如此。例如:求 1~100 的和:
sum = 100*(100+1)/2;
数学公式: (a1 + an)*n/2
使用C语言的位操作可以减少除法和取模的运算。在计算机程序中数据的位是可以操作的最小数据单位,理论上可以用“位运算”来完成所有的运算和操作。因而,灵活的位操作可以有效地提高程序运行的效率。比如用用位操作区代替除法:比如:128 / 8 ->> 128 >> 3;
优化算法和数据结构对提高代码的效率有很大的帮助。当然有时候时间效率和空间效率是对立的,此时应分析哪个更重要, 做出适当的折中。另外,在进行优化的时候不要片面的追求紧凑的代码,因为紧凑的代码并不能产生高效率的机器码。
5、存储器分配
由于成本限制,嵌入式系统存储器容量有限。程序中所有的变量,包含的库函数以及堆栈等都使用有限的内存:全局变量在整个程序范围内都有效。程序执行完后才会释放;静态变量的作用范围也是整个程序,只有局部变量中的动态变量在函数执行完后会释放。因此, 在程序中应尽量使用局部变量,提高内存使用效率。程序中堆的大小受限于所有全局数据和栈空间都分配后的剩余量,如果堆太小,程序不能够在需要的时候分配内存。因此在使用 malloc 函数申请内存之后一定要用 free 函数进行释放, 防止内存泄露。
6、选择好的无限循环
在编程中,我们常常需要用到无限循环,常用的两种方法是while (1) 和 for (;;)。这两种方法效果完全一样,但那一种更好呢?然我们看看它们编译后的代码:
编译前:
while (1);
编译后:
mov eax,1
test eax,eax
je foo+23h
jmp foo+18h
编译前:
for (;;);
编译后:
jmp foo+23h
显然,for (;;)指令少,不占用寄存器,而且没有判断,跳转,比while (1)好。
7、使用Memoization,以避免递归重复计算
考虑Fibonacci(斐波那契)问题,Fibonacci问题是可以通过简单的递归方法来解决:
[plain] view plain copy print?
int fib ( n )
{
if ( n == 0 || n == 1 )
{
return 1;
}
else
{
return fib( n - 2 ) + fib ( n - 1 );
}
}
注:在这里,我们考虑Fibonacci 系列从1开始,因此,该系列看起来:1,1,2,3,5,8,…
注意:从递归树,我们计算fib(3)函数2次,fib(2)函数3次。这是相同函数的重复计算。如果n非常大,fib函数的效率会比较低。Memoization是一个简单的技术,可以被用在递归,加强计算速度。fibonacci 函数Memoization的代码如下:
[plain] view plain copy print?
int calc_fib ( int n )
{
int val[ n ] , i;
for ( i = 0; i <=n; i++ )
{
val[ i ] = -1; // Value of the first n + 1 terms of the fibonacci terms set to -1
}
val[ 0 ] = 1; // Value of fib ( 0 ) is set to 1
val[ 1 ] = 1; // Value of fib ( 1 ) is set to 1
return fib( n , val );
}
int fib( int n , int* value )
{
if ( value[ n ] != -1 )
{
return value[ n ]; // Using memoization
}
else
{
value[ n ] = fib( n - 2 , value ) + fib ( n - 1 , value ); // Computing the fibonacci term
}
return value[ n ]; // Returning the value
}
除了编程上的技巧外,为提高系统的运行效率,我们通常也需要最大可能地利用各种硬件设备自身的特点来减小其运转开销,例如减小中断次数,利用DMA传输方式等。
对于嵌入式系统,C语言在开发速度,软件可靠性以及软件质量等方面都有着明显的优势。本文就嵌入式C语言在系统开发中,如何更好的利用系统资源,对代码进行优化进行了讨论。当然代码优化的方法还有很多,这里只是写出了一部分,希望能为开发人员提供一些帮助,也欢迎大家留言交流。
最后,达内嵌入式培训机构提醒每一个it爱好者:如果你想要在短时间内快速入门,顺利掌握一门技术,建议还是认真学习视频。多练习,多动手。
填写下面表单即可预约申请免费试听!怕钱不够?可就业挣钱后再付学费! 怕学不会?助教全程陪读,随时解惑!担心就业?一地学习,可全国推荐就业!
Copyright © 京ICP备08000853号-56 京公网安备 11010802029508号 达内时代科技集团有限公司 版权所有
Tedu.cn All Rights Reserved