结构是一些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量
struct tag {
mermber-list;
}variable-list
//例如描述一个学生
struct Stu{
char name[20]; //名字
int age; //年龄
char Sex[5]; //性别
char id[20]; //学号
}s4,s5,s6; //分号不能丢 全局变量
struct Stu s3; //全局变量
int main(){
//创建结构体变量
struct Stu s1;
struct Stu s2;
}
//匿名结构体类型
struct {
int a;
char b;
float c;
}x;
struct {
int a;
char b;
float c;
}a[20],*p;
//上面两个结构在声明的时候省略了结构体标签(tag)
// p = &x;
//警告:编译器会把上面的两个声明当成完全不同的两个类型。所以是非法的。
//
struct Node{
int data; //数据域
struct Node *next; //指针域
};
int main(){
return 0;
}
struct Point {
int x;
int y;
}p1; //声明类型的同时定义变量p1
struct Point p2; //定义结构体变量p2
//初始化:定义变量的同时赋初始值
struct Point p3 = {x,y};
struct Stu { //类型说明
char name[15]; //名字
int age; //年龄
};
struct Stu s = {"zhangsan",20}; //初始化
struct Node{
int data;
scruct Point p;
struct Node* next;
}n1= {10,{4,5},NULL} //结构体嵌套初始化
struct Node n2 = {20,{5,6},NULL}; //结构体嵌套初始化
gcc没有默认对齐数
struct S1{
char c1;
int a;
char c2;
};
struct S2{
char c1;
char c2;
int a;
};
int main(){
struct S1 s1 = {0};
printf("%d\n",sizeof(s1)); //12 (4+4+1+n)%4=0 4+4+1+n=12
struct S2 s2 = {0};
printf("%d\n",sizeof(s2)); //8
return 0;
}
函数传参的时候,参数是需要压栈,会有时间和空间上的系统开销
如果传递的是一个结构体对象的时候,结构体过大,参数压栈的系统开销比较大,所以会导致性能的下降
结论:结构体传参的时候,要传结构体地址
#define _CRT_SECURE_NO-WANINGS 1
struct S{
int a;
char c;
double d;
};
void Init(struct S *tmp){
tmp -> a =100;
tmp -> c = 'a';
tmp -> d = 3.14;
}
//传值
void Printf1(struct S s){
printf("%d %c %lf\n", s.a, s.c, s.d);
}
//传址
void Printf2(struct S *p){ // const struct S *p 如果加了const就不能改变 安全性高
printf("%d %c %lf\n", p->a, p->c, p->d);
}
int main(){
struct S s = {0}; //初始化
Init(&s);
Printf1(s); //传结构体
Printf2(&s); //建议传地址,节约空间
return 0;
}
节省空间
位段的声明和结构是类似的,有两个不同
struct S{
int _a:2;
int _b:5;
int _c:10;
int _d:30;
};
int main(){
struct S s;
printf("%d\n",sizeof(s)); // 8
}
位段的内存分配
列举
把可能的值一一列举
enum Sex{
MALE,
FEMALE
};
enum Color{
RED, //默认0
GREEN, //1
BLUE //2
};
int main(){
enum Sex s = MALE;
s = FEMALE;
printf("%d %d %d \n",RED,GREEN,BLUE); //0 1 2
return 0;
}
enum Color{
RED =2, //设初始值
GREEN ,
BLUE =8
};
int main(){
printf("%d %d %d \n",RED,GREEN,BLUE); //2 3 8
return 0;
}
c语言的源代码 ---预处理---> 编译---->链接 ----> 可执行程序
enum Color{
RED =1, //设初始值
GREEN = 4,
BLUE =8
};
enum Color c = BLUE; //只能拿枚举常量给枚举变量赋值,才不会出现类型的差异
c = 5 //错误
联合也是一种特殊的自定义类型,这种类型定义的变量也包含一系列的成员,特征是这些成员公用同一块空间(所以联合体也叫共用体)
特点:
联合的成员是共用同一块内存空间的,这样一块联合变量的大小,至少是最大成员的大小(因为联合至少得有能力保存最大的那个成员)
面试题:判断当前计算机的大小端存储
union un{ //不能同时使用c和i
char c; //1
int i; //4
};
//5个字节
int main(){
union un u;
printf("%d\n",sizeof(u));//4
return 0;
}
union un{
char arr[5];
char c; //1
int i; //4
};
int main(){
union un u;
printf("%d\n",sizeof(u));//8
return 0;
}