为什么c=4而不是1的结构中字符和int的地址不同

为什么c=4而不是1的结构中字符和int的地址不同,c,struct,char,size,C,Struct,Char,Size,我在下面的代码中输入了以下内容 a 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,&b

我在下面的代码中输入了以下内容
a 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));

}
#包括
int main(){
结构体的构造
{
字符名;
浮动价格;
整版;
};
结构书b1、b2、b3;
printf(“输入名称、价格和页数\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));
}
我得到了以下输出

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


现在我不明白的是,b1.name(2686740)和b1.price(2686744)的地址之间的差异是4,其中b1.name是一个字符,所以差异应该是1,b2和b3中也重复了相同的内容。请帮忙

这是因为结构填充

计算机处理器的体系结构是这样的:它一次可以从内存中读取一个字

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

默认情况下,填充处于启用状态。它将以下间隙插入到第一个结构中:

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

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

这可以通过使用
#pragma包(1)

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

但是,由于您没有命令编译器打包为1字节块,因此它打包为n字节块,其中
n=结构内部最大类型的大小,在您的情况下为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

播放以下片段:

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));

你偶然发现的东西叫做“字节填充”。研究一下,你会得到一些好文章来帮助你理解它。可能是重复的。我甚至不知道什么是填充,所以我无法根据它进行搜索。你使用的编译器在结构中添加填充。指针的正确格式说明符是%p,而不是%d。
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));