【问题标题】:why is the difference in address of character and int in a structure in c =4 and not 1为什么 c = 4 而不是 1 的结构中字符和 int 的地址不同
【发布时间】:2019-01-19 06:07:27
【问题描述】:

我在下面的代码中给出了以下输入
12.5 12
b 13.5 13
c 14.5 14

#include <stdio.h>
int main(){

struct book
{
char name;
float price;
int pages;
};

struct book b1,b2,b3;



printf("enter name , price ,& no of pages\n");
scanf(" %c %f %d",&b1.name,&b1.price,&b1.pages);



scanf(" %c %f %d",&b2.name,&b2.price,&b2.pages);


scanf(" %c %f %d",&b3.name,&b3.price,&b3.pages);



printf("%c %d %f %d %d %d",b1.name,&b1.name,b1.price,&b1.price,b1.pages,&b1.pages);

printf("\n%c %d %f %d %d %d",b2.name,&b2.name,b2.price,&b2.price,b2.pages,&b2.pages);

printf("\n%c %d %f %d %d %d",b3.name,&b3.name,b3.price,&b3.price,b3.pages,&b3.pages);

printf("\n%d %d %d",sizeof(b1.name),sizeof(b1.price), sizeof(b1.pages));

}

我得到了以下输出

2686740 12.500000 2686744 12 2686748
b 2686728 13.500000 2686732 13 2686736
c 2686716 14.500000 2686720 14 2686724
1 4 4

现在我无法理解的是 b1.name(2686740) 和 b1.price(2686744) 的地址之间的差异是 4 其中 b1.name 是一个字符,所以差异应该是 1 并且相同在 b2 和 b3 中也重复。请帮忙!!!

【问题讨论】:

  • 您偶然发现的称为“字节填充”。研究它,你会得到很好的文章来帮助你理解它。
  • 好吧,我什至不知道填充是什么,所以我无法根据它进行搜索
  • 这是您使用的编译器在结构中添加填充。
  • 指针的正确格式说明符是 %p,而不是 %d。

标签: c struct char size


【解决方案1】:

这是因为结构padding

计算机处理器的架构是这样一种方式,它可以一次从内存中读取 1 个单词。

为了利用处理器的这一优势,数据总是对齐为 4 字节的包,这导致在其他成员的地址之间插入空地址。例如在 64 位系统上,int 应从可被 4 整除的地址开始,long 可被 8 整除,short 可被 2 整除。

默认情况下填充是打开的。它将以下间隙插入到您的第一个结构中:

struct book
{
   char name;
   char padded_gap[3]; //padding extra 3 bytes
   float price;
   int pages;
};

【讨论】:

    【解决方案2】:

    拥有不同类型的结构体可以被紧密地打包(这意味着地址之间的差异将如你所想):

    |--0--|--1--|--2--|--3--||||--4--|--5--|--6--|--7--||||--8--|--9--|--10--|--11--|
       c     f0    f1    f2       f3    i0    i1    i2    i3
    

    这可以通过使用#pragma pack(1)来实现

    #pragma pack 指示编译器以特定对齐方式打包结构成员

    但是,由于您没有命令编译器打包成 1 字节块,它打包成 n 字节块,其中 n = size of largest type inside struct,在您的情况下是 4 字节,导致:

    |--0--|--1--|--2--|--3--||||--4--|--5--|--6--|--7--||||--8--|--9--|--10--|--11--|
       c    pad0  pad1  pad2      f0    f1    f2       f3    i0    i1    i2     i3
    

    玩一下这个 sn-p:

    struct A{
        char c;   // has 7 bytes padding due to having a double in the struct
        double d; // size 8
    }AA;
    
        printf("%d\n", sizeof(AA));
    
    // feel free to change the parameter inside the pragma pack
    #pragma pack(1) 
    struct B{
        char c;   // has no padding due to pack(1)
        double d;
    }BB;
    #pragma pack(0)
    
        printf("%d\n", sizeof(BB));
    
    #pragma pack(2)
    struct C{
        char c;    // has only 1 byte padding
        double d;
    }CC;
    #pragma pack(0)
    
        printf("%d\n", sizeof(CC));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-02-02
      • 2011-09-07
      • 1970-01-01
      • 2011-10-03
      • 2013-11-15
      • 1970-01-01
      • 2015-09-29
      相关资源
      最近更新 更多