目录
十一、结构体与共用体
11.1概述
将不同类型的数据组合成一个有机的整体,以便于引用。在一个组合项中包含若干个类型不同(当然也可以相同)的数据项。C语言允许用户自己指定这样一种数据结构,它称为“结构体”。
声明一个结构体类型的一般形式为:
struct 结构体名
{ 成员表列 };
“结构体名”用作结构体类型的标志,它又称为“结构体标记”。花括号内室该结构体中的各个成员,又它们组成一个结构体。对各个成员都应进行类型声明,例如:
类型名 成员名
也可以把“成员表列”称为“域表”。每一个成员也称为结构体中的一个域。成员名命名规则与变量名相同。
小例子:
struct student{ //结构体名为student
int num; //占2个字节
char name[20]; //占20个字节
char sex; //占1个字节
int age; //占2个字节
float score; //占4个字节
char address[30];//占30个字节
}; //注意不要忽略最后这个分号
11.2定义结构体类型变量的方法
为了能在程序中使用结构体类型的数据,应当定义结构体类型的变量,并在其中存放具体的数据。
可以采用以下3种方法定义结构体类型变量。
1、先声明结构体类型再定义变量
如上面已经定义了一个结构体类型struct student,可以用它来定义变量。例如:
struct student student1,student2;
//结构体类型名 这两是结构体变量名
定义了student1和student2为struct student类型的变量,它们具有与struct student类型的数据结构。
在定义了结构体变量后,系统会为之分配内存单元。例如student1和student2在内存中各占59个字节。(各成员所占内存之和)
2、在声明类型的同时定义变量
例如:
struct student{
int num;
char name[20];
char sex;
int age;
float score;
char address[30];
}student1,student2;
作用与前一种方法相同。这种形式定义的一般形式为:
struct 结构体名
{
成员表列
}变量名表列;
3、直接定义结构体类型变量
其一般形式为:
struct
{
成员表列
}变量名表列;
即不出现结构体名。
关于结构体类型,有几点需要说明:
(1)类型与变量是不同的概念,不要混同。只能对变量赋值、存取或运算,而不能对一个类型赋值、存取或运算。在编译时,对类型是不分配空间的,只对变量分配空间。
(2)对结构体中的成员(即“域”),可以单独使用,它的作用与地位相当于普通变量。(关于对成员的引用方法,下面会讲到)
(3)成员也可以是一个结构体变量。例如:
struct date{ //声明一个结构体类型
int month;
int day;
int year;
}
struct student{
int num;
char name[20];
char sex;
int age;
struct date birthday; //birthday是struct date类型
char address[30];
}student1,student2;
(4)成员名可以与程序中变量名相同,二者不代表同一对象。
11.3结构体变量的引用
引用结构体变量应当遵循以下原则:
(1)不能将一个结构体变量作为一个整体进行输入和输出。例如:已定义student1和student2为结构体变量并且它们已有值。不能这样引用:
printf("%d,%s,%c,%d,%f,%s\n",student1);
只能对结构体变量中各个成员分别进行输入和输出。引用结构体变量中成员的方式为:
结构体变量名.成员名
例如:
student1.num = 10010; //对student1变量中的num成员赋值
“ . "是成员(分量)运算符,它在所有的运算符中优先级最高,因此可以把student1.num作为一个整体看待。
(2)如果成员本身又属于一个结构体类型,则要若干个成员运算符,一级一级地找到最低的一级的成员。只能对最低级的成员进行赋值或存取以及运算。例如对上面定义的结构体变量student1,可以这样访问各成员:
student1.num
student1.birthday.month
注意,不能用student1.birthday来访问student1变量中的成员birthday,因为birthday本身就是一个结构体变量。
(3)对结构体变量的成员可以像普通变量一样进行各种运算(根据其类型决定可以进行的运算)。例如,
student2.score = student1.score;
sum = student2.score + student1.score;
student1.age++;
++student1.age;
由于" . " 运算符的优先级最高,因此student1.age++是对student1.age进行自加运算,而不是先对age进行自加运算。
(4)可以引用结构体变量成员的地址,也可以引用结构体变量的地址。例如:
scanf("%d",&student1.num); //输入student1.num的值
printf("%o",&student1); //输出student1的首地址
但不能用以下语句整体读入结构体变量,例如:
scanf("%d%s%c%d%f%s",&student1);
结构体变量的地址主要用作函数参数,传递结构体变量的地址。
11.4结构体变量的初始化
和其他类型变量一样,对结构体变量可以在定义时指定初始值。
对结构体变量初始化。
#include<stdio.h>
int main()
{
struct student{
long int num;
char name[20];
char sex;
char address[20];
}a{10101,"Li Hua",'M',"123 Guangxi Road"}; //对结构体变量a赋值
printf("No.%ld\nname=:%s\nsex:%c\naddress:%s\n",a.num,a.name,a.sex,a.address);
return 0;
}
//输出:
No.10101
name=:Li Hua
sex:M
address:123 Guangxi Road
11.5结构体数组
一个结构体可以存放一组数据。
定义结构体数组
和定义结构体变量的方法相仿,只需要说明其为数据即可。例如:
struct student{
int num;
char name[20];
char sex;
int age;
float score;
char address[30];
};
struct student stu[3]; //定义了一个数组stu,数组有3个元素,均为struct student类型数据。
也可以直接定义一个结构体数组。
struct student{
int num;
char name[20];
char sex;
int age;
float score;
char address[30];
}stu[3];
struct{
int num;
char name[20];
char sex;
int age;
float score;
char address[30];
}stu[3];
数组各元素在内存中连续存放。
结构体数组的初始化
struct student{
int num;
char name[20];
char sex;
int age;
float score;
char address[30];
}stu[3] = {{...},{...},{...}}; //具体内容 这里就不写了
定义数组stu时,元素个数可以不指定,即可以写成以下形式:
stu[] = {{...},{...},{...}};
//或者
struct student stu[] = {{...},{...},{...}}
编译时,系统会根据给出初值的结构体常量的个数来确定数组元素的个数。一个结构体常量包括结构体中全部成员的值。
从以上的例子可以看出,结构体数组初始化的一般形式是在定义数组的后面加上“={初值表列};”
这里举一个简单的例子来说明结构体数组的定义和引用。
对候选人得票的统计程序。设有3个候选人,每次输入一个得票的候选人的名字,要求输出最后输出各人得票结果。
#include<stdio.h>
#include<string.h>
struct person{
char name[20];
int count;
}leader[3] = {{"Li",0},{"Zhang",0},{"Fun",0}};
int main()
{
char leader_name[20];
printf("请输入你要投票的人的name:(有三人,分别是Li、Zhang、Fun)\n");
for(int i=1;i<=10;i++)
{
printf("第%d票投给:",i);
scanf("%s",leader_name);
for(int j=0;j<3;j++)
{
if(strcmp(leader_name,leader[j].name)==0) leader[j].count++;
}
}
printf("\n统计结果如下:\n");
for(int i=0;i<3;i++)
{
printf("%5s:%d\n",leader[i].name,leader[i].count);
}
return 0;
}
运行结果:
声明:本文章为个人学习笔记,资料整理参考谭浩强《C程序设计(第三版)》如有错误,欢迎大家指正!