【问题标题】:Why pointer is typecasted as a char here?为什么指针在这里被强制转换为字符?
【发布时间】:2015-04-08 23:24:57
【问题描述】:

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

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

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

  3. 为什么(float*)(p+1)-(float*)p) 的输出是 5。

代码:

#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: %d\n", (char*)(p+1)-(char*)p);

    printf("size of struct w/o using sizeof: %d\n", (float*)(p+1)-(float*)p);

    printf("size of struct using sizeof: %d\n", sizeof(struct sample));

    printf(" %d %d %d %d\n", sizeof(char), sizeof(int), sizeof(float), sizeof(x));

}

输出:

不使用 sizeof 的结构大小:20
不使用 sizeof 的结构大小:5
使用 sizeof 的结构大小:20
1 4 4 20

4) 感谢您的回答。我还有一个疑问。

代码

struct sample
{
int a,b;
float c;
char z;
int k;
char s;
};

填充后,这个结构的大小将是 24 字节。为什么在 float (float)((float*)(p+1)-(float*)p) 中打印它不会给出 5.8000 而不是 6。

【问题讨论】:

  • 对于 1 和 3:你对 p+1 的理解是什么? sizeof(char) 是什么? sizeof(float) 是什么?
  • 提示:对于问题 2,请参考结构填充。
  • 5 因为大小是 5 个浮点数(5 x 4 字节)
  • 不是。它被类型转换为 pointer 到 char。

标签: c pointers type-conversion


【解决方案1】:
  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. 转换为浮点数将为您提供浮点数中的 sizeof 结构(5 个浮点数 = 20 字节)

【讨论】:

  • 值得注意的是,您列出的所有大小(除 char [定义为 1] 之外的类型以及结构成员之间的填充量)都是实现定义的。
【解决方案2】:
  1. 类型转换为 (char*),因为您想以 char(字节)为单位打印大小。当你增加 p 时,它会增加 p 的大小。所以 (p+1)-p 是结构的大小, (char *) 帮助以字节为单位打印它。

  2. 了解结构对齐和填充

  3. 5 因为这一次它被类型转换为 (float *) 因为你想以浮点为单位打印大小(4 个字节)。当你增加 p 时,它会增加 p 的大小。所以 (p+1)-p 是结构的大小, (float *) 帮助以浮点数(4 个字节)打印它。

【讨论】:

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

    2. 许多 cpu 架构,包括 intel x86 系列处理器,需要在可被其大小整除的地址处读取其多字节整数,例如对于 4 字节类型,该地址必须能被其大小整除4. 这意味着,当您的struct 创建一个数组时,即使您的char 在末尾,第二个元素的ints 也必须也能被4 整除。这就是为什么在此处添加填充并包含在结构的总大小中的原因。

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

    【讨论】:

      猜你喜欢
      • 2021-05-08
      • 2013-06-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多