结构体和共用体各有什么特点:
1、结构体中每一个成员都有自己的内存空间,计算结构体大小的时候要注意内部字节对齐;
32位占4字节,64位占8字节。
结构体访问成员:点降级访问
2、共用体又叫联合体union,每一个成员都共享内存空间。同一时间只能使用一个成员变量的值,初始化时同一时间只能给一个变量赋值。因此,共用体大小等于成员中占内存最大的那个大小。
结构体字节对齐的原则?字节对齐3原则
1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除;
2) 结构体每个成员相对结构体首地址的偏移量(offset)都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节(internal adding);
3) 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节{trailing padding}。
概况起来就是三对齐:首地址对齐(按最大)、总大小对齐(按最大)、成员对齐(按成员类型)
练习1:
struct student
{
char a; //1
int c; //4
}struct student
{
char a; //1
short b; //2
int c; //4
}struct student
{
char a; //1
char d; //1
int c; //4
short b; //2
}
练习2:
typedef int BOOL;
union val_t
{
BOOL b_val; //bool类型存储空间
int i_val; //整形值存储空间
float f_val; //浮点值存储空间
};
- 定义一个
val_t
类型的变量a,对a的f_val进行赋值,然后打印f_val成员的值(值随意赋)。 - 定义一个变量
val_t
类型的变量b,将a的值赋给变量b。 - 比较变量a和变量b的值是否相等(思考下如果是结构体呢?)
#include <stdio.h>
typedef int BOOL;
union val_t
{
BOOL v_val;
int i_val;
float f_val;
};
int main(void)
{
union val_t a, b;
a.f_val = 2.1;
b = a;
printf("a.f_val = %f, b.f_val = %f\n", a.f_val, b.f_val);
//memcmp 内存比较
//从s1和s2两个起始地址开始比较,比较n字节是否相等。
//如果相等,返回0,如果不相等返回非0
int memcmp(const void *s1,const void *s2,size_t n);
//memcpy 内存拷贝
printf("a和b的比较结果为:%d\n",memcmp(&a,&b,sizeof(a)));
return 0;
}
结论
- 对于C语言符合数据类型(结构体、共用体)可以直接赋值。
- 但是不可以直接比较。
- 如果直接比较,使用
memcmp
方法。