#include <stdio.h>
#include <stdlib.h>
typedef struct A
{
char a;
int b;
float c;
double d;
int *e;
char *f;
short g;
}A;
int main(int argc, char *argv[])
{
printf("sizeof A=%d\n",sizeof(A));
printf("sizeof char=%d\n",sizeof(char));
printf("sizeof int=%d\n",sizeof(int));
printf("sizeof float=%d\n",sizeof(float));
printf("sizeof double=%d\n",sizeof(double));
printf("sizeof int*=%d\n",sizeof(int*));
printf("sizeof char*=%d\n",sizeof(char*));
printf("sizeof short=%d\n",sizeof(short));
return 0;
}
程序运行截图:
9 个解决方案
#1
搜“c语言结构体字节对齐”
#2
项目属性可以设置 字节对齐方式
32位操作系统默认应该是 32bit
也就是每个成员变量的起始地址是4字节的倍数
是一个char a[1] 和 a[4]占有的空间一样
32位操作系统默认应该是 32bit
也就是每个成员变量的起始地址是4字节的倍数
是一个char a[1] 和 a[4]占有的空间一样
#3
+1
#4
结构体的对齐和补齐,在32位机上是按照4个字节进行对齐和补齐的。即小于4个字节的数据类型会自动转换为4个字节。大于或者是等于4个字节的。会保存4个字节的倍数。你还可以去看一下大小端的问题。也是用的这个原理。
#5
你的意思是
sizeof (struct {char c;})
的结果是4??
#6
在 结构定义前加上 #pragma pack(1) 再试试
#7
仅供参考:
#include <stdio.h>
#define field_offset(s,f) (int)(&(((struct s *)(0))->f))
struct AD { int a; char b[13]; double c;};
#pragma pack(push)
#pragma pack(1)
struct A1 { int a; char b[13]; double c;};
#pragma pack(2)
struct A2 { int a; char b[13]; double c;};
#pragma pack(4)
struct A4 { int a; char b[13]; double c;};
#pragma pack(8)
struct A8 { int a; char b[13]; double c;};
#pragma pack(16)
struct A16 { int a; char b[13]; double c;};
#pragma pack(pop)
int main() {
printf("AD.a %d\n",field_offset(AD,a));
printf("AD.b %d\n",field_offset(AD,b));
printf("AD.c %d\n",field_offset(AD,c));
printf("\n");
printf("A1.a %d\n",field_offset(A1,a));
printf("A1.b %d\n",field_offset(A1,b));
printf("A1.c %d\n",field_offset(A1,c));
printf("\n");
printf("A2.a %d\n",field_offset(A2,a));
printf("A2.b %d\n",field_offset(A2,b));
printf("A2.c %d\n",field_offset(A2,c));
printf("\n");
printf("A4.a %d\n",field_offset(A4,a));
printf("A4.b %d\n",field_offset(A4,b));
printf("A4.c %d\n",field_offset(A4,c));
printf("\n");
printf("A8.a %d\n",field_offset(A8,a));
printf("A8.b %d\n",field_offset(A8,b));
printf("A8.c %d\n",field_offset(A8,c));
printf("\n");
printf("A16.a %d\n",field_offset(A16,a));
printf("A16.b %d\n",field_offset(A16,b));
printf("A16.c %d\n",field_offset(A16,c));
printf("\n");
return 0;
}
//AD.a 0
//AD.b 4
//AD.c 24
//
//A1.a 0
//A1.b 4
//A1.c 17
//
//A2.a 0
//A2.b 4
//A2.c 18
//
//A4.a 0
//A4.b 4
//A4.c 20
//
//A8.a 0
//A8.b 4
//A8.c 24
//
//A16.a 0
//A16.b 4
//A16.c 24
//
//
#8
+1
#9
typedef struct A
{
char a;
int b;
float c;
double d;
int *e;
char *f;
short g;
}A;
该struct中,double类型所占空间最大,故此该struct为8字节对齐方式,a和b占据8个字节,c占据8个字节,d占据8个字节,两个指针占据8个字节,最后一个short占据8个字节,一共是40个字节。
内存对齐技术是一种以空间换取读取效率的做法,比如b,应该是从第5个字节存储到第8个字节,字节偏移为4,实际上就是要struct实例对象的基地址+字节偏移4能够整除b的类型大小(int为4)。具体你可以打印出所有struct成员的地址来看看内存排布,PS:打印a地址的时候,请注意将其强制转换为(void*),否则打印出来的不是地址值。
{
char a;
int b;
float c;
double d;
int *e;
char *f;
short g;
}A;
该struct中,double类型所占空间最大,故此该struct为8字节对齐方式,a和b占据8个字节,c占据8个字节,d占据8个字节,两个指针占据8个字节,最后一个short占据8个字节,一共是40个字节。
内存对齐技术是一种以空间换取读取效率的做法,比如b,应该是从第5个字节存储到第8个字节,字节偏移为4,实际上就是要struct实例对象的基地址+字节偏移4能够整除b的类型大小(int为4)。具体你可以打印出所有struct成员的地址来看看内存排布,PS:打印a地址的时候,请注意将其强制转换为(void*),否则打印出来的不是地址值。
#1
搜“c语言结构体字节对齐”
#2
项目属性可以设置 字节对齐方式
32位操作系统默认应该是 32bit
也就是每个成员变量的起始地址是4字节的倍数
是一个char a[1] 和 a[4]占有的空间一样
32位操作系统默认应该是 32bit
也就是每个成员变量的起始地址是4字节的倍数
是一个char a[1] 和 a[4]占有的空间一样
#3
+1
#4
结构体的对齐和补齐,在32位机上是按照4个字节进行对齐和补齐的。即小于4个字节的数据类型会自动转换为4个字节。大于或者是等于4个字节的。会保存4个字节的倍数。你还可以去看一下大小端的问题。也是用的这个原理。
#5
你的意思是
sizeof (struct {char c;})
的结果是4??
#6
在 结构定义前加上 #pragma pack(1) 再试试
#7
仅供参考:
#include <stdio.h>
#define field_offset(s,f) (int)(&(((struct s *)(0))->f))
struct AD { int a; char b[13]; double c;};
#pragma pack(push)
#pragma pack(1)
struct A1 { int a; char b[13]; double c;};
#pragma pack(2)
struct A2 { int a; char b[13]; double c;};
#pragma pack(4)
struct A4 { int a; char b[13]; double c;};
#pragma pack(8)
struct A8 { int a; char b[13]; double c;};
#pragma pack(16)
struct A16 { int a; char b[13]; double c;};
#pragma pack(pop)
int main() {
printf("AD.a %d\n",field_offset(AD,a));
printf("AD.b %d\n",field_offset(AD,b));
printf("AD.c %d\n",field_offset(AD,c));
printf("\n");
printf("A1.a %d\n",field_offset(A1,a));
printf("A1.b %d\n",field_offset(A1,b));
printf("A1.c %d\n",field_offset(A1,c));
printf("\n");
printf("A2.a %d\n",field_offset(A2,a));
printf("A2.b %d\n",field_offset(A2,b));
printf("A2.c %d\n",field_offset(A2,c));
printf("\n");
printf("A4.a %d\n",field_offset(A4,a));
printf("A4.b %d\n",field_offset(A4,b));
printf("A4.c %d\n",field_offset(A4,c));
printf("\n");
printf("A8.a %d\n",field_offset(A8,a));
printf("A8.b %d\n",field_offset(A8,b));
printf("A8.c %d\n",field_offset(A8,c));
printf("\n");
printf("A16.a %d\n",field_offset(A16,a));
printf("A16.b %d\n",field_offset(A16,b));
printf("A16.c %d\n",field_offset(A16,c));
printf("\n");
return 0;
}
//AD.a 0
//AD.b 4
//AD.c 24
//
//A1.a 0
//A1.b 4
//A1.c 17
//
//A2.a 0
//A2.b 4
//A2.c 18
//
//A4.a 0
//A4.b 4
//A4.c 20
//
//A8.a 0
//A8.b 4
//A8.c 24
//
//A16.a 0
//A16.b 4
//A16.c 24
//
//
#8
+1
#9
typedef struct A
{
char a;
int b;
float c;
double d;
int *e;
char *f;
short g;
}A;
该struct中,double类型所占空间最大,故此该struct为8字节对齐方式,a和b占据8个字节,c占据8个字节,d占据8个字节,两个指针占据8个字节,最后一个short占据8个字节,一共是40个字节。
内存对齐技术是一种以空间换取读取效率的做法,比如b,应该是从第5个字节存储到第8个字节,字节偏移为4,实际上就是要struct实例对象的基地址+字节偏移4能够整除b的类型大小(int为4)。具体你可以打印出所有struct成员的地址来看看内存排布,PS:打印a地址的时候,请注意将其强制转换为(void*),否则打印出来的不是地址值。
{
char a;
int b;
float c;
double d;
int *e;
char *f;
short g;
}A;
该struct中,double类型所占空间最大,故此该struct为8字节对齐方式,a和b占据8个字节,c占据8个字节,d占据8个字节,两个指针占据8个字节,最后一个short占据8个字节,一共是40个字节。
内存对齐技术是一种以空间换取读取效率的做法,比如b,应该是从第5个字节存储到第8个字节,字节偏移为4,实际上就是要struct实例对象的基地址+字节偏移4能够整除b的类型大小(int为4)。具体你可以打印出所有struct成员的地址来看看内存排布,PS:打印a地址的时候,请注意将其强制转换为(void*),否则打印出来的不是地址值。