C语言语法入门-结构体
9unk Lv5

结构体

数据关联性

代码清单12-1

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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
/*程序名:list1201.c*/
/*
对5名学生的 “姓名和身高” 按身高进行升序排列。
*/

#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>

#define NUMBER 5
#define NAME_LEN 64

/*---交换x和y指向的整数值---*/
void swap_int(int* x, int* y)
{
int temp = *x;
*x = *y;
*y = temp;
}

/*---交换sx和sy指向的字符串---*/
void swap_str(char* sx, char* sy)
{
char temp[NAME_LEN];
strcpy(temp, sx);
strcpy(sx, sy);
strcpy(sy, temp);
}

/*---基于num对数组num和str的前n个元素进行升序排列*/
void sort(int num[], char str[][NAME_LEN], int n)
{
int i, j;

for (i = 0; i < n - 1; i++)
{
for (j = n - 1; j > i; j--)
{
if (num[j - 1] > num[j])
{
swap_int(&num[j - 1], &num[j]);
swap_str(str[j - 1], str[j]);
}
}
}
}

int main(void)
{
int i;
int height[] = { 178,175,173,165,179 };
char name[][NAME_LEN] = { "Sato","Sanaka","Takao","Mike","Masaki" };

for (i = 0; i < NUMBER; i++)
{
printf("%2d : %-8s%4d\n", i + 1, name[i], height[i]);
}

sort(height, name, NUMBER);

puts("\n按身高进行升序排列。");
for (i = 0; i < NUMBER; i++)
printf("%2d : %-8s%4d\n", i + 1, name[i], height[i]);

return 0;
}

结构体

结构体是一种新的数据类型,该数据类型由程序员自定义。结构体中可自定义不同类型的变量,这些变量称为结构体成员。
1

使用结构体数据类型定义变量:

struct student sanaka

“student” 是结构名。“struct student” 是类型名。

结构体成员和运算符

代码清单12-2

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
33
34
35
/*程序名:list1202.c*/
/*
用表示学生的结构体来显示 Sanaka 的信息。
*/

#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <string.h>

#define NAME_LEN 64

/*---表示学生的结构体---*/
struct student
{
char name[NAME_LEN];
int height;
float weight;
long schols;
};


int main(void)
{
struct student sanaka;
strcpy(sanaka.name, "Sanaka");
sanaka.height = 175;
sanaka.weight = 62.5;
sanaka.schols = 73000;

printf("姓名 = %s\n", sanaka.name);
printf("身高 = %d\n", sanaka.height);
printf("体重 = %.lf\n", sanaka.weight);
printf("奖学金 = %ld\n", sanaka.schols);
return 0;
}

成员的初始化

代码清单12-3

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
/*程序名:list1203.c*/
/*
用表示学生的结构体来显示 Takao 的信息。
*/

#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <string.h>

#define NAME_LEN 64

/*---表示学生的结构体---*/
struct student
{
char name[NAME_LEN];
int height;
float weight;
long schols;
};


int main(void)
{
struct student takao = { "Takao",173,86.2 };

printf("姓名 = %s\n", takao.name);
printf("身高 = %d\n", takao.height);
printf("体重 = %.lf\n", takao.weight);
printf("奖学金 = %ld\n", takao.schols);
return 0;
}

结构体成员->运算符

代码清单12-4

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
33
34
35
36
37
38
39
/*程序名:list1204.c*/
/*
修改结构体成员的值。
*/

#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <string.h>

#define NAME_LEN 64

/*---表示学生的结构体---*/
struct student
{
char name[NAME_LEN];
int height;
float weight;
long schols;
};

/*---将std指向的学生的身高变为180cm,体重变为80kg---*/
void hiroko(struct student* std)
{
if ((*std).height < 180) (*std).height = 180;
if ((*std).weight > 80) (*std).weight = 80;
}

int main(void)
{
struct student sanaka = { "Sanaka",175,62.5,73000 };

hiroko(&sanaka);

printf("姓名 = %s\n", sanaka.name);
printf("身高 = %d\n", sanaka.height);
printf("体重 = %.lf\n", sanaka.weight);
printf("奖学金 = %ld\n", sanaka.schols);
return 0;
}

代码清单12-4a

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
33
34
35
36
37
38
39
/*程序名:list1204a.c*/
/*
修改结构体成员的值。
*/

#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <string.h>

#define NAME_LEN 64

/*---表示学生的结构体---*/
struct student
{
char name[NAME_LEN];
int height;
float weight;
long schols;
};

/*---将std指向的学生的身高变为180cm,体重变为80kg---*/
void hiroko(struct student* std)
{
if (std->height < 180) (*std).height = 180;
if (std->weight > 80) (*std).weight = 80;
}

int main(void)
{
struct student sanaka = { "Sanaka",175,62.5,73000 };

hiroko(&sanaka);

printf("姓名 = %s\n", sanaka.name);
printf("身高 = %d\n", sanaka.height);
printf("体重 = %.lf\n", sanaka.weight);
printf("奖学金 = %ld\n", sanaka.schols);
return 0;
}

在表示指针 p 指向的结构体成员m时,推荐使用 “->” 运算符将 (*p).m 简写为 p->m。另外,”.” 运算符和 “->” 运算符统称为访问运算符。

结构体和typedef

代码清单12-5

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
33
34
35
36
37
38
39
/*程序名:list1205.c*/
/*
引入typedef名
*/

#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <string.h>

#define NAME_LEN 64

/*---表示学生的结构体系---*/
typedef struct student
{
char name[NAME_LEN];
int height;
float weight;
long schols;
} Student;

/*---将std指向的学生的身高变为180cm,体重变为80kg---*/
void hiroko(Student* std)
{
if (std->height < 180) (*std).height = 180;
if (std->weight > 80) (*std).weight = 80;
}

int main(void)
{
Student sanaka = { "Sanaka",175,62.5,3000 };

hiroko(&sanaka);

printf("姓名 = %s\n", sanaka.name);
printf("身高 = %d\n", sanaka.height);
printf("体重 = %.lf\n", sanaka.weight);
printf("奖学金 = %ld\n", sanaka.schols);
return 0;
}

在类型名 “struct student” 中,同义词 “Student” 被作为 typedef 名定义。因此,单独的 “Student” 也可以作为类型名发挥作用。

返回结构体的函数

代码清单12-6

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
33
34
35
36
37
38
/*程序名:list1206.c*/
/*
返回结构体的函数
*/

#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>

/*---xyz结构体---*/
struct xyz
{
int x;
long y;
double z;
};

/*---返回具有{x,y,z}的值的就结构体xyz---*/
struct xyz xyz_of(int x, long y, double z)
{
struct xyz temp;

temp.x = x;
temp.y = y;
temp.z = z;
return temp;
};

int main(void)
{
struct xyz s = { 0,0,0 };

s = xyz_of(12, 7654321, 35.689);

printf("xyz.x = %d\n", s.x);
printf("xyz.y = %ld\n", s.y);
printf("xyz.z = %f\n", s.z);
return 0;
}

结构体数组

代码清单12-7

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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
/*程序名:list1207.c*/
/*
将5名学生的身高按升序排列
*/

#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#define NUMBER 5
#define NAME_LEN 64

/*---表示学生的结构体---*/
typedef struct {
char name[NAME_LEN];
int height;
float weight;
long schols;
} Student;

/*---将x和y指向的学生进行交换---*/
void swap_Student(Student* x, Student* y)
{
Student temp = *x;
*x = *y;
*y = temp;
}

/*---将学生数组a的前n个元素按身高进行升序排列---*/
void sort_by_height(Student a[], int n)
{
int i, j;
for (i = 0; i < n - 1; i++)
{
for (j = n - 1; j > i; j--)
{
if (a[j - 1].height > a[j].height)
{
swap_Student(&a[j - 1], &a[j]);
}
}
}
}

int main(void)
{
int i;
Student std[] =
{
{"Sato",178,61.2,80000},
{"Sanaka",175,62.5,73000},
{"Takao",173,86.2,0},
{"Mike",165,72.3,70000},
{"Masaki",179,77.5,70000},
};

for (i = 0; i < NUMBER; i++)
{
printf("%-8s %6d%6.1f%7ld\n",std[i].name, std[i].height, std[i].weight, std[i].schols);
}

sort_by_height(std, NUMBER);
puts("\n按身高排序");

for (i = 0; i < NUMBER; i++)
{
printf("%-8s %6d%6.1f%7ld\n", std[i].name, std[i].height, std[i].weight, std[i].schols);
}
return 0;
}

派生类型

2

作为成员的结构体(结构体中的结构体)

结构体成员不仅可以是int类型和double类型等基本类型,还可以是数组或结构体。

表示坐标的结构体

代码清单12-8

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
33
34
/*程序名:list1208.c*/
/*
计算两点之间的距离
*/

#define _CRT_SECURE_NO_DEPRECATE
#include <math.h>
#include <stdio.h>
#define sqr(n) ((n) * (n))

/*---表示点的坐标的结构体---*/
typedef struct {
double x;
double y;
} Point;

/*---返回点pa和点pb之间的距离---*/
double distance_of(Point pa, Point pb)
{
return sqrt(sqr(pa.x - pb.x) + sqr(pa.y - pb.y));
}

int main(void)
{
Point crnt, dest;

printf("当前地点的X坐标:"); scanf("%lf", &crnt.x);
printf(" Y坐标:"); scanf("%lf", &crnt.y);
printf("目的地的X坐标:"); scanf("%lf", &dest.x);
printf(" Y坐标:"); scanf("%lf", &dest.y);

printf("到目的地的距离为%.2f。\n", distance_of(crnt, dest));
return 0;
}

具有结构体成员的结构体

代码清单12-9

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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
/*程序名:list1209.c*/
/*
汽车行驶
*/

#define _CRT_SECURE_NO_DEPRECATE
#include <math.h>
#include <stdio.h>
#define sqr(n) ((n) * (n))

/*---表示点的坐标的结构体---*/
typedef struct {
double x;
double y;
} Point;

/*---表示汽车的结构体---*/
typedef struct
{
Point pt;
double fuel;
} Car;

/*---返回点pa和点pb之间的距离---*/
double distance_of(Point pa, Point pb)
{
return sqrt(sqr(pa.x - pb.x) + sqr(pa.y - pb.y));
}

/*---显示汽车的当前位置和剩余燃料---*/
void put_info(Car c)
{
printf("当前位置:(%.2f,%.2f)\n", c.pt.x, c.pt.y);
printf("剩余燃料:%.2f 升\n", c.fuel);
}

/*---使c指向的汽车向目标坐标dest行驶---*/
int move(Car* c, Point dest)
{
double d = distance_of(c->pt, dest);

if (d > c->fuel)
return 0;

c->pt = dest;
c->fuel -= d;
return 1;
}

int main(void)
{
Car mycar = { {0.0,0.0},90.0 };

while (1)
{
int select;
Point dest;
put_info(mycar);
printf("开动骑车吗[Yes---1/No---0]:");
scanf("%d", &select);
if (select != 1) break;
printf("目的地的X坐标:"); scanf("%lf", &dest.x);
printf(" Y坐标:"); scanf("%lf", &dest.y);
if (!move(&mycar, dest))
puts("\a燃料不足无法行驶。");
}
return 0;
}

总结

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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
/*程序名:summary.c*/
/*
表示日期的结构体和表示人的结构体
*/

#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#define NAME_LEN 128

/*---表示日期的结构体---*/
struct Date
{
int y;
int m;
int d;
};

/*---表示人的结构体---*/
typedef struct
{
char name[NAME_LEN];
struct Date birthday;
} Human;

/*---显示指针h所指向的人的姓名和生日---*/
void print_Human(const Human* h)
{
printf("%s (%04d 年 %02d 月 %02d 日生)\n", h->name, h->birthday.y, h->birthday.m, h->birthday.d);
}

int main(void)
{
int i;
struct Date today;
Human member[] =
{
{"谷歌正南",{1904,11,18}},
{"柴田汪洋",{1963,11,18}},
{"冈田准一",{1980,11,18}},
};

printf("请输入今天的日期。\n");
printf("年:"); scanf("%d", &today.y);
printf("月:"); scanf("%d", &today.m);
printf("日:"); scanf("%d", &today.d);

printf("---会员一览表---\n");
for (i = 0; i < sizeof(member) / sizeof(member[0]); i++)
{
print_Human(&member[i]);
}
return 0;
}

练习

练习12-1

3

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
/*程序名:lx12-1.c*/

#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <string.h>

#define NAME_LEN 64

/*---表示学生的结构体---*/
struct student
{
char name[NAME_LEN];
int height;
float weight;
long schols;
};

int main(void)
{
struct student takao = { "Takao",173,86.2 };

printf("takao.name的指针:%p\n", takao.name);
printf("takao.height的指针:%p\n", &takao.height);
printf("takao.weight的指针:%p\n", &takao.weight);
printf("takao.schols的指针:%p\n", &takao.schols);
return 0;
}

练习12-2

4

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
33
34
35
36
37
38
39
40
41
/*程序名:lx12-2.c*/

#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <string.h>

#define NAME_LEN 64

/*---表示学生的结构体系---*/
typedef struct student
{
char name[NAME_LEN];
int height;
float weight;
long schols;
} Student;

/*---将std指向的学生的身高变为180cm,体重变为80kg---*/
void hiroko(Student* std)
{
if (std->height < 180) (*std).height = 180;
if (std->weight > 80) (*std).weight = 80;
}

int main(void)
{
Student sanaka;

printf("请输入学生的姓名:"); scanf("%s", sanaka.name);
printf("请输入学生的身高:"); scanf("%d", &sanaka.height);
printf("请输入学生的体重:"); scanf("%f", &sanaka.weight);
printf("请输入学生的奖学金:"); scanf("%ld",&sanaka.schols);

hiroko(&sanaka);

printf("姓名 = %s\n", sanaka.name);
printf("身高 = %d\n", sanaka.height);
printf("体重 = %.lf\n", sanaka.weight);
printf("奖学金 = %ld\n", sanaka.schols);
return 0;
}

练习12-3

5

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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
/*程序名:lx12-3.c*/

#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <string.h>

struct xyz
{
int x;
long y;
double z;
};


struct xyz scan_xyz(int x,long y,double z)
{
struct xyz temp;

temp.x = x;
temp.y = y;
temp.z = z;

return temp;
}



int main(void)
{
struct xyz s;
int x;
long y;
double z;

printf("请输入变量x:"); scanf("%d", &x);
printf("请输入变量y:"); scanf("%ld", &y);
printf("请输入变量z:"); scanf("%lf", &z);

s = scan_xyz(x, y, z);

printf("xyz.x = %d\n", s.x);
printf("xyz.y = %ld\n", s.y);
printf("xyz.z = %f\n", s.z);

return 0;
}

练习12-4

6

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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
/*程序名:lx12-4.c*/


#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#define NUMBER 5
#define NAME_LEN 64

/*---表示学生的结构体---*/
typedef struct {
char name[NAME_LEN];
int height;
float weight;
long schols;
} Student;

/*---将x和y指向的学生进行交换---*/
void swap_Student(Student* x, Student* y)
{
Student temp = *x;
*x = *y;
*y = temp;
}

/*---将学生数组a的前n个元素按身高进行升序排列---*/
void sort_by_height(Student a[], int n)
{
int i, j;
for (i = 0; i < n - 1; i++)
{
for (j = n - 1; j > i; j--)
{
if (a[j - 1].height > a[j].height)
{
swap_Student(&a[j - 1], &a[j]);
}
}
}
}

/*---将学生数组a的前n个元素按姓名的顺序进行排列---*/
void sort_by_name(Student a[], int n)
{
int i, j;
for (i = 0; i < n - 1; i++)
{
for (j = n - 1; j > i; j--)
{
if (a[j - 1].name > a[j].name)
{
swap_Student(&a[j - 1], &a[j]);
}
}
}
}

int main(void)
{
int i;
int flag;
Student std[5];

for (i = 0; i < NUMBER; i++)
{
printf("请输入学生%d姓名、身高、体重、奖学金:", i + 1);
scanf("%s %d %f %ld", std[i].name, &std[i].height, &std[i].weight, &std[i].schols);
}

for (i = 0; i < NUMBER; i++)
{
printf("%-8s %6d%6.1f%7ld\n", std[i].name, std[i].height, std[i].weight, std[i].schols);
}

printf("请输入相应数字使用姓名排序<0>/身高排序<1>");
scanf("%d", &flag);

if (flag == 0)
{
sort_by_name(std, NUMBER);
puts("\n按姓名排序");
}
else
{
sort_by_height(std, NUMBER);
puts("\n按身高排序");
}

for (i = 0; i < NUMBER; i++)
{
printf("%-8s %6d%6.1f%7ld\n", std[i].name, std[i].height, std[i].weight, std[i].schols);
}
return 0;
}

练习12-5

7

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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
/*程序名:lx12-5.c*/

#define _CRT_SECURE_NO_DEPRECATE
#include <math.h>
#include <stdio.h>
#define sqr(n) ((n) * (n))

/*---表示点的坐标的结构体---*/
typedef struct {
double x;
double y;
} Point;

/*---表示汽车的结构体---*/
typedef struct
{
Point pt;
double fuel;
} Car;

/*---返回点pa和点pb之间的距离---*/
double distance_of(Point pa, Point pb)
{
return sqrt(sqr(pa.x - pb.x) + sqr(pa.y - pb.y));
}

/*---显示汽车的当前位置和剩余燃料---*/
void put_info(Car c)
{
printf("当前位置:(%.2f,%.2f)\n", c.pt.x, c.pt.y);
printf("剩余燃料:%.2f 升\n", c.fuel);
}

/*---使c指向的汽车向目标坐标dest行驶---*/
int move(Car* c, Point dest)
{
double d = distance_of(c->pt, dest);

if (d > c->fuel)
return 0;

c->pt = dest;
c->fuel -= d;
return 1;
}

/*---输入目的地坐标点---*/
Point car_coor(void)
{
static flag;
Point temp;

printf("请选择你的需求:设置当前汽车的位置<1>/设置汽车行驶的距离<0>"); scanf("%d", &flag);

if (flag == 1)
{
printf("请输入当前汽车的X坐标:"); scanf("%lf", &temp.x);
printf("请输入当前汽车的Y坐标:"); scanf("%lf", &temp.y);
}
else
{
printf("请输入汽车X坐标要行驶的距离:"); scanf("%lf", &temp.x);
printf("请输入汽车Y坐标要行驶的距离:"); scanf("%lf", &temp.y);
}

return temp;
}

int main(void)
{
Car mycar = { car_coor(),90.0 };
Car dist = { car_coor(),0.0 };

while (1)
{
int select;
Point dest;
put_info(mycar);
printf("开动骑车吗[Yes---1/No---0]:");
scanf("%d", &select);
if (select != 1) break;
mycar.pt.x += dist.pt.x;
mycar.pt.y += dist.pt.y;
dest.x = mycar.pt.x + dist.pt.x;
dest.y = mycar.pt.y + dist.pt.y;

if (!move(&mycar, dest))
puts("\a燃料不足无法行驶。");
}
return 0;
}
  • 本文标题:C语言语法入门-结构体
  • 本文作者:9unk
  • 创建时间:2023-08-06 18:21:00
  • 本文链接:https://9unkk.github.io/2023/08/06/c-yu-yan-yu-fa-ru-men-jie-gou-ti/
  • 版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!