C语言 为什么指针在这里被类型转换为字符



我通过这个程序找到了结构的长度,而不使用 sizeof。我有一些找不到答案的问题。

  1. 我无法理解这一步 (char*)(p+1)-(char*)p) - 为什么指针的类型转换为字符。

  2. 我打印了每种数据类型的大小。因此,结构的大小应该是 3* int 的大小 + float 的大小 + char 的大小 = 17。但是,结构的大小为 20。请解释如何。

  3. 为什么输出为 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。

  1. 以字节为单位转换将为您提供两个指针之间的字节差异

  2. 您的结构得到填充以对齐到 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
    }
    
  3. 转换为浮点数将为您提供浮点数
  4. 结构的大小(5 浮点数 = 20 字节(

  1. 类型转换为 (char*(,因为您希望以字符(字节(打印大小。当你递增 p 时,它将按 p 的大小递增。所以 (p+1(-p 是结构的大小,(char *( 有助于以字节为单位打印它。

  2. 阅读有关结构对齐和填充的信息

  3. 5 因为这次它的类型转换为 (float *(,因为您想以 float(4 字节(为单位打印大小。当你递增 p 时,它将按 p 的大小递增。所以 (p+1(-p 是结构的大小,(float *( 有助于以浮点数(4 字节(打印它。

  1. 尽管(char*)(p+1) - (char*)p)承诺不使用sizeof *p,但它确实隐含地这样做,因为指向 p 的指针乘以大小......各自的类型。C99中提到了这一点:http://www.iso-9899.info/n1256.html#FOOTNOTE.91

  2. 许多 CPU 架构(包括英特尔x86系列处理器(都需要在可被其大小整除的地址处读取其多字节整数,例如,对于 4 字节类型,地址必须能被 4 整除。这意味着,当创建struct数组时,第二个元素的int s也必须能被4整除,即使你的char在最后。这就是为什么在那里添加填充并包含在结构的总大小中的原因。

  3. 此结果是结构的大小除以float类型的大小。因为我们现在知道结构的大小是 20,所以 p+1 计算地址 p 后 20 个字节,但随后它被转换为 float* ,这会将偏移量除以适合间隔的浮点数。

最新更新