我通过这个程序找到了结构的长度,而不使用 sizeof。我有一些找不到答案的问题。
-
我无法理解这一步
(char*)(p+1)-(char*)p)
- 为什么指针的类型转换为字符。 -
我打印了每种数据类型的大小。因此,结构的大小应该是 3* int 的大小 + float 的大小 + char 的大小 = 17。但是,结构的大小为 20。请解释如何。
-
为什么输出为 5 表示
(float*)(p+1)-(float*)p)
.
法典:
#include<stdio.h>
struct sample
{
int a,b;
float c;
char z;
int k;
};
void main()
{
struct sample *p;
struct sample x;
printf("size of struct w/o using sizeof: %dn", (char*)(p+1)-(char*)p);
printf("size of struct w/o using sizeof: %dn", (float*)(p+1)-(float*)p);
printf("size of struct using sizeof: %dn", sizeof(struct sample));
printf(" %d %d %d %dn", sizeof(char), sizeof(int), sizeof(float), sizeof(x));
}
输出:
不带结构的大小,使用大小:20
结构的大小,不带使用大小:5
使用大小的结构大小:20
1 4 4 20
4(感谢您的回答。我还有一个疑问。
法典
struct sample
{
int a,b;
float c;
char z;
int k;
char s;
};
填充后,此结构的大小将为 24 字节。为什么在浮点数(float)((float*)(p+1)-(float*)p)
中打印它不会给出 5.8000 而不是 6。
-
以字节为单位转换将为您提供两个指针之间的字节差异
-
您的结构得到填充以对齐到 4 字节边界。在您的结构中,真实尺寸如下(包括填充(
struct sample { int a,b; // 8 bytes, 4 bytes each float c; // 4 bytes char d; // 4 bytes, 1 byte + 3 padding int k; // 4 bytes }
转换为浮点数将为您提供浮点数 结构的大小(5 浮点数 = 20 字节(
-
类型转换为 (char*(,因为您希望以字符(字节(打印大小。当你递增 p 时,它将按 p 的大小递增。所以 (p+1(-p 是结构的大小,(char *( 有助于以字节为单位打印它。
-
阅读有关结构对齐和填充的信息
-
5 因为这次它的类型转换为 (float *(,因为您想以 float(4 字节(为单位打印大小。当你递增 p 时,它将按 p 的大小递增。所以 (p+1(-p 是结构的大小,(float *( 有助于以浮点数(4 字节(打印它。
-
尽管
(char*)(p+1) - (char*)p)
承诺不使用sizeof *p
,但它确实隐含地这样做,因为指向 p 的指针乘以大小......各自的类型。C99中提到了这一点:http://www.iso-9899.info/n1256.html#FOOTNOTE.91 -
许多 CPU 架构(包括英特尔
x86
系列处理器(都需要在可被其大小整除的地址处读取其多字节整数,例如,对于 4 字节类型,地址必须能被 4 整除。这意味着,当创建struct
数组时,第二个元素的int
s也必须能被4整除,即使你的char
在最后。这就是为什么在那里添加填充并包含在结构的总大小中的原因。 -
此结果是结构的大小除以
float
类型的大小。因为我们现在知道结构的大小是 20,所以p+1
计算地址 p 后 20 个字节,但随后它被转换为float*
,这会将偏移量除以适合间隔的浮点数。