详解C语言结构体、枚举、联合体

(174) 2024-04-06 12:01:01

结构体、枚举、联合体

    • 1.什么是结构体、枚举、联合体
    • 2.定义结构体
      • 2.1 包含结构体成员变量、variable
      • 2.2 tag、结构体成员变量
      • 2.3 用结构体声名变量
      • 2.4 用typedef 创建新类型
      • 2.5 两个结构体相互包含
      • 2.6 结构体变量初始化
      • 2.7 结构体指针
    • 3.枚举
      • 3.1 定义方式
      • 3.2 为什么用枚举
      • 3.3 枚举变量的定义
      • 3.4 实例
      • 3.5 枚举实际用途
    • 4.联合体
      • 4.1 与结构体区别
      • 4.2 定义

详解C语言结构体、枚举、联合体 (https://mushiming.com/)  第1张

1.什么是结构体、枚举、联合体

结构体(struct)是由一系列具有相同类型或不同类型的数据项构成的数据集合,这些数据项称为结构体的成员。如下面的student结构体包含三个成员,分别是name、num、age。

枚举(enum)是C语言的一种特殊类型。当我们在编程中遇到定义一些固定长度或范围的数值时,可以考虑使用枚举类型。使用枚举可以让我们的程序可读性更强、看起来更加直观。举个例子,如果我们在编程中需要使用数字06分别表示星期日星期六,程序的可读性就不高,我们需要翻手册或者看程序注释才能知道每个数字具体代表什么意思。如果我们使用枚举呢,基本上不需要看注释或手册就可知晓其大意。

联合体是一种结构。
它的所有成员相对于基地址的偏移量都是0。
此结构空间要大到足够容纳最宽的成员。
其对其方式适合其中所有成员。

// 创建结构体
struct student
{ 
   
  char *name;  // 学生名字
  int num;     // 学生学号
  int age;     // 学生年龄
};

2.定义结构体

struct tag{ 
   
	成员变量...
}variable;

通常,tag、结构体成员变量、variable这3个部分至少要出现2个

2.1 包含结构体成员变量、variable

struct
{ 
   
	char name[100];
	int age;
}s1;//s1相当于对这个结构体声明了一个变量,可以在程序中直接调用

s1相当于声明的全局变量。

2.2 tag、结构体成员变量

struct person
{ 
   
	char name[100];
	int age;
};

2.3 用结构体声名变量

struct person p1,p2[5],*p3

2.4 用typedef 创建新类型

typedef struct 
{ 
   
	char name[100];
	int age;
} person;
//用新定义的person类型定义变量
person p1,p2[5],*p3

2.5 两个结构体相互包含

struct B;				//需先对结构体B进行声明,不然声明A时编译无法通过
struct A
{ 
   
	struct B *partner;
	//other members;
};
struct B
{ 
   
	struct A *partner;
	//other members;
};

2.6 结构体变量初始化

#include <stdio.h> 
struct persons { 
   
    char name[100];
    int age;
}person = { 
   "chuhe",18};
int main()
{ 
   
    printf("%s,%d", person.name, person.age);
    return 0;
}

2.7 结构体指针

#include <stdio.h> 

typedef struct persons { 
   
    char name[100];    
    int age;
}persons;
int main()
{ 
   
    struct persons p = { 
    "chuhe",18 };
    printf("%s,%d\n", p.name, p.age);
    persons* p1 = &p;//定义结构体指针
    printf("%s,%d\n", p1->name, p1->age);

    return 0;
}

3.枚举

3.1 定义方式

enum 枚举名{ 
   元素1,元素2};

3.2 为什么用枚举

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

例如上式,定义非常麻烦,此时便可以用枚举

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

注意:第一个枚举成员的默认值为整型的 0,后续枚举成员的值在前一个成员上加 1。我们在这个实例中把第一个枚举成员的值定义为 1,第二个就为 2,以此类推

3.3 枚举变量的定义

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

enum DAY{ 
   MON=1,TUE,WED,THU,FRI}day;//也可以在定义枚举类型时一起定义

enum{ 
   MON=1, TUE, WED, THU, FRI, SAT, SUN}day;//可以省略枚举名称

3.4 实例

#include <stdio.h>
enum DAY
{ 
   
      MON=1, TUE, WED, THU, FRI, SAT, SUN
};
int main()
{ 
   
    enum DAY day;
    day = WED;
    printf("%d",day);
    return 0;
}

3.5 枚举实际用途

#include <stdio.h>
#include <stdlib.h>
int main(){ 
   
    enum color { 
    red=1, green, blue };
    enum  color favorite_color;
    printf("请输入你喜欢的颜色: (1. red, 2. green, 3. blue): ");
    scanf("%u", &favorite_color);
    switch (favorite_color){ 
   
    case red:
        printf("你喜欢的颜色是红色");
        break;
    case green:
        printf("你喜欢的颜色是绿色");
        break;
    case blue:
        printf("你喜欢的颜色是蓝色");
        break;
    default:
        printf("你没有选择你喜欢的颜色");
    }
    return 0;
}

4.联合体

通过前面的讲解,我们知道结构体(Struct)是一种构造类型或复杂类型,它可以包含多个类型不同的成员。在C语言中,还有另外一种和结构体非常类似的语法,叫做共用体(Union),它的定义格式为:

union 共用体名{ 
   
    成员列表
};

4.1 与结构体区别

结构体和共用体的区别在于:结构体的各个成员会占用不同的内存,互相之间没有影响;而共用体的所有成员占用同一段内存,修改一个成员会影响其余所有成员。

4.2 定义

union data{ 
   
    int n;
    char ch;
    double f;
};
union data a, b, c;

共用体 data 中,成员 f 占用的内存最多,为 8 个字节,所以 data 类型的变量(也就是 a、b、c)也占用 8 个字节的内存,请看下面的演示:

#include <stdio.h>

union data{ 
   
    int n;
    char ch;
    short m;
};

int main(){ 
   
    union data a;
    printf("%d, %d\n", sizeof(a), sizeof(union data) );
    a.n = 0x40;
    printf("%X, %c, %hX\n", a.n, a.ch, a.m);
    a.ch = '9';
    printf("%X, %c, %hX\n", a.n, a.ch, a.m);
    a.m = 0x2059;
    printf("%X, %c, %hX\n", a.n, a.ch, a.m);
    a.n = 0x3E25AD54;
    printf("%X, %c, %hX\n", a.n, a.ch, a.m);
   
    return 0;
}

运行结果:
4, 4
40, @, 40
39, 9, 39
2059, Y, 2059
3E25AD54, T, AD54

THE END

发表回复