C语言 结构体 共用体 枚举

一.结构体

 结构体定义时需要先定义结构体类型,然后再用类型来定义变量。

结构体是用来解决数组所有的元素的类型必须一致缺陷的,可以将结构体理解为一个其中元素类型可以不相同的数组。

 1 // 定义类型
 2 struct people
 3 {
 4     char name[20];
 5     int age;
 6 };
 7  
 8 // 定义类型的同时定义变量。
 9 struct student
10 {
11     char name[20];
12     int age;
13 }s1;
14  
15 // 将类型struct student重命名为s1,s1是一个类型名,不是变量
16 typedef struct student
17 {
18     char name[20];
19     int age;
20 }s1;
21  

结构体变量中的元素访问方式:

只有一种,用 . 或者->的方式来访问。

 1 struct score
 2 {
 3     int a;
 4     int b;
 5     int c;
 6 };
 7  
 8 struct myStruct
 9 {
10     int a;            // 4 
11     double b;        // 8
12     char c;
13 };
14  
15 int  main()
16 {
17     struct myStruct s1;
18     s1.a = 12;              // int *p = (int *)&s1; *p = 12;
19     s1.b = 4.4;             // double *p = (double *)(&s1 + 4); *p = 4.4;
20     s1.c = 'a';            // char *p = (char *)((int)&s1 + 12); *p = 'a';
21     
22     int a[3];        // 3个学生的成绩,数组方式
23     score s;        // 3个学生的成绩,结构体的方式
24     
25     s.a = 12;        // 编译器在内部还是转成指针式访问 int *p = s; *(p+0) = 12;
26     s.b = 44;        // int *p = s; *(p+1) = 44;
27     s.c = 64;        // int *p = s; *(p+2) = 44;
28 }

结构体对齐:

对齐访问牺牲了内存空间,换取了速度性能。

 1 struct mystruct1
 2 {                    // 1字节对齐        4字节对齐
 3     int a;            // 4            4
 4     char b;            // 1            2(1+1)
 5     short c;        // 2            2
 6 };
 7 
 8 typedef struct mystruct2
 9 {                    // 1字节对齐      4字节对齐
10     char a;            // 1            4(1+3)
11     int b;            // 4            4
12     short c;        // 2            4(2+2)
13 }MyS2;
14 
15 typedef struct myStruct5
16 {                            // 1字节对齐       4字节对齐
17     int a;                    // 4            4
18     struct mystruct1 s1;    // 7            8
19     double b;                // 8            8
20     int c;                    // 4            4    
21 }MyS5
22  
23 int main()
24 {
25     printf("sizeof(struct mystruct1) = %d.\n", sizeof(struct mystruct1));       //   8
26 
27     printf("sizeof(struct mystruct2) = %d.\n", sizeof(struct mystruct2));   //12
28     printf("sizeof(struct mystruct5) = %d.\n", sizeof(MyS5));  //24
29 
30     return 0;
31 }

二.共用体

共用体union和结构体struct在类型定义、变量定义、使用方法上很相似。

共用体中的各个成员其实是一体的,彼此不独立,他们使用同一个内存单元。

 

union中的元素不存在内存对齐的问题,因为union中实际只有1个内存空间,都是从同一个地址开始的,所以不涉及内存对齐。

用union来测试机器的大小端模式:

 1 #include <stdio.h>
 2  
 3 // 共用体中很重要的一点:a和b存放都是从u1的低地址开始的。
 4 // 假设u1所在的4字节地址分别是:0、1、2、3的话,那么a存放顺序自然就是0、1、2、3;
 5 // b所在的地址是0而不是3.
 6 union myunion
 7 {
 8     int a;
 9     char b;
10 };
11  
12 // 如果是小端模式则返回1,小端模式则返回0
13 int is_little_endian(void)
14 {
15     union myunion u1;         //1对应十六进制就是0x0000_0001
16     u1.a = 1;                // 地址0的那个字节内是1(小端)或者0(大端)
17     return u1.b;
18 }
19  
20 int main(void)
21 {
22     int i = is_little_endian();
23     if (i == 1)
24     {
25         printf("小端模式\n");      //在X86下的Linux中验证是小端模式
26     }
27     else
28     {
29         printf("大端模式\n");
30     }
31     
32     return 0;                      
33 }

三.枚举

枚举本质就是int类型的常量,每个符号和一个常量绑定。

宏定义和枚举的区别:

枚举是将多个有关联的符号封装在一个枚举中(譬如一星期有7天,譬如一个月有31天,适合用枚举),而宏定义是完全散的。也就是说枚举其实是多选一。

1 #define MON  1
2 #define TUE  2
3 #define WED  3
4 #define THU  4
5 #define FRI  5
6 #define SAT  6
7 #define SUN  7

例如以上这些代码,看起来很多很复杂,如果用枚举的方式:

1 enum DAY{MON=1,TUE,WED, THU, FRI, SAT, SUN};

枚举变量的定义:

1 enum DAY{MON=1,TUE,WED,THU,FRI};
2 enum DAY day;
3 enum DAY{MON=1,TUE,WED,THU,FRI}day;//也可以在定义枚举类型时一起定义
4 enum{MON=1, TUE, WED, THU, FRI, SAT, SUN}day;//可以省略枚举名称

示例:

 1 #include <stdio.h>
 2 enum DAY
 3 {
 4       MON=1, TUE, WED, THU, FRI, SAT, SUN
 5 };
 6 int main()
 7 {
 8     enum DAY day;
 9     day = WED;
10     printf("%d",day);
11     return 0;
12 }
 1 #include <stdio.h>
 2 enum DAY{
 3       MON=1, TUE, WED, THU, FRI, SAT, SUN
 4 } day;
 5 int main(){
 6     // 遍历枚举元素
 7     for (day = MON; day <= SUN; day++) {
 8         printf("枚举元素:%d \n", day);
 9     }
10 }
1 #include<stdio.h>
2 enum DAY{MON=1, TUE, WED, THU=6, FRI, SAT, SUN}day;
3 int main(){
4     for(day=MON;day<=SUN;day++){
5         printf("%d\t",day);
6     }
7     return 0;
8 }
9 //以上的输出结果会变成 1     2     3     4     5     6     7     8     9

 

posted @ 2022-06-11 19:47  学习&笔记  阅读(65)  评论(0)    收藏  举报