第二十四课 #pragma使用分析
#pragma简介
#pragma用于指示编译器完成一些特定的动作
#pragma所定义的很多指示字是编译器特有的
#pragma在不同的编译器间是不可移植的
预处理器将忽略它不认识的#pragma指令
不同的编译器可能以不同的方式解释同一条#pragma指令
一般用法:#pragma parameter
注:不同的parameter参数语法和意义各不相同
#pragma message
message参数在大多数的编译器中都有相似的实现
message参数在编译时输出消息到编译输出窗口中
message用于条件编译中可提示代码的版本信息
#if defined (ANDROID20)
#pragma message(“Compile Andriod SDK2.0…”)
#define VERSION”Android 2.0”
#endif
与#error和#warning不同,#pragma message仅仅代表一条编译消息,不代表程序错误。
24-1 #pragma message使用示例
#pragma once
#pragma once用于保证头文件只被编译一次
#pragma once是编译器相关的,不一定被支持
这两种方式有什么区别?
24-2 #pragma once使用分析
#pragma pack
什么是内存对齐?
不同类型的数据在内存中按照一定的规则排列
而不一定是顺序的一个接一个的排列
Test1和Test2所占的内存空间是否相同?不相同,Test1是12,Test2是8
为什么需要内存对齐?
CPU对内存的读取不是连续的,而是分成块读取的,块的大小只能是1、2、4、8、16…字节
当读取操作的数据未对齐,则需要两次总线周期来访问内存,因此性能会大打折扣
某些硬件平台只能从规定的相对地址处读取特定类型的数据,否则产生硬件异常
#pragma pack用于指定内存对齐方式
#pragma pack能够改变编译器的默认对齐方式
struct占用的内存大小
第一个成员起始于0偏移处
每个成员按类型大小和pack参数中较小的一个进行对齐
偏移地址必须能被对齐参数整除
结构体成员的大小取其内部长度最大的数据成员作为其大小
结构体总长度必须为所有对齐参数的整数倍
编译器在默认情况下按照4字节对齐 #pragma pack(4)
24-3 24-4 结构体大小计算
24-4微软面试题
#include <stdio.h>
#pragma pack(8)
struct S1
{
short a;
long b;
};
struct S2
{
char c;
struct S1 d;
double e;
};
#pragma pack()
int main()
{
printf("%d\n", sizeof(struct S1));
printf("%d\n", sizeof(struct S2));
return 0;
}
所用编译器 老师编译器 VC2010
gcc编译器的#pragma pack(8)的作用
gcc编译器不支持8字节对齐参数,根据默认4字节对齐参数
8字节 4字节
小结:
#pragma用于指示编译器完成一些特定的动作
#pragma所定义的很多指示字是编译器特有的
#pragma message用于自定义编译消息
#pragma once用于保证头文件只被编译一次
#pragma pack用于指定内存对齐方式