八、构造数据类型
1. 结构体
是什么?
C语言允许用户根据需要自己建立的由不同类型数据组成的组合型的数据类型。(struct)
为什么用?
结构体能够根据用户需要来更方便的存储各种各样的信息。
typedef:给类型取别名
typedef unsigned int uint; //给未取名的结构体取别名 STT typedef struct { int a; int b; }STT;
基本格式,struct关键词表示接下来是一个结构。
struct 结构体名
{
成员列表
};
//比如一个学生的结构 struct Student{ //声明结构体 char name[20]; //姓名 int num; //学号 float score; //成绩 };
struct Student stu1; //定义结构体变量
//2.结构体变量的定义也可以与结构体的声明同时,这样就简化了代码 struct Student{ //声明结构体 char name[20]; //姓名 int num; //学号 float score; //成绩 }stu1; //struct Student stu1; //1.结构体变量的定义可以放在结构体的声明之后 int main() { stu1.num = 1; printf("%d\n",stu1.num); }
//3.还可以使用匿名结构体来定义结构体变量,但要注意的是这样的方式虽然简单,但不能再次定义新的结构体变量了。 struct { //没有结构名 char name[20]; int num; float score; }stu1;
typedef :给结构体重新命名
//实例1 typedef struct { int ID; char name[10]; float score; }SS; SS aa; int main() { aa.ID = 10; printf("%d\n", aa.ID); aa.name = "张三"; //错误,字符串不能这样初始化 printf("%s\n", strcpy(aa.name, "张三")); //字符串注意, strcpy需要用到头文件<string.h> return 0; }
//实例2 typedef struct HERO //HERO可要可不要 { int ID; char name[10]; float score; }hero; int main() { hero arr[2] = { {12,"张三",99.1f}, {11,"李四",98.2f} }; for(int i=0; i<2; i++) { printf("%d\t%s\t%f\n", arr[i].ID, arr[i].name, arr[i].score); } return 0; }
//实例3 typedef struct Student //Student可要可不要,必须要用typedef 给结构体重定义名字,这里重定义名字为S { int ID; char name[10]; float score; }S; S aa; int main() { aa = (S){1,"张三", 60.1f}; //一一对应赋值 注意等号后面加(S),否则报错:expected expression before '{' tokengcc printf("%d\n",aa.ID); }
2. 结构体嵌套
用 stu1.birthday.year 访问出生的年份.
struct Birthday{ //声明结构体 Birthday int year; int month; int day; }; struct Student{ //声明结构体 Student char name[20]; int num; float score; struct Birthday birthday; //生日 }stu1;
3. 推荐博客
[点击跳转]((2条消息) C语言中的结构体(struct)___Sunshine_的博客-CSDN博客_c语言结构体)
4. 内存对齐准则
- 以该结构体中最大的基本数据类型所占的内存进行对齐。
struct One { int a; //4 char b[10]; //10,但是需要是4的倍数,所以是12 float c; //4 }; printf("One的字节数为%d\n",sizeof(One)); //输出20
当数据成员前有更大的数据类型所占没存,先按照顺序进行最大的数据类型进行内存分配对齐。
如果在最后还有比前面更大的基本数据类型所占内存,那么就按照更大的进行对齐。
struct Two { char a; //8 int b; //8 int占4个,剩下4个分配给c char c[10]; // 8,其中6个给剩下的c double d; //最后一个基本数据类型所占内存最大,为8 }; printf("Two的字节数为%d\n",sizeof(Two)); //输出32
5.共用体
union,关键字,和结构体类似。区别在于占用内存。
内存存储:共用体所有的成员共用里面最大的车官员的空间,在同一个时刻只能存一个成员的值。
只算最大的成员所占的内存,但要以共用体中最大的基本数据类型所内存进行对齐。
union Arr { int c; char a[10]; //最大的内存成员,占10个字节,但是最大的基本数据类型是4字节,所以以4对齐,所以总共占12个字节 float b; }arr; printf("arr的字节数为%d\n",sizeof(arr)); //12
6. 枚举类型
关键字:enum
内存大小就是int类型所占内存大小。
不需要数据类型
枚举中元素会有默认的值,是int。第一个元素默认值为0,第二个是1,后面依次加1.
//情况1 enum arr { a,b,c,d } printf("%d\n%d\n%d\n%d\n",a,b,c,d); //0,1,2,3 情况2 enum arr { a,b,c=10,d } printf("%d\n%d\n%d\n%d\n",a,b,c,d); //0,1,10,11