优化C语言代码(程序员必读)_编译器再什么时候会优化代码 c-程序员宅基地

技术标签: 语言  c  编译器  delay  优化  数据结构  

1、选择合适的算法和数据结构
      应该熟悉算法语言,知道各种算法的优缺点,具体资料请参见相应的参考资料,有很多计算机书籍上都有介绍。将比较慢的顺序查找法用较快的二分查找或乱序查找法代替,插入排序或冒泡排序法用快速排序、合并排序或根排序代替,都可以大大提高程序执行的效率。.选择一种合适的数据结构也很重要,比如你在一堆随机存放的数中使用了大量的插入和删除指令,那使用链表要快得多。数组与指针语句具有十分紧密的关系,一般来说,指针比较灵活简洁,而数组则比较直观,容易理解。对于大部分的编译器,使用指针比使用数组生成的代码更短,执行效率更高。但是在Keil中则相反,使用数组比使用的指针生成的代码更短。。


2、使用尽量小的数据类型
      能够使用字符型(char)定义的变量,就不要使用整型(int)变量来定义;能够使用整型变量定义的变量就不要用长整型(long int),能不使用浮点型(float)变量就不要使用浮点型变量。当然,在定义变量后不要超过变量的作用范围,如果超过变量的范围赋值,C编译器并不报错,但程序运行结果却错了,而且这样的错误很难发现。
      在ICCAVR中,可以在Options中设定使用printf参数,尽量使用基本型参数(%c、%d、%x、%X、%u和%s格式说明符),少用长整型参数(%ld、%lu、%lx和%lX格式说明符),至于浮点型的参数(%f)则尽量不要使用,其它C编译器也一样。在其它条件不变的情况下,使用%f参数,会使生成的代码的数量增加很多,执行速度降低。

3、使用自加、自减指令
      通常使用自加、自减指令和复合赋值表达式(如a-=1及a+=1等)都能够生成高质量的程序代码,编译器通常都能够生成inc和dec之类的指令,而使用 a=a+1或a=a-1之类的指令,有很多C编译器都会生成二到三个字节的指令。在AVR单片适用的ICCAVR、GCCAVR、IAR等C编译器以上几种书写方式生成的代码是一样的,也能够生成高质量的inc和dec之类的的代码。

4、减少运算的强度
      可以使用运算量小但功能相同的表达式替换原来复杂的的表达式。如下:
(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)+a

5、循环
(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循环。

6、查表
      在程序中一般不进行非常复杂的运算,如浮点数的乘除及开方等,以及一些复杂的数学模型的插补运算,对这些即消耗时间又消费资源的运算,应尽量使用查表的方式,并且将数据表置于程序存储区。如果直接生成所需的表比较困难,也尽量在启了,减少了程序执行过程中重复计算的工作量。

7、其它
比如使用在线汇编及将字符串和一些常量保存在程序存储器中,均有利于优化。 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/her0z/article/details/5396248

智能推荐

计算机行业方面的应用研究,计算机系统的应用及研究-程序员宅基地

文章浏览阅读160次。摘 要 计算机是一种用于协助人类信息处理的工具。计算机科技的发展在推动各学科和行业的发展方面发挥了重要的作用,人类也发展出关于计算机的学科和行业。计算机科技和行业的发展存在着一系列隐忧,应进行深入研究,寻求相应的对策。【关键词】计算机 过程存储和重组模型 中枢神经系统 信息处理 智力起源 大脑量化模型 文明 自动化 信息化计算机是一种用于协助人类信息处理的工具。计算机科技的发展在各学科和行业的发展..._计算机应用系统等领域的科学研究

Redis trouble12 -- aof 文件损坏修复_修复aof的时候提示failed to truncate aof-程序员宅基地

文章浏览阅读612次。一、问题描述aof持久化的redis执行flushall之后,想恢复数据,于是删除aof中的最后一条指令flushall之后,重启redis提示aof文件损坏,使用fix修复会存在清空数据的危险二、解决方案aof-load-truncated yesredis在恢复时,会忽略最后一条可能存在问题的指令。默认值yes。即在aof写入时,可能存在指令写错的问题(突然断电,写了一半),这种情况下,yes会load并继续,而no会直接恢复失败配置之后重启节点对于redis集群若想恢复需要重._修复aof的时候提示failed to truncate aof

全网最全json数据结构可视化工具汇总_json可视化-程序员宅基地

文章浏览阅读1.5w次,点赞6次,收藏24次。在查阅或编辑过大的json文件时,会因为文本量过多而不容易理清整体的数据结构,这里提供集中数据可视化工具,方便理解json的数据结构。_json可视化

ev使用系列-程序员宅基地

文章浏览阅读207次。使用事件驱动模型实现网络服务程序libev学习笔记(持续更新)库-libev:详解libev源码分析--常用的watcher

数组分割算法_划分数组算法-程序员宅基地

文章浏览阅读1.7k次。W3Cschool数组分割算法挑战: 编写一个函数,把一个数组arr按照指定的数组大小size分割成若干个数组块。 例如:chunk([1,2,3,4],2)=[[1,2],[3,4]]; chunk([1,2,3,4,5],2)=[[1,2],[3,4],[5]];function chunk(arr, size) {var newArr = [];for(var i = 0..._划分数组算法

计算机的发展多媒体应用论文,计算机多媒体技术的前景趋势与应用探讨的优秀论文.docx...-程序员宅基地

文章浏览阅读205次。计算机多媒体技术的前景趋势与应用探讨的优秀论文计算机多媒体技术能够实现视频、声音、图像、数据、文字等信息的处理,它结合了数据传输、数据存储、数据转化等多方面的功能。目前,该技术在多个领域中被应用。  通讯领域中计算机多媒体技术的应用  通讯系统为人们的交流提供了有利条件,该系统可实现信息的交换、传递,通过计算机可同时对视频、音频、动画、文字等信息进行处理,从而实现信息的交流、传播。另外,将计算机与...

随便推点

log4j入门、基础、环境搭建_log4j 搭建-程序员宅基地

文章浏览阅读706次。log4j教程分类: java web 2008-08-25 15:13 7705人阅读 评论(5) 收藏 举报log4jlayoutclassexceptionoutputstring目录(?)[+]1. 简介2. 安装3. log4j基本概念3.1. Logger3.2. Appender3.2.1. 使用ConsoleAppender3.2.2. 使用_log4j 搭建

linux的复制粘贴_linux复制粘贴-程序员宅基地

文章浏览阅读1w次,点赞3次,收藏7次。复制粘贴也适用于外部来源。在其他网站复制命令示例(使用通用 Ctrl+C 键),你可以使用 Ctrl+Shift+V 将此命令粘贴到终端中。同样,你可以使用 Ctrl+shift+C 从终端复制文本,然后使用常规的 Ctrl+V 快捷方式将其粘贴到文本编辑器或 Web 浏览器中。这种行为早在 Ctrl+C 和 Ctrl+V 开始用于复制粘贴文本之前就已经存在。由于 Ctrl+C 键“保留”用于停止命令,因此不能用于复制。基本上,当你与 Linux 终端交互时,你。..._linux复制粘贴

踩了个C++的未定义标识符"cout"的坑_未定义标识符cout-程序员宅基地

文章浏览阅读4w次,点赞40次,收藏54次。问题表现没怎么用过C++写过完整的项目,今天闲来无事,便创建个c++的工程玩玩,结果一个简单的打印输出就给卡住了,无法打开文件“iostream.h”,““cout” 未声明的标识符”,这是什么鬼。。。首先第一个问题,无法打开文件“iostream.h”。找了下外部依赖文件,确实没有文件“iostream.h”,倒是有“iostream”,OK,去掉.h,再编译一遍。结果,无法打开的问题..._未定义标识符cout

Sipdroid实现SIP(六): SIP中的请求超时和重传-程序员宅基地

文章浏览阅读638次。目录一. Sipdroid的请求超时和重传二. SIP中超时和重传的定义三. RFC中超时和重传的定义一. Sipdroid的请求超时和重传Sipdroid实现SIP协议栈系列, 之前的文章仅涉及了SIP消息的基本概念, 比如:请求型消息: INVITE, REGISTER...应答型消息: 100 Trying, 180 Ringing, 200 OK,..._sip呼叫超时是什么原因导致的

element-ui的表格增加行_基于Vue+ElementUI的骨架屏-程序员宅基地

文章浏览阅读1.7k次。vue-elementui-skeleton基于Vue+ElementUI的骨架屏。使用指令v-skeleton的方式生成骨架屏,可自动识别常用的ElementUI组件并生成对应的骨架屏。也提供了N多参数以便进行个性化配置。el-table:自识别:宽度、列数、行高。可配置:行数、圆角、背景色el-menu:TODOel-breadcrumb:TODO...效果安装npm i vue-e..._v-skeleton

ros-melodic-desktop-full : Depends: ros-melodic-perception but it is not going to be installed_ros-melodic-desktop-full : depends: ros-melodic-de-程序员宅基地

文章浏览阅读1.2k次。描述:卸载ros相关的东西,从头开始安装发现缺少依赖。sudo apt install python-rosdep python-rosinstall python-rosinstall-generator python-wstool build-essential_ros-melodic-desktop-full : depends: ros-melodic-desktop but it is not going

推荐文章

热门文章

相关标签