嵌入式系统程序设计.ppt
voidsetzero(char*p,intn){for(;n0;n--){p=0;p++;}}清除从字符型指针p开始的n个字节空间12一、编译器的特性问题:编译器的特性(续)voidsetzero(char*p,intn){for(;n0;n--){*p=0;p++;}}问题:编译器不知道n是否为0。编译器不知道p是否4字节对齐。编译器不知道n是否为4的倍数。结论:01编译器是保守的:必须假定n的所有可能值。必须假定p所有可能的边界值。01了解哪些方面编译器是保守的01了解编译器对应的处理器体系结构02编写高效C代码的要求二、数据类型对程序效率的影响unsignedchari;for(i=0;i100;i++){…}i声明为unsignedchar的优点?无符号字符变量表示的范围超过了100,可以完成题目要求。char更节省寄存器和内存空间。函数参数类型总体思想:尽量采用int、long类型。A如果程序中只有加、减、乘法,那么有符号数和无符号数的执行效率没有区别。B如果有除法,那么需要额外的步骤。有符号数和无符号数有符号数和无符号数(续)有符号除法在ARMC中,如果x是负数,那么除2操作不是一个右移操作。例如-3/2=-1。但是在ARM机器中:11111101-311111110-2-111111111直接右移加1右移结论:使用无符号数除法效率更高。BAC对于存放在寄存器中的变量,尽量采用整型。函数参数和返回值尽量采用整型数据。尽可能使用无符号数进行运算。总结三、循环方式对程序效率的影响循环是代码优化的重点C程序主要使用for和while进行循环固定次数的循环什么是ARM上编写for循环最高效的方法?固定次数的循环(续)inti;for(i=0;i100;i++){…}inti;for(i=100;i0;i--){…}上面代码要实现转移需要两条指令,首先把某寄存器的内容和100比较,其次条件符合时转移。相同功能的代码如果写作下面形式,则可用“BNE”一条指令实现比较以及转移两个功能。打开一个日志文件,syslog()函数可以向其中写入消息,不返回文件描述符(与open()不一样)message是指定加到日志中的字符串option是选项的“或”值,见下页facility是“功能表”中的某个值。voidopenlog(constchar*message,intoption,intfacility)功能:格式:B.openlog()函数openlog的选项选项描述LOG_PID在每条消息中包含PID(进程号)LOG_CONS如果消息不能写入日志文件,则发到控制台LOG_NDELAY立即打开连接(默认是在syslog第一次被调用时才打开连接)LOG_PERROR把消息写入日志文件的同时也输入到stderr注:openlog是可选的,如果不显式调用它,则在第一次调用syslog时,syslog函数会自动调用openlog。openlog(justtry,LOG_PID,LOG_USER);syslog(LOG_NOTICE,thecurrentnumberis%d\n,iNum);01代码在/var/log/messages文件中产生如下信息:02Sep2221:20:22lxcjusttry[2432]:thecurrentnumberis503openlog举例用途:函数原型:关闭由openlog打开的文件描述符。voidcloselog(void);C.closelog()函数D.setlogmask()函数用途:为所有的日志消息设置默认的级别。syslog拒绝任何没有在掩码中设置的优先级的消息。函数原型: intsetlogmask(intpriority); 参数priority可以是单个的优先级,也可以是一个优先级的范围。这里有两个宏: LOG_MASK(intpriority):创建一个仅由一个优先级级,priority代表优先级别。 LOG_UPTO(intpriority):创建优先级范围,priority代表其中的最低优先级,并作为参数传给该宏【例3-23】/* ch3_23.c */#includestdio.h#in