我想知道是否有人能向我解释一下#pragma pack预处理器语句是做什么的,更重要的是,为什么要使用它.

我查看了MSDN page,它提供了一些见解,但我希望从有经验的人那里听到更多.我以前在代码中见过它,但我似乎再也找不到它的位置了.

推荐答案

#pragma pack指示编译器使用特定对齐方式打包 struct 成员.大多数编译器在声明 struct 时,都会在成员之间插入填充,以确保它们与内存中的适当地址对齐(通常是类型大小的倍数).这避免了与访问未正确对齐的变量相关的某些体系 struct 的性能损失(或直接错误).例如,给定4字节整数和以下 struct :

struct Test
{
   char AA;
   int BB;
   char CC;
};

编译器可以 Select 这样在内存中布局 struct :

|   1   |   2   |   3   |   4   |  

| AA(1) | pad.................. |
| BB(1) | BB(2) | BB(3) | BB(4) | 
| CC(1) | pad.................. |

and sizeof(Test) would be 4 × 3 = 12, even though it only contains 6 bytes of data. The most common use case for the #pragma (to my knowledge) is when working with hardware devices where you need to ensure that the compiler does not insert padding into the data and each member follows the previous one. With #pragma pack(1), the struct above would be laid out like this:

|   1   |

| AA(1) |
| BB(1) |
| BB(2) |
| BB(3) |
| BB(4) |
| CC(1) |

And sizeof(Test) would be 1 × 6 = 6.

对于#pragma pack(2),上面的 struct 布局如下:

|   1   |   2   | 

| AA(1) | pad.. |
| BB(1) | BB(2) |
| BB(3) | BB(4) |
| CC(1) | pad.. |

And sizeof(Test) would be 2 × 4 = 8.

struct 中变量的顺序也很重要.变量的顺序如下:

struct Test
{
   char AA;
   char CC;
   int BB;
};

如果是#pragma pack(2), struct 的布局如下:

|   1   |   2   | 

| AA(1) | CC(1) |
| BB(1) | BB(2) |
| BB(3) | BB(4) |

sizeOf(Test)等于3×2=6.

C++相关问答推荐

如何在Scilab API中求解方程

如何从C中的公钥字符串创建EVP_PKEY

理解C中的指针定义

为什么I2C会发送错误的数据?

不会停在空格或换行符上的错误

当我运行/调试C程序时,Malloc()似乎正在将&q;r\r...&q;赋值给一个指针,我不确定为什么?

将数据移动到寄存器时出现分段故障

可变宏不能编译

Caesar密码调试:输出文本末尾的问号和随机字符

Realloc():中止的下一个大小无效(核心转储)

如何在不更改格式说明符的情况下同时支持双精度和长双精度?

我编写这段代码是为了判断一个数字是质数、阿姆斯特朗还是完全数,但由于某种原因,当我使用大数时,它不会打印出来

存储和访问指向 struct 的指针数组

浮点正零何时不全为零?

不兼容的整数到指针转换传递';char';到类型';常量字符*

atoi函数最大长-长误差的再创造

DennisM.Ritchie的C编程语言一书中关于二进制搜索的代码出现错误?

这些表达式是否涉及 C 中定义的复合文字?

在 C 中传递参数时出现整数溢出

变量的指针右对齐,函数的指针左对齐