C语言-结构体
结构体定义
struct st_type //st_type为类型标识符
{
... //此处为结构体成员表
}; **//注意,此处分号不能少!!**
举例:
struct st_student
{
char num[7]; /*学号*/
char name[20]; /*姓名*/
char sex; /*性别*/
int age; /*年龄*/
float score; /*成绩*/
char address[30]; /*家庭住址*/
};
说明:
(1)定义结构体类型只是规定了构成这种数据类型的模型,在编译时并不给它分配存储空间。所以绝对不允许对定义的结构体类型进行存取数据的操作,正如不能给int、float、char这些类型赋值一样,也不能给定义的结构体类型赋值。
(2)结构体成员可以是简单变量、数组或另一个结构体变量。
(3)结构体成员名可以同程序中的其他变量同名,系统会自动识别它,不会混淆。
(4)结构体类型定义可以放在函数外部,也可以放在函数内部。若放在函数外部,则从定义点到程序尾之间的全局有效;若放在函数内部,则只在本函数内有效。
结构体变量
1、结构体变量的定义和初始化
1结构体变量的定义
结构体变量也必须遵循先定义后引用的原则。它的定义有以下三种方式:
(1)类型和变量分开定义,先定义类型,再定义变量
struct st_student
{
...
};
struct st_student student1,student2,student3[2];
(2)在定义类型的同时定义变量
struct st_student
{
...
}student1,student2,student3[2];
(3)不定义类型名,直接定义结构体变量
struct //注意,struct后没有类型标识符
{
...
}student1,student2,student3[2];
三种形式各自优点如下:
形式(1)是常用的方法,在该定义之后的任意位置仍可用该结构体类型来定义其他变量,适用于需要大量饮用该结构体类型的情况。它可以把那些可以通用的类型定义集中在一个单独的源文件中,再用文件包含命令“#include”供多个程序使用。
形式(2)是一种简略形式,此时类型定义与变量定义合在一起。此后,该结构体类型还可以再次引用,适用于该结构体类型引用不太多的情况。
形式(3)适用于一次性定义该结构体类型变量的场合,因为没有定义结构体类型名,所以不能再在别处用它来定义其他结构体变量。
**注意:**结构体变量的定义一定要在结构体类型定义之后或同时进行,对尚未定义的结构体类型,不能利用它来定义结构体变量。
2结构体变量的初始化
正如在定义数组是可以同时进行初始化一样,在定义结构体变量的同时,也可对结构体变量进行初始化,对其中的个成员变量赋初值。它的一般格式为:
结构体类型名 结构体变量【={初始值表}】;
结构体类型名 结构体数组名[数组长度]【={初始值表}】;
int main()
{
struct st_student student1={"302103","Zhang San",'m',18, 92,"Xian"};
struct st_student student2={"302103","Li Si",'m',18, 92,"Beijing"};
struct st_student student3[2]={{"302103","Zhang San",'m',18, 92,"Xian"}, //注意,此处用逗号隔开数组两个元素的初始值表
{"302103","Li Si",'m',18, 92,"Beijing"}};
...
}
说明:
可选项“={初始值表}”是定义中的初始化式,其中的“初始值表”由若干个用逗号分隔的初始值组成,初始值的顺序和类型要与相应成员的顺序和类型匹配。
初始化对整个结构体变量进行。初始值得个数不得超过成员数,若小于成员数,则剩余成员将被初始化为默认值。
2、结构体变量的引用
1对结构体变量整体的引用
结构体变量整体的引用限制较大,只能对它进行一部分操作。例如:
(1)可作为函数的形参、实参或函数的返回值等进行函数的数据传递。
(2)可以整体赋值,但注意赋值号左边必须是结构体变量,右边必须是同一种结构体类型的结构体变量或函数返回值。例如:
student1=student2;
student3[0]=student1;
注意:不能把初始化中的“{初始值表}”作为一个结构体类型常量赋给结构体变量。不能对结构体变量整体进行输入输出,只能对它的各个成员分别进行输入输出。
struct st_student student1;
student1={"302103","Li Si",'m',18, 92,"Beijing"}; **//该使用方法错错错!!!!初始值表只能在结构体定义时使用**
2对结构体变量成员的引用
和数组相似,C语言只允许对结构体变量的成员进行算术运算、比较运算和输入输出等操作,不允许对结构体变量整体进行此类操作。对结构天亮的成员进行操作,就要引用结构体变量的成员,它的一般形式如下:
结构体变量名.成员名 //结构体变量的成员用“.”引用
结构体变量指针->成员名 //结构体变量指针的成员用“->”引用
结构体数组名[下标].成员名 //数组元素成员的引用方法
struct st_student student1;
struct st_student *pstudent2;
struct st_student student3[2];
student1.age=18; //结构体变量的成员用“.”引用
pstudent2->age=18; //结构体变量指针的成员用“->”引用
student3[0].age=18; //结构体数组元素成员的引用方法
其中“.”、“->”是结构体成员运算符,它的优先级别最高,结合性是自左至右。用这种形式就可以按该成员类型的变量一样,对结构体成员进行操作。如果结构体成员又属于另一个结构体类型,则需要再用成员运算符,一级一级地找到最低级的成员。
结构体和函数
1、结构体作为函数参数
结构体成员可以作为函数的实参,而形参为与成员同类型的变量。此时传递的是单个成员值,与同类型的变量传递规则相同。
现在C语言中允许使用结构体变量整体作函数的实参和形参,进行“值传递”。形参是结构体类型的局部变量,它的类型必须与对应的实参结构体类型完全相同。在函数调用时,系统给形参分配内存空间,然后,将实参结构体的全部成员按顺序赋值给形参。被调函数对形参的修改结果,不会影响主调函数中的实参结构体变量。
由于结构体数组元素在程序中扮演的角色和结构体变量完全一样,所以结构体数组元素也可以作为函数的实参进行整体值传递,形参是与数组元素同类型的结构体变量。
void print(struct st_student s)
{
...
}
2、结构体作为函数参数
与其他类型一样,结构体类型也可以作为函数的返回值类型。定义返回值为结构体类型函数的一般形式为:
结构体类型名 函数名(形参表)
用结构体类型定义的函数可以将被调用函数的结构体类型值返回主调函数。
struct st_student input()
{
...
}