查看: 7158|回复: 19

【高效C语言】(一)--提高C语言代码效率的方法

  [复制链接]
  • TA的每日心情
    无聊
    2016-12-20 15:08
  • 签到天数: 510 天

    连续签到: 1 天

    [LV.9]以坛为家II

    发表于 2012-11-3 15:16:47 | 显示全部楼层 |阅读模式
    分享到:
      首先声明这篇文章系网上转帖,因为觉得讲得不错,特地转了与大家分享。
      代码效率包括两个方面内容:代码的大小和代码执行速度。如果代码精简和执行速度快,我们就说这个代码效率高。一般情况下,代码精简了速度也相应提上来了。单片机的ROMRAM的空间都很有限,当您编程时遇到单片机的ROMRAM的不够用的时候,或者您的程序要求较高的执行速度时,我们就得面对解决代码效率问题了。如何提高代码效率?现笔者以一个LED闪烁的程序为例与您探讨。
    #i nclude<reg52.h>//包含头文件
    sbit led=P2^0;//定义位变量led,使其关联单片机管脚P2.0
    void Delayms(unsigned int t);//定义延时函数
    int main(void)//主函数(C语言程序入口函数)
    {
           while(1)
           {
                 led=0;//P2.0拉低,点亮LED
                 Delayms(500);//调用延时函数,延时500毫秒
                 led=1;//P2.0拉高,熄灭LED
                 Delayms(500);//调用延时函数,延时500毫秒
           }
           return 0;
    }
    void Delayms(unsigned int t)//延时函数
    {
            unsigned int i,j;
            for(i=0;i<t;i++)
                   for(j=0;j<120;j++);//大约延时1毫秒
    }
    这是指示灯LED闪烁的C源码,这个源码在Keil uVision4 生成的程序代码是67个字节。下面我们就采用几个方法来提高这个程序的效率。
    一.尽量定义局部变量
    单片机程序的全局变量一般是放在通用数据存储器(RAM)中,而局部变量一般是放在特殊功能寄存器当中。处理寄存器数据的速度比处理RAM数据要快,如果在一个局部函数里调用一个全局变量将会多生成好几个代码出来。所以,少定义全局变量,多定义局部变量。如上例中,如果把延时函数里的ij定义为全局变量,编译后程序代码会增加到79个字节,多了12个字节。
    二.省略函数定义
    在一个单片机程序里我们习惯在main函数的前面先定义被调用函数,然后在mian函数的下面再实现被调用函数。这样的写法固然是一个好习惯,但每定义一个函数会增加几个代码,而且函数形参数据类型越大、形参越多增加的代码就越多,显然这不是什么好事。如果不定义编译器又报错,怎么办?C编译器的编译顺序是从上往下编译,只要被调用的函数在主调函数调用之前实现就没有问题了。所以,笔者的习惯写法是不用定义函数,但要按先后顺序(被调用函数一定要在主调函数之前写好)来写函数实现,到最后再写main函数。这样做编译器不但不会报错,而且代码得到精简了。如上例中,把延时函数的定义删除了,然后把延时函数的实现搬到main函数的上面,编译后程序代码减少到63个字节,减少了4个字节。
    三.省略函数形参
    函数带形参,是为了在函数调用时传递实参,不但可以避免重复代码出现,还可以通过传递不同的实参值多次调用函数且实现不同的函数功能,总体代码也会得到精简。在实际编程的时候,我们只要注意,还可以进一步精简代码。对于不是多次调用或者多次调用但实参值不变的函数我们可以省略函数形参。如上例中的延时函数,我们把它改成不带形参的函数:
    void Delayms()//延时函数
    {
         unsigned int i,j;
         for(i=0;i<500;i++)
              for(j=0;j<120;j++);//大约延时1毫秒
    }
    编译后,程序代码变成了56个字节,精简了11个字节。
    四.改换运算符
    也许您可能没有注意到C运算符的运用也会影响程序代码的数量。如上例中,把延时函数里的自加运算符改成自减运算符后,如:
    void Delayms(unsigned int t)//延时函数
    {
         unsigned int i,j;
         for(i=t;i>0;i--)
              for(j=120;j>0;j--);//大约延时1毫秒
    }
    编译后,程序代码变成了65个字节,精简了2个字节。
    通过改换运算符能达到精简代码的例子还有:
    1.把求余运算表达式改为位与运算表达式。如:b=a%8 可以改为:b=a&7
    2.把乘法运算表达式改为左移运算表达式。如:b=a*8 可以改为:b=a<<3
    3.把除法运算表达式改为右移运算表达式。如:b=a/8 可以改为:b=a>>3
    五.选择合适的数据类型
    C语言里选择变量的数据类型很讲究,变量的数据类型过小满足不了程序的要求,变量的数据类型过大会占用太多的RAM资源。您可能还没有注意到数据类型定义也影响程序代码的大小,而且这个影响还不小。如上例中,延时函数里的局部变量j定义的数据类型明显偏大,如果把它由unsigned int改成unsigned char 。编译后,程序代码变成了59个字节,精简了8个字节。
    六.直接嵌入代码
        在您的程序里如果某个函数只调用一次,而您又要求代码提高执行速度,建议您不要采用调用函数的形式,而应该将该函数里的代码直接嵌入主调函数里,代码执行效率会大大提高。
    七.使用效率高的C语句
    C语言里有一个三目运算符“?”,俗称“问号表达式”。很多程序员都很喜欢使用,因为它逻辑清晰表达简洁。
    看这个问号表达式:c=(a>b) ? a+1 : b+1;实际上等效于以下的if…else结构:
    if (a>b)  c=a+1;
    else  c=b+1;
    可以看到,使用问号表达式,语句相当简洁,但它的执行效率却很低,远没有if…else语句效率高。所以,当您的程序要求提高执行速度的话,建议您不要使用问号表达式了。
    另外,do…while语句也比while语句的效率高。
    代码的效率问题,不是我们编程中的主要问题,除了程序要求较高的执行速度或者单片机的ROMRAM不够用的时候才会考虑。一般情况下,我们不用在乎。如果您一味追求高效率的代码,可能会影响代码的可读性和可维护性。
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2016-6-9 09:16
  • 签到天数: 9 天

    连续签到: 1 天

    [LV.3]偶尔看看II

    发表于 2012-11-7 10:04:31 | 显示全部楼层
    学习了,实际经验最重要。
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    发表于 2012-11-8 14:50:16 | 显示全部楼层
    进步在于不断的学习!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    擦汗
    2020-3-19 13:22
  • 签到天数: 805 天

    连续签到: 1 天

    [LV.10]以坛为家III

    发表于 2012-11-12 09:19:08 | 显示全部楼层
    能搞成PDF的不啊  方便大家下载
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    无聊
    2016-12-20 15:08
  • 签到天数: 510 天

    连续签到: 1 天

    [LV.9]以坛为家II

    发表于 2012-11-12 13:09:14 | 显示全部楼层
    怎么做成pdf,这个没做过
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    2012-11-26 19:50
  • 签到天数: 8 天

    连续签到: 1 天

    [LV.3]偶尔看看II

    发表于 2012-11-14 19:26:39 | 显示全部楼层
    以前很粗糙地学过
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    无聊
    2016-12-20 15:08
  • 签到天数: 510 天

    连续签到: 1 天

    [LV.9]以坛为家II

    发表于 2012-11-14 23:24:49 | 显示全部楼层
    boldspeaker 发表于 2012-11-14 19:26
    以前很粗糙地学过

    多多少少有点收获
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2019-10-14 03:09
  • 签到天数: 28 天

    连续签到: 1 天

    [LV.4]偶尔看看III

    发表于 2012-11-23 22:10:26 | 显示全部楼层
    谢谢分享!!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    慵懒
    2013-1-2 00:30
  • 签到天数: 24 天

    连续签到: 1 天

    [LV.4]偶尔看看III

    发表于 2012-12-6 10:10:10 | 显示全部楼层
    好高端啊,不练的多的话根本不会遇到啊
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    郁闷
    2020-1-7 22:03
  • 签到天数: 38 天

    连续签到: 1 天

    [LV.5]常住居民I

    发表于 2012-12-10 09:31:39 | 显示全部楼层
    太需要这些了
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /4 下一条

    手机版|小黑屋|与非网

    GMT+8, 2024-11-26 08:33 , Processed in 0.238449 second(s), 33 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.