17条嵌入式C语言编程小知识,需要知道( 二 )


a.i = 100;
a.c = ‘A’;
那么此时共用体变量a中的成员i已经没有值了,因为存储该值的内存现在已经被用来存储成员c的值了 。
3> 共用体变量的长度取决于其成员的最大长度:
说明:
结构体变量所占内存的长度是各个成员的总和,每个成员分别占有自己的存储空间 。共用体变量所占内存的长度是其最长成员的长度 。当然,编译器出于提高访问效率的目的,在编译分配存储空间时往往要进行对齐操作 。
对齐操作以最大基本类型为准 。即以最大基本类型为基本单元 。若按实际算下的长度不是基本单元的整数倍,则其实际长度应该是基本单元的整数倍 。
(在TurboC中不进行对齐,在linux中进行对齐)
11. CPU字长与存储器位宽不一致处理
例如:使用共用体来解决这一冲突:
union send_temp{
uint16 words;
uint8 bytes[2];
}send_buff;
eg:send_buff.bytes[0]=a;//此处a 是8位
send_buff.bytes[1]=b;//此处 b 是8位;
此时就将8位字拼成了16位字存储了 。
发送时send(send_buff.words)就可以每次发送一个16位的数据了 。
12. C语言符号优先级:
1>复合赋值运算符号:
a+=3*5;
等价于a=a+(3*5);
13.一个常见的调试策略是把一些printf函数的调用散布于程序中,确定错误出现的具体位置 。但是,这些函数调用的输出结果被写入到缓冲区中,并不立即显示于屏幕上 。事实上,如果程序失败,缓冲输出可能不会被实际写入,因此得到的错误位置就是错误的 。解决的方法是在每个用于调试的printf函数之后立即调用fflush函数即可得到 。

17条嵌入式C语言编程小知识,需要知道

文章插图
 
14.关键字volatile的用法
volatile变量可能用于如下几种情况:
1>设备的硬件寄存器(如:状态寄存器)
2>一个中断服务子程序中会访问到的全局变量
3>多线程应用中被几个任务共享的变量 。
15.关键字register的用法:
当对一个变量频繁被读写时,需要反复访问内存,从而花费大量的存取时间 。为此,C语言提供了一种变量,即寄存器变量 。这种变量存放在CPU的寄存器中,使用时,不需要访问内存,而直接从寄存器中读写,从而提高效率 。寄存器变量的说明符是register 。对于循环次数较多的循环控制变量及循环体内反复使用的变量均可定义为寄存器变量,而循环计数是应用寄存器变量的最好候选者 。
(1) 只有局部自动变量和形参才可以定义为寄存器变量 。因为寄存器变量属于动态存储方式,凡需要采用静态存储方式的量都不能定义为寄存器变量,包括:模块间全局变量、模块内全局变量、局部static变量;
(2) register是一个"建议"型关键字,意指程序建议该变量放在寄存器中,但最终该变量可能因为条件不满足并未成为寄存器变量,而是被放在了存储器中,但编译器中并不报错(在C++语言中有另一个"建议"型关键字:inline) 。
16.对于程序代码,已经被烧录在FLASH或ROM中,我们可以让CPU直接从其中读取代码执行,但通常这不是一个好办法,我们最好在系统启动后将FLASH或ROM中的目标代码拷贝入RAM中后再执行以提高取指令速度 。
CPU对各种存储器的访问速度,基本上是:
CPU内部RAM > 外部同步RAM > 外部异步RAM > FLASH/ROM
17. 宏定义
在C语言中,宏是产生内嵌代码的唯一方法 。对于嵌入式系统而言,为了能达到性能要求,宏是一种很好的代替函数的方法 。
1>宏定义“像”函数;
2>宏定义不是函数,因而需要括上所有“参数”;
3>宏定义可能产生副作用 。因而不要给宏定义传入有副作用的"参数" 。




推荐阅读