结构体

结构体

结构体的定义

结构体是一种用户 自定义的数据类型,在C语言中使用,它是 一组不同数据类型的数据元素的集合

1
2
3
4
5
6
7
8
struct tag_name {
data_type1 member1; //结构体的成员
data_type2 member2;
// ...
}; //注意分号,不可缺少
//tag_name 是结构体的标识符(结构体名),可以省略。
//data_type1、data_type2 等表示不同的数据类型
//member1、member2 等表示结构体成员变量的名称。

结构体的每个成员可以是任何C数据类型,包括其他结构体类型。

实例

1
2
3
4
5
struct student {
int id;
char name[20];
int age;
};

int、float、char 等,我们称之为基本数据类型;而结构体可以包含多个基本类型的数据,也可以包含其他的结构体,我们将它称为 复杂数据类型或构造数据类型

结构体变量

结构体是种数据类型,因此我们可以用它定义结构体类型变量,如下所示:

1
struct tag_name obj_name;

定义结构体变量的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//1
struct student stu1, stu2;

//2
//定义结构体的同时定义结构体变量:
struct student {
int id;
char name[20];
int age;
} stu1, stu2;

//3
//省略结构体名
//只需要stu1和stu2两个变量,后面不再需要使用这个结构体定义新的变量,可以这么写。
struct {
int id;
char name[20];
int age;
} stu1, stu2;

结构体的成员变量的访问

可以通过 . 运算符进行访问,如下所示:

1
2
3
obj_name.member1;
obj_name.member2;
结构体变量名.成员名;

可以通过这种方式获取结构体成员变量的值,也可以通过这种方式对结构体变量进行赋值

实例

1.逐一赋值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
struct Student {
char name[20];
int age;
float score;
};

struct Student student1;
strcpy(student1.name, "Tom"); // 对结构体的成员变量进行赋值。字符数组在初始化的时候可以赋值字符串,在之后的程序中对其进行赋值操作,需要注意,使用赋值运算符(=)对字符数组进行赋值会出现错误,需要使用字符串函数如strcpy()等进行操作。
student1.age = 18;
student1.score = 90.5;

printf("%s %d %.1f\n", student1.name, student1.age, student1.score); // 输出结构体的成员变量

输出:
Tom 18 90.5
1
2
3
4
5
6
7
8
9
10
11
12
//2
struct Student {
char name[20];
int age;
float score;
};

struct Student student1 = {"Tom", 18, 90.5}; // 定义并初始化一个结构体变量
printf("%s %d %.1f\n", student1.name, student1.age, student1.score); // 输出结构体的成员变量

输出:
Tom 18 90.5

定义时整体赋值

1
2
3
4
5
6
7
8
9
10
struct Student {
char name[20];
int age;
float score;
} student1 = {"Tom", 18, 90.5};

printf("%s %d %.1f\n", student1.name, student1.age, student1.score); // 输出结构体的成员变量

输出:
Tom 18 90.5

结构体数组

实例1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
struct student {
char name[20];
int age;
float score;
};

struct student stu_array[3];
//可以通过下标的方式对数组中的每个学生信息进行访问
strcpy(stu_array[0].name, "Tom");
stu_array[0].age = 20;
stu_array[0].score = 90.5;

strcpy(stu_array[1].name, "Jerry");
stu_array[1].age = 19;
stu_array[1].score = 85.5;

strcpy(stu_array[2].name, "Lucy");
stu_array[2].age = 21;
stu_array[2].score = 92.0;

实例2

1
2
3
4
5
6
7
8
9
struct student {
char name[20];
int age;
float score;
}stu_array[3] = { // 当对数组中全部元素赋值时,数组大小可以省略
{"Tom", 20, 90.5},
{"jerry", 19, 85.5},
{"Lucy", 21, 92.1}
};

结构体指针

结构体指针是指向结构体变量的指针,可以用来访问结构体变量的成员。定义结构体指针的语法格式为:

1
struct 结构体名 *指针变量名;

使用结构体指针时,需要先分配内存空间,并将结构体指针指向该内存空间

1
2
3
4
5
6
7
8
9
10
struct student {
char name[20];
int age;
float score;
};

struct student stu1 = {"Alice", 20, 85.5};
struct student *p;
p = &stu1; //取得结构体变量的地址,必须在前面加&
//定义了一个名为stu1的结构体变量,并初始化其成员值。接着,定义了一个结构体指针p,并将其指向stu1的地址。

获取结构体成员

如下所示:

1
2
3
(*pointer).memberName

pointer->memberName //这是->在C语言中的唯一用途。

实例

1
2
3
printf("name: %s\n", p->name);
printf("age: %d\n", p->age);
printf("score: %f\n", p->score);

结构体指针作为函数参数

结构体指针可以作为函数参数进行传递,以便在函数内部修改结构体变量的值。下面是一个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <stdio.h>

struct Student {
char name[20];
int age;
};

void modify_student(struct Student* ptr) {
// 使用 -> 操作符访问指针所指向的结构体成员
ptr->age = 20;
}

int main() {
struct Student stu = {"Tom", 18};
printf("Before modify: name = %s, age = %d\n", stu.name, stu.age);

// 传递结构体指针作为函数参数
modify_student(&stu);

printf("After modify: name = %s, age = %d\n", stu.name, stu.age);
return 0;
}

在这个例子中,定义了一个名为 struct Student 的结构体类型,并在 main 函数中定义了一个名为 stu 的结构体变量。然后,定义了一个名为 modify_student 的函数,该函数接受一个指向 struct Student 类型结构体的指针作为参数,并将结构体变量的年龄修改为 20。在 main 函数中调用 modify_student 函数,并传递 stu 变量的地址作为参数。最后,输出修改后的 stu 变量的值。

需要注意的是,当我们使用结构体指针访问结构体成员时,需要使用 -> 操作符,而不是 . 操作符。

枚举

在 C 语言中,枚举(Enumeration)是一种用户定义的数据类型,用于将一组有名常量映射到一组整数值。枚举类型定义了一个新的数据类型,它可以包含一组命名的常量值,称为枚举常量。每个枚举常量对应一个整数值,且这些整数值是依次递增的。

枚举类型的定义通常形式如下:

1
2
3
4
5
6
enum 枚举类型名 {
枚举常量1 = 值1,
枚举常量2 = 值2,
...
枚举常量n = 值n
};

其中,枚举常量可以有自己的值,如果没有给出,则会默认从0开始自增。

使用枚举类型可以使代码更加清晰、易读。常见的应用场景是定义状态码、命令类型等常量。

以下是一个简单的枚举类型示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
enum Day {
MON = 1,
TUE,
WED,
THU,
FRI,
SAT,
SUN
}; // 也可以都赋值,也可以像这样只给第一个赋值

int main() {
enum Day day = WED;
printf("Today is %d\n", day);
return 0;
}

在上述代码中,定义了一个名为 Day 的枚举类型,其中各个枚举常量依次对应整数值1~7。在 main 函数中,将变量 day 赋值为 WED,即星期三,输出结果为 Today is 3

共用体

C语言中,共用体(union)是一种特殊的数据类型,它可以存储不同类型的数据,但同一时刻只能存储其中的一种类型。共用体与结构体相似,不同之处在于,共用体的所有成员共用同一块内存空间,而结构体的成员则各自占用一块独立的内存空间。

定义共用体的语法如下:

1
2
3
4
5
6
union union_name {
member_type1 member1;
member_type2 member2;
...
};
//union_name 是共用体类型的名称,member_type1 和 member_type2 是共用体的成员类型,member1 和 member2 是共用体的成员名称。

实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <stdio.h>
#include <string.h>

union Data {
int i;
float f;
char str[20];
};

int main( ) {

union Data data;

printf( "Memory size occupied by data : %ld\n", sizeof(data));

data.i = 10;
printf( "data.i : %d\n", data.i);

data.f = 220.5;
printf( "data.f : %f\n", data.f);

strcpy( data.str, "C Programming");
printf( "data.str : %s\n", data.str);

return 0;
}

输出:
Memory size occupied by data : 20
data.i : 10
data.f : 220.500000
data.str : C Programming

在这个示例中,我们定义了一个共用体 Data,它有三个成员,分别是 ifstr。在 main 函数中,我们首先使用 sizeof 函数来获取 data 的内存大小,然后分别赋值并打印出 data.idata.fdata.str 的值。需要注意的是,由于共用体的所有成员共用同一块内存空间,因此在修改 data 中的某个成员时,其他成员的值也可能被改变。