1、volatile关键字
volatile int i=10;
int j = i;
...
int k = i;
volatile告诉编译器i变量是随时可能发生变化的,例如IO端口的输入值,所以每次读取i都是从i的地址中读取,而不是,当重读读取i时发现读取变量一样,调用上次的寄存器。
下面是volatile变量的几个例子:
-
并行设备的硬件寄存器(如:状态寄存器)
-
一个中断服务子程序中会访问到的非自动变量(Non-automatic variables)
-
多线程应用中被几个任务共享的变量 回答不出这个问题的人是不会被雇佣的。
int square(volatile int *ptr)
{
return *ptr * *ptr;
}
可以等同为下面代码
int square(volatile int *ptr)
{
int a,b;
a = *ptr;
b = *ptr;
return a * b;
}
正确的平方代码应为
int square(volatile int *ptr)
{
int a;
a = *ptr;
return a * a;
}
2、union 联合体、共用体
结构体占用的内存大于等于所有成员占用的内存的总和
(成员之间可能会存在缝隙),
共用体占用的内存等于最长的成员占用的内存
。
共用体使用了内存覆盖技术,同一时刻只能保存一个成员的值,如果对新的成员赋值,就会把原来成员的值覆盖掉
。
计算的时候需要考虑字节对齐问题:
- 所占空间必须是成员变量中字节最大的整数倍
- 每个变量类型的偏移量必须是该变量类型的整数倍
- 对于联合体,由于所有变量都是共用一块内存,还需注意数组占用最大内
存
例如:
Typedef union {double I;int k[5];char c;} DATE;
在联合体中成员变量最大为 double 为 8 个字节,所以最终大小必须是 8
的整数倍;又因为联合体是共占内存空间,即 int*5=20 字节,所以最终
为 24 个字节