一 认识结构体
1 结构体是什么
和整形int一样,【结构体】也是C语言中一类重要的数据类型,该数据类型由一组称为成员(或称为域,或称为元素)的不同数据组成,其中每个成员可以是不同的类型。结构体通常用来表示类型不同但是又相关的若干数据。
2 结构体类型的定义
结构体类型的定义形式如下:
struct 结构体名
{
类型标识符 结构体成员名1;
类型标识符 结构体成员名2;
……
类型标识符 结构体成员名n;
};
例如,以下面这个结构体定义学生信息:
struct student
{
int sno; //学号
char sname[10]; //姓名
int sage; //年龄
char dempt[20]; //专业
float ascore; //成绩
};
定义好结构体后,就可以用这个结构体来存储下面表格中的信息:
学号 | 姓名 | 年龄 | 专业 | 成绩 |
1001 | 张平 | 19 | 信息与计算 | 98 |
1002 | 李林 | 18 | 信息与计算 | 95 |
1003 | 江兰 | 19 | 信息与计算 | 92 |
关于结构体类型的声明,做以下几点说明:
①结构体名:结构体名是一个合法的标识符,例如上面的student就是结构体名,有时也称为结构体标记。
②结构体成员:结构体的每一个成员代表了结构体的一个分量,可以将每一个结构体成员称为结构体中的域。结构体成员名的形式和定义普通变量相同,结构体成员可以是一个简单类型,也可以是一个构造类型,如结构体、数组等。
③结构体成员根据需要可以是任意类型,既可以是int、float等简单的类型,也可以是一个结构体类型。
④成员名可以和变量名相同,两者不代表同一个对象,互不干扰,例如:
struct date
{
int year;
int month;
int day;
};
struct date year;
year.year=1980;
定义了一个date型结构体类型,其中有一个year成员,之后又用该结构体类型去定义一个名为year的变量。这种使用方法是允许的。
3 结构体变量的定义
定义好结构体类型后,就可以用该类型去定义结构体变量。定义结构体变量的方法有三种:
3.1 先定义结构体类型再定义结构体变量
struct student stu1,stu2;
定义了两个student结构体型变量,变量名分别为stu1,stu2。像简单变量一样,定义了结构体变量后,系统会为之分配内存空间,结构体变量的各个成员在内存中是连续存放的。
3.2 在声明结构体类型的时候定义结构体变量
struct student
{
int sno;
char sname[10];
int sage;
char depmt[20];
float cscore;
}stu1,stu2;
这种定义结构体变量的方法和第一种的作用是相同的,即先定义结构体类型,然后马上定义两个结构体变量。使用这种方法定义结构体变量后,也可以使用第一种方法继续定义其他的该结构体型的变量。
3.3 省略结构体类型名的变量定义
可以不为结构体赋类型名而直接进行结构体变量的定义,其形式为:
struct
{
int sno;
char sname[10];
int sage;
char depmt[20];
float cscore;
}stu1,stu2;
省略结构体类型名后,只能把程序中所有用到的结构体变量都直接定义在结构体类型的后面,而不能在程序中再使用第一种方法再次定义了。因此有时候使用起来不太方便。
二 使用结构体
1 结构体变量的引用
1.1 对结构体变量的输入操作
不可以用scanf()函数对一个结构体变量整体进行输入操作,对于结构体变量的输入必须通过引用其各成员来进行。例如:
struct student
{
int sno;
char sname[10];
int sage;
char depmt[20];
float cscore;
}stu1,stu2;
scanf("%d %s %d %s %f",&stu1.sno,stu1.sname,&stu1.sage,stu1.dempt,&stu1.cscore)
对于结构体变量成员的引用形式为
结构体变量.成员名
每个成员的操作等价于同等地位的普通变量,如果一个成员类型为字符数组的形式,在输入时可以不用加地址符。
1.2 对结构体变量的输出操作
同输入一样,也不可以用printf()函数对一个结构体变量进行整体输出操作,只能逐个输出结构体变量中的每个成员。例如,输出前面定义的student型变量stu1的各个成员数据:
printf("%d",stu1.sno);
printf("%s",stu1.sname);
printf("%d",stu1.sage);
printf("%s",stu1.dempt);
printf("%f",stu1.cscore);
1.3 对结构体变量的赋值操作
对结构体变量的赋值,可以对其中的每个成员赋值:
stu1.sno=1001;
strcpy(stu1.sname,"zhangsan");
stu1.sage=21;
strcpy(stu1.dempt,"math");
stu1.cscore=89;
需要注意,对于字符数组形式的结构体变量成员,不能直接使用赋值符号“=”赋值,必须使用字符串赋值函数strcpy()实现将一个字符串常量赋给结构体中的字符串型成员。
C语言中结构体变量支持整体赋值。例如,stu1中各个成员都已赋值,那么可以使用如下形式将stu1整体赋值给stu2变量:
stu2=stu1;
2 结构体变量的初始化
结构体变量也可以像其他类型变量一样,在定义时初始化。结构体变量初始化的格式,与一维数组相似,具体格式为:
结构体变量={初值表}
例如:
struct student stu3={1003,"lisi",23,"math",98};
3 结构体数组
结构体数组的每一个元素都是一个结构体类型的变量,每个元素都有自己的成员项。
3.1 定义结构体数组
直接定义法定义结构体数组
struct student
{
……
}s1[3];
定义一个student型结构体数组,数组名为s1,其中含3个元素。
间接法定义结构体数组
struct student
{
……
};
int main(
{
struct student s1[3];
……
}
结构体数组的存放和普通数组一样,也是在内存中顺序存放的。
3.2 结构体数组的初始化
与普通数组一样,结构体数组也可以在定义时进行初始化。初始化的格式为:
结构数[n]={{初值表1},{初值表2},……,{初值表n}}
4 结构体类型指针
4.1 指向结构体变量的指针的定义
可以定义一个指针指向结构体变量或结构体数组,该指针称为结构体类型指针。
struct student s1;
struct student * p=&s1;
定义结构体类型指针p,p指向结构体变量s1的首地址。
4.2 利用结构体指针引用结构体变量成员
假设指针变量ps已指向结构变量stu,则以下三种形式均可引用指针变量的成员,作用是等价的:
stu.成员
ps->成员
(*ps).成员
在第一种格式中,分量运算度“.”左侧的运算对象只能是结构变量;而在第二种格式中,指向运算符“->”左侧的运算对象,只能是指向结构体变量(或结构体数组)的指针变量,否则都会出错。
5 指向结构体数组的指针
当定义一个结构体指针变量指向一个结构体数组时,该指针指向的是结构体数组的首地址,即第一个数组元素的地址:
struct student
{
……
};
int main(
{
struct student ar[10];
struct student *ps=ar;
//等价于struct student *ps=ar[0]
}
如果指针变量ps已经指向某结构数组,则ps+1指向结构数组的下一个元素,而不是当前元素的下一个成员。