初识C语言:4.自定义类型:结构体,枚举,联合

  1. 结构体

1.1定义

结构体是一些值的集合,这些值称为结构体的成员变量

1.2结构体的声明

struct tag
{
    member-list;
}variable-list;

eg:
struct Stu//结构体类型
{
    char name[20];//成员变量
    int age;//成员变量
}student1,student2;//声明的同时定义结构体变量student1,student2,
struct Stu student3={"luzun",22};//定义结构体变量students3并初始化
struct Stu s[3]={{"mazun",22},{"zhaozun",22},{"jiange",22}};//定义结构体数组并初始化

1.3结构体自引用

struct Node
{
    int data;
    struct Node* next;
};
struct Node n1={10,NULL};


typedef struct
{
    int data;
    struct Node* next;
}Node;

1.4结构体内存对齐

结构体内存对齐决定了结构体占内存空间的大小。

  • 结构体的第一个成员变量永远在偏移量为0的地址处。

  • 从第二个成员变量开始,都要对齐到某个数字(对齐数)的整数倍处的地址。

这个数是编译器中一个默认数字与该成员大小的较小值。(VS中默认是8)

  • 结构体大小一定为最大对齐数的整数倍。

  • 如果嵌套结构体,嵌套的结构体就要对齐到自己最大对齐数的整数倍。

对齐后内存访问只需一次,是一种拿空间换时间的做法

对齐后内存访问只需一次,是一种那空间换时间的做法

#pragma pack(8)//设置默认对齐数为8
#pragma pack()//取消设置默认对齐数,还原为默认

1.5结构体传参

void print1(struct S s)//要接收整个结构体,参数压栈的系统开销比较大,性能下降
{
    ;
}

void print2(struct S* ps)//只接收地址,效率高
{
    ;
}
  1. 位段

2.1定义

  • 位段类型与结构体相似,但更节省空间,移植性差

  • 位段的成员必须是整型家族的(int, char,unsigned)

  • 成员名后有冒号+数字

struct A
{
    int a:2;
    int b:3;
    int c:4;
};//A就是一个位段类型

成员名后的数字代表该成员需要的比特位

struct S
{
    char a:3;
    char b:4;
    char c:5;
    char d:4;
};
int main()
{
    struct S s={0};
    s.a=10;
    s.b=12;
    s.c=3;
    s.d=4;
    printf("%x ","%x ","%x ","%x ",s.a,s.b,s.c,s.d);
    return 0;
}

结果应是62 03 04

2.2位段的问题

  • int位段是被当作有符号数还是无符号数是不确定的

  • 位段中最大位的数目不能确定

  • 位段成员是从左向右分配,还是从右向左分配是未知的

  • 当第二个位段无法容纳于第一个位段的剩余位时,是舍弃剩余位还是利用这是未知的。

  1. 枚举

3.1定义

就是将可能有的值一一列举。

enum Sex
{
    MALE,//0
    FEMALE,//1
    UNKNOW//2
};

3.2枚举的优点

  • 增加代码的可读性和可维护性 和#define定义的标识比较,枚举有类型检查,更加严谨 防止了命名污染 便于调试 使用方便,一次可以定义多个常量

  1. 联合体

4.1定义:

联合体也是一种自定义类型,可以包含一系列的成员,他的特征是这些成员共同使用一块内存空间。

4.2联合体的特点

由于所有成员对象共用一块内存空间,所以一个联合体的大小至少是联合体内最大成员的大小。但是,联合体并不一定总是最大成员的大小,因为联合体也存在对齐的问题。

举例:

union un1
{
    short c[7];
    int i;
};
union un2
{
    char c[5];
    int i;
};
printf("%d",sizeof(union un1));
printf("%d",sizeof(union un2));

当最大成员大小不是联合体内最大对齐数的整数倍时,就要对齐到最大对齐数的整数倍。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值