目录
1.结构体(struct)
- 结构体类型的声明
- 结构体变量的定义和初始化
- 结构体自引用
- 结构体传参
- 结构体内存对齐
结构体的声明:结构体是不同类型数据的一个集合。例如描述一本书
struct Book
{
char name[20];//用字符数组存放书名
char author[10];//用字符数组存放作者名
int price;//用int存放价格
};//结构体后面的分号不可省略
这就是一个简单的结构体。 结构体的的所有声明是这样的
struct tag
{
member-list;//成员变量
}variable-list;//快速创建结构体变量
特殊的声明:匿名结构体
struct
{
int a;
char b;
float c;
}x;
结构体的定义和初始化:
有了结构体类型,那如何定义变量,其实很简单
struct Point
{
int x;
int y;
}p1;//声明类型的同时定义变量p1
struct Point p2;//定义结构体变量p2
初始化也简单
struct Stu //类型声明
{
char name[15];//名字
int age;//年龄
};
struct Stu s = {"zhangsan",20};//初始化
结构体自引用
struct Node
{
int data;
struct Node* next;
};
结构体传参
结构传参和函数中的传值调用和传址调用类似,传结构体本身(print1)相当于在函数内部重新开辟了一块内存空间struct S s,是原来结构体变量s的一份临时拷贝,出函数后就会自动销毁,无法找到真正的结构体变量s。而传地址(print2)就可以直接找到结构体s本身,而且更加节省空间。
#include<stdio.h>
struct S
{
int data[1000];
int num;
};
struct S s = { {1,2,3,4}, 1000 };
//结构体传参
void print1(struct S s)
{
printf("%d\n", s.num);
}
//结构体地址传参
void print2(struct S* ps)
{
printf("%d\n", ps->num);
}
int main()
{
print1(s); //传结构体
print2(&s); //传地址
return 0;
}
结构体内存对齐(往期博客有详细介绍)
2.枚举(enum)
- 枚举类型的定义
- 枚举的优点
- 枚举的使用
枚举的定义
枚举的定义和结构体的定义类似,只不过枚举内部是一系列的枚举常量
enum Day//星期
{
//枚举常量
Mon,
Tues,
Wed,
Thur,
Fri,
Sat,
Sun
};
枚举常量是有值的,默认从0开始,一次递增1,当然在定义的时候也可以赋初值。由此看来,上述代码等同于这样
#define Mon 0
#define Tues 1
#define Wed 2
#define Thur 3
#define Fri 4
#define Sat 5
#define Sun 6
但是为什么还要有枚举类型呢?
枚举的优点
1. 增加代码的可读性和可维护性
2. 和#define定义的标识符比较枚举有类型检查,更加严谨
3. 防止了命名污染(封装)
4. 便于调试
5. 使用方便,一次可以定义多个常量
枚举的使用
enum sex
{
male,
female,
secret,
};
enum sex s=male;
3.联合体(union)
- 联合类型的定义
- 联合的特点
- 联合大小的计算
联合类型的定义
联合也是一种特殊的自定义类型 这种类型定义的变量也包含一系列的成员,特征是这些成员公用同一块空间(所以联合也叫共用体)
union Un
{
int i;
char c;
};
union Un un;
联合的特点
联合的成员是共用同一块内存空间的,这样一个联合变量的大小,至少是最大成员的大小(因为联 合至少得有能力保存最大的那个成员)
所以
//sizeof(un) 4
联合大小的计算
联合的大小至少是最大成员的大小。 当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。
union Un1
{
char c[5];
int i;
};
union Un2
{
short c[7];
int i;
};
//下面输出的结果是什么?
printf("%d\n", sizeof(union Un1));//8
printf("%d\n", sizeof(union Un2));//16