目录
结构体
1.怎么计算结构体各个成员的偏移量
方法一:通过定义结构体变量求偏移量
?方法二:不定义结构体变量求偏移量
方法三:通过宏函数:
#define MY_OFFEST(type,arg) ?(int)&(((type*)0)->arg)?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
共用体
计算共用体占多少字节
?联合体应用:判断平台是大端还是小端
??自定义类型嵌套自定义类型:
位段:位域
结构体
1.怎么计算结构体各个成员的偏移量
struct Node
{
char a;
short b;
int c;
float d;
double f;
long long int l;
};
?
方法一:通过定义结构体变量求偏移量
int main()
{
struct Node tmp;
int dist = ((char*)&(tmp.d) - (char*)&tmp);//指针-指针 求d的偏移量
printf("%d\n", dist);
return 0;
}
?
?
?方法二:不定义结构体变量求偏移量
定义了一个指针指向0,指针类型为Node*,通过->访问里边的成员,再取其地址。此时左边的类型为int,右边类型为float*类型将其强转为int类型(假设开始地址从0开始)
int main()
{
int dist = (int)&(((struct Node*)0)->d);//假设开始地址从0开始 0地址强转为Node*指针类型 指向d
printf("%d\n", dist);
return 0;
}
?
?
方法三:通过宏函数:
#define MY_OFFEST(type,arg) ?(int)&(((type*)0)->arg)? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
?将0地址强转为type类型的指针,通过->访问成员,整体取地址,再将强转为int类型
#define MY_OFFEST(type,arg) ((int)&(((type*)0)->arg))
int main()
{
printf("%d\n", MY_OFFEST(Node, a));
printf("%d\n", MY_OFFEST(Node, b));
printf("%d\n", MY_OFFEST(Node, c));
printf("%d\n", MY_OFFEST(Node, d));
return 0;
}
?
共用体
?自定义类型:结构体、共用体 共用体:也叫联合体,共用体内所有成员共享同一内存,每个成员都是顶头开始 共用体所占共享内存,所以成员都可以访问,只不过最好有一人使用,其他人都不再使用,以免发生错误
计算共用体占多少字节
方法:算最大的并且需要整体大小能整除最大成员所占的字节数
union D {? ? ? ? ? ? ? ? ? ? ? ? ? ? ?1.找最大的为20 ?? ?char a;? ? ? ? ? ? ? ?2.20不能整除8(最大成员所占字节数) ?? ?short b;? ? ? ? ? ? ? 3.20+4=24 可以整除 ?? ?int c;? ? ? ? ? ? ? ? ? 4得到字节数为24 ?? ?double d; ?? ?long long l; ? ?? ?int arr[5]; };
?联合体应用:判断平台是大端还是小端
小端:低地址存低数据
union W? ? ? ? ? ? ? ?给W.b=1? ? ?32位的二进制位0000000000...01 ?? ?{? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 如果是小端存储方式位? 01? 00? 00? 00 ?? ??? ?char a;? ? ? ? ? ? ? ? ? ?a只用这四个字节的四分之一,a只能看到01 ?? ??? ?int b;? ? ? ? ? ? ? ? ? ? ? ? 如果是大端存储方式为 00? 00? 00? 01 ?? ?};? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 此时a只能看到00
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?所以判断大小端只需看a打印的结果是不是1
bool Islittle()
{
union //联合体只使用一次可不设置名字
{
char a;
int b;
}tmp;
tmp.b = 0x12345678; //给.b赋值
return tmp.a == 0x78;
}
int main()
{
bool flg = Islittle();
if (flg)
{
printf("小端\n"); //若a为0x78则为小端
}
else
printf("大端\n");
return 0;
}
?
??自定义类型嵌套自定义类型:
?? ?1.里面的自定义类型上面有名字,下面没有名字 类型声明 不占空间 ?? ?2.里面的自定义类型上面有名字,下面有名字 ? 类型声明时顺便定义了一个变量
struct K//32(所占空间大小) { ?? ?int a; ?? ?double b; ?? ?union L ?? ?{ ?? ??? ?int a; ?? ??? ?int arr[4]; ?? ?}aaa; }; ?? ?3.里面的自定义类型上面没有名字,下面没有名字 相当于定义了一个自定义类型变量放在那里
struct KK//32 { ?? ?int a; ?? ?double b; ?? ?union? ?? ?{ ?? ??? ?int a; ?? ??? ?int arr[4]; ?? ?}; }; ?? ?4.里面的自定义类型上面没有名字,下面有名字 ?相当于这个自定义类型只用了一次,定义了一个变量,所以不给名字
struct KKK//32 { ?? ?int a; ?? ?double b; ?? ?union? ?? ?{ ?? ??? ?int a; ?? ??? ?int arr[4]; ?? ?}aaa; };
位段:位域
位段,C语言允许在一个结构体中以位为单位来指定其成员所占内存长度,这种以位为单位的成员称为“位段”或称“位域”( bit field) 。利用位段能够用较少的位数存储数据。
?
struct W
{
char a : 3;//char:(不能大于8);
char b : 2;
char c : 5;
};
int main()
{
printf("%d\n", sizeof(W));
return 0;
}
?
|