C语言程序设计-11 结构体与共用体
11.1 定义一个结构的一般形式
11.2 结构类型变量的说明
1. 先定义结构,再说明结构变量。
2. 在定义结构类型的同时说明结构变量。
3. 直接说明结构变量。
11.3 结构变量成员的表示方法
11.4 结构变量的赋值
结构变量的赋值就是给各成员赋值。可用输入语句或赋值语句来完成。
【例 11.1】给结构变量赋值并输出其值。
#include <math.h>
#include <stdio.h>void main()
{struct stu{int num;char *name;char sex;float score;} boy1, boy2;boy1.num = 102;boy1.name = "Zhang ping";printf("input sex and score\n");scanf("%c %f", &boy1.sex, &boy1.score);boy2 = boy1;printf("Number=%d\nName=%s\n", boy2.num, boy2.name);printf("Sex=%c\nScore=%f\n", boy2.sex, boy2.score);}
本程序中用赋值语句给 num 和 name 两个成员赋值,name 是一个字符串指针变量。用 scanf
函数动态地输入 sex 和 score 成员值,然后把 boy1 的所有成员的值整体赋予 boy2。最后分
别输出 boy2 的各个成员值。本例表示了结构变量的赋值、输入和输出的方法。
11.5 结构变量的初始化
和其他类型变量一样,对结构变量可以在定义时进行初始化赋值。
【例 11.2】对结构变量初始化。
#include <math.h>
#include <stdio.h>void main()
{struct stu /*定义结构*/{int num;char *name;char sex;float score;} boy2, boy1 = {102, "Zhang ping", 'M', 78.5};boy2 = boy1;printf("Number=%d\nName=%s\n", boy2.num, boy2.name);printf("Sex=%c\nScore=%f\n", boy2.sex, boy2.score);
}
本例中,boy2,boy1 均被定义为外部结构变量,并对 boy1 作了初始化赋值。在 main 函
数中,把 boy1 的值整体赋予 boy2,然后用两个 printf 语句输出 boy2 各成员的值。
11.6 结构数组的定义
【例 11.3】计算学生的平均成绩和不及格的人数。
#include <math.h>
#include <stdio.h>struct stu
{int num;char *name;char sex;float score;
} boy[5] = {{101, "Li ping", 'M', 45},{102, "Zhang ping", 'M', 62.5},{103, "He fang", 'F', 92.5},{104, "Cheng ling", 'F', 87},{105, "Wang ming", 'M', 58},
};
void main()
{int i, c = 0;float ave, s = 0;for (i = 0; i < 5; i++){s += boy[i].score;if (boy[i].score < 60)c += 1;}printf("s=%f\n", s);ave = s / 5;printf("average=%f\ncount=%d\n", ave, c);
}
本例程序中定义了一个外部结构数组 boy,共 5 个元素,并作了初始化赋值。在 main 函
数中用 for 语句逐个累加各元素的 score 成员值存于 s 之中,如 score 的值小于 60(不及格)
即计数器 C 加 1,循环完毕后计算平均成绩,并输出全班总分,平均分及不及格人数。
【例 11.4】建立同学通讯录
#include "stdio.h"
#define NUM 3struct mem
{char name[20];char phone[10];
};
void main()
{struct mem man[NUM];int i;for (i = 0; i < NUM; i++){printf("input name:\n");gets(man[i].name);printf("input phone:\n");gets(man[i].phone);}printf("name\t\t\tphone\n\n");for (i = 0; i < NUM; i++)printf("%s\t\t\t%s\n", man[i].name, man[i].phone);
}
本程序中定义了一个结构 mem,它有两个成员 name 和 phone 用来表示姓名和电话号码。
在主函数中定义 man 为具有 mem 类型的结构数组。在 for 语句中,用 gets 函数分别输入各
个元素中两个成员的值。然后又在 for 语句中用 printf 语句输出各元素中两个成员值。
11.7 结构指针变量的说明和使用
11.7.1 指向结构变量的指针
下面通过例子来说明结构指针变量的具体说明和使用方法。
【例 11.5】
#include "stdio.h"
#define NUM 3struct stu
{int num;char *name;char sex;float score;
} boy1 = {102, "Zhang ping", 'M', 78.5}, *pstu;
main()
{pstu = &boy1;printf("Number=%d\nName=%s\n", boy1.num, boy1.name);printf("Sex=%c\nScore=%f\n\n", boy1.sex, boy1.score);printf("Number=%d\nName=%s\n", (*pstu).num, (*pstu).name);printf("Sex=%c\nScore=%f\n\n", (*pstu).sex, (*pstu).score);printf("Number=%d\nName=%s\n", pstu->num, pstu->name);printf("Sex=%c\nScore=%f\n\n", pstu->sex, pstu->score);
}
本例程序定义了一个结构 stu,定义了 stu 类型结构变量 boy1 并作了初始化赋值,还定
义了一个指向 stu 类型结构的指针变量 pstu。在 main 函数中,pstu 被赋予 boy1 的地址,因
此 pstu 指向 boy1。然后在 printf 语句内用三种形式输出 boy1 的各个成员值。从运行结果
可以看出:
结构变量.成员名
(*结构指针变量).成员名
结构指针变量->成员名
这三种用于表示结构成员的形式是完全等效的。
11.7.2 指向结构数组的指针
【例 11.6】用指针变量输出结构数组。
#include "stdio.h"
#define NUM 3struct stu
{int num;char *name;char sex;float score;
} boy[5] = {{101, "Zhou ping", 'M', 45},{102, "Zhang ping", 'M', 62.5},{103, "Liou fang", 'F', 92.5},{104, "Cheng ling", 'F', 87},{105, "Wang ming", 'M', 58},
};
main()
{struct stu *ps;printf("No\tName\t\t\tSex\tScore\t\n");for (ps = boy; ps < boy + 5; ps++)printf("%d\t%s\t\t%c\t%f\t\n", ps->num, ps->name, ps->sex, ps->score);
}
11.7.3 结构指针变量作函数参数
【例 11.7】计算一组学生的平均成绩和不及格人数。用结构指针变量作函数参数编程。
#include "stdio.h"struct stu
{int num;char *name;char sex;float score;
} boy[5] = {{101, "Li ping", 'M', 45},{102, "Zhang ping", 'M', 62.5},{103, "He fang", 'F', 92.5},{104, "Cheng ling", 'F', 87},{105, "Wang ming", 'M', 58},
};
main()
{struct stu *ps;void ave(struct stu * ps);ps = boy;ave(ps);
}
void ave(struct stu *ps)
{int c = 0, i;float ave, s = 0;for (i = 0; i < 5; i++, ps++){s += ps->score;if (ps->score < 60)c += 1;}printf("s=%f\n", s);ave = s / 5;printf("average=%f\ncount=%d\n", ave, c);
}
本程序中定义了函数 ave,其形参为结构指针变量 ps。boy 被定义为外部结构数组,因
此在整个源程序中有效。在 main 函数中定义说明了结构指针变量 ps,并把 boy 的首地址赋
予它,使 ps 指向 boy 数组。然后以 ps 作实参调用函数 ave。在函数 ave 中完成计算平均成
绩和统计不及格人数的工作并输出结果。
由于本程序全部采用指针变量作运算和处理,故速度更快,程序效率更高。
11.8 动态存储分配
【例 11.8】分配一块区域,输入一个学生数据。
#include "stdio.h"
#include <stdlib.h>main()
{struct stu{int num;char *name;char sex;float score;} *ps;ps = (struct stu *)malloc(sizeof(struct stu));ps->num = 102;ps->name = "Zhang ping";ps->sex = 'M';ps->score = 62.5;printf("Number=%d\nName=%s\n", ps->num, ps->name);printf("Sex=%c\nScore=%f\n", ps->sex, ps->score);free(ps);
}
本例中,定义了结构 stu,定义了 stu 类型指针变量 ps。然后分配一块 stu 大内存区,
并把首地址赋予 ps,使 ps 指向该区域。再以 ps 为指向结构的指针变量对各成员赋值,并用
printf 输出各成员值。最后用 free 函数释放 ps 指向的内存空间。整个程序包含了申请内存
空间、使用内存空间、释放内存空间三个步骤,实现存储空间的动态分配。
11.9 链表的概念
【例 11.9】建立一个三个结点的链表,存放学生数据。为简单起见, 我们假定学生数据结
构中只有学号和年龄两项。可编写一个建立链表的函数 creat。程序如下:
#include <stdio.h>
#include <stdlib.h>#define NULL1 0
#define TYPE struct stu
#define LEN sizeof(struct stu)
struct stu
{int num;int age;struct stu *next;
};
TYPE *creat(int n)
{struct stu *head, *pf, *pb;int i;for (i = 0; i < n; i++){pb = (TYPE *)malloc(LEN);printf("input Number and Age\n");scanf("%d%d", &pb->num, &pb->age);if (i == 0)pf = head = pb;elsepf->next = pb;pb->next = NULL1;pf = pb;}return (head);
}
在函数外首先用宏定义对三个符号常量作了定义。这里用 TYPE 表示 struct stu,用 LEN
表示 sizeof(struct stu)主要的目的是为了在以下程序内减少书写并使阅读更加方便。结构
stu 定义为外部类型,程序中的各个函数均可使用该定义。
creat 函数用于建立一个有 n 个结点的链表,它是一个指针函数,它返回的指针指向 stu
结构。在 creat 函数内定义了三个 stu 结构的指针变量。head 为头指针,pf 为指向两相邻结
点的前一结点的指针变量。pb 为后一结点的指针变量。
11.10 枚举类型
11.10.1 枚举类型的定义和枚举变量的说明
11.10.2 枚举类型变量的赋值和使用
【例 11.10】
#include <stdio.h>
#include <stdlib.h>main()
{enum weekday{sun,mon,tue,wed,thu,fri,sat} a,b, c;a = sun;b = mon;c = tue;printf("%d,%d,%d", a, b, c);
}
【例 11.11】
#include <stdio.h>
#include <stdlib.h>main()
{enum body{a,b,c,d} month[31],j;int i;j = a;for (i = 1; i <= 30; i++){month[i] = j;j++;if (j > d)j = a;}for (i = 1; i <= 30; i++){switch (month[i]){case a:printf(" %2d %c\t", i, 'a');break;case b:printf(" %2d %c\t", i, 'b');break;case c:printf(" %2d %c\t", i, 'c');break;case d:printf(" %2d %c\t", i, 'd');break;default:break;}}printf("\n");
}
11.11 类型定义符 typedef
typedef 定义的一般形式为:
typedef 原类型名 新类型名