前言
本章节主要讲解:
- 深入关键字volatile
- 深入关键字struct
- 深入关键字union
- 深入关键字enum
- 深入关键字typedef
关键字 - volatile
- 结论:
volatile是一个类型修饰符,作用是作为指令关键字,一般都是和const对应
用来确保本条指令不会被编译器的优化而忽略(既保持内存可见性)
- 示例:
- 不加volatile
int main() { int i = 10; int a = i; printf("i=%d\n ", i); //下面汇编语句的作用就是改变内存中i的值,但是又不让编译器知道 __asm { mov dword ptr[ebp - 4], 20h } int b = i; printf("i=%d\n", b); return 0; }
在debug(调试)版本模式运行程序,输出结果如下:
i = 10
i = 32
然后在release版本模式运行下,输出结果如下:
i = 10
i = 10
- 加上volatile
int main() { volatile int i = 10; int a = i; printf("i=%d\n ", i); //下面汇编语句的作用就是改变内存中i的值,但是又不让编译器知道 __asm { mov dword ptr[ebp - 4], 20h } int b = i; printf("i=%d\n", b); return 0; }
分别在debug和release版本运行结果都是如下:
i = 10
i = 32
关于const与volatile
const要求你不要进行写入;volatile意思是你读取时,每次都要从内存读,两者并不冲突
所以,一个参数既可以是const还可以是volatile
- 例如只读的状态寄存器:
它是volatile因为它可能被意想不到地改变
它是const因为程序不应该试图去修改它
关键字-struct
空结构体多大
- 示例:
struct student { }stu; int main (void) { printf ("sizeof (stu) = %d\n", sizeof (stu)); return 0; }
输出结果: 在C中, sizeof (stu) = 0 在C++中, sizeof (stu) = 1
结论:对于空结构体不同编译器理解不同,所以大小不一(可能0或者1)
struct的内存对齐
定义:struct中的各成员变量的存储地址有一套对齐的机制(让CPU能够更舒服地访问变量)
struct内存空间的分配是粗放的,不管用不用,全分配
- 规律:
- 每个成员变量的首地址,必须是它的类型的所占字节数的整数倍,如果不满足,它与前一个成员变量之间要填充(padding)一些无意义的字节来满足;
- 整个struct的大小,必须是该struct中所有成员的类型中占字节最大者的整数倍,如果不满足,在最后一个成员后面填充
- 示例:
struct student{ char sex; int score; };
- 现象:
第一个char类型成员与第二个int类型成员之间会填充数据,(要求1);
最大长度为整型占用4个字节的空间,所以其占用的空间为4的倍数,这样s占用的空间就是8个字节(要求2)
注意:数据成员的书写顺序会影响结构体占用的空间的大小,尽量将相同数据类型的变量连续书写