实验8结构体与共用体 8.1结构体 【实验目的】 1.掌握结构体变量的定义和引用: 2.掌握结构体的嵌套方法: 3. 掌握结构体变量作为函数参数时的使用方法。 【相关知识点】 1.定义结构体类型的一般格式: struct结构体名 { 成员表列 }; 示例:定义一个学生(student)结构体类型,该结构体由学号、姓名、性别、年龄、成 绩和地址等成员构成。 struct student int num; 体学号制 char name[20;/体姓名/ char sex; /体性别制 int age, 体年龄 float score: *成绩*/ char addr[30;/体地址*/ }; 该示例定义的结构体类型为struct student,.其中包含6个成员,每个成员都有自己的数据 类型。 -137
实验8 结构体与共用体 8.1 结构体 【实验目的】 1. 掌握结构体变量的定义和引用; 2. 掌握结构体的嵌套方法; 3. 掌握结构体变量作为函数参数时的使用方法。 【相关知识点】 1. 定义结构体类型的一般格式: struct 结构体名 { 成员表列 }; 示例:定义一个学生(student)结构体类型,该结构体由学号、姓名、性别、年龄、成 绩和地址等成员构成。 struct student { int num; /* 学号 */ char name[20]; /* 姓名 */ char sex; /* 性别 */ int age; /* 年龄 */ float score; /* 成绩 */ char addr[30]; /* 地址 */ } ; 该示例定义的结构体类型为 struct student,其中包含 6 个成员,每个成员都有自己的数据 类型。 - 137 -
2.定义结构体变量的三种方法 a)先定义结构体类型再定义结构体变量名 struct结构体名变量名表列; 示例: struct student student1.student2: 本例定义了studentl和student2为struct student类型的变量,即它们具有struct student类 型的结构。 注意:将一个变量定义为标准类型(基本数据类型)与定义为结构体类型不同之处在于 后者不仅要求指定变量为结构体类型,而且要求指定为某一特定的结构体类型,因为可以定 义出很多种具体的结构体类型。 b)在定义结构体类型的同时定义结构体变量 struct结构体名 成员表列: }变量名表列; 示例: struct student int num; 体学号制 char name[20;/*姓名*/ char sex; /*性别*/ int age; 体年龄* float score; 体成绩*/ char addr[30l;/体地址*/ student1,student2; 它的作用与第一种方法相同,即定义了两个struct student类型的变量studentl,.student2。 c)直接定义结构体类型变量 struct -138-
2. 定义结构体变量的三种方法 a) 先定义结构体类型再定义结构体变量名 struct 结构体名 变量名表列; 示例: struct student student1,student2; 本例定义了 student1 和 student2 为 struct student 类型的变量,即它们具有 struct student 类 型的结构。 注意:将一个变量定义为标准类型(基本数据类型)与定义为结构体类型不同之处在于 后者不仅要求指定变量为结构体类型,而且要求指定为某一特定的结构体类型,因为可以定 义出很多种具体的结构体类型。 b) 在定义结构体类型的同时定义结构体变量 struct 结构体名 { 成员表列; }变量名表列; 示例: struct student { int num; /* 学号 */ char name[20]; /* 姓名 */ char sex; /* 性别 */ int age; /* 年龄 */ float score; /* 成绩 */ char addr[30]; /* 地址*/ } student1,student2; 它的作用与第一种方法相同,即定义了两个 struct student 类型的变量 student1,student2。 c) 直接定义结构体类型变量 struct { - 138 -
成员表列: }变量名表列; 示例: struct int num; 体学号*/ char name[20];/体姓名*/ char sex; 体性别/ int age, *年龄*/ float score; *成绩 char addr[30l;/体地址*/ )studentl,student2; 直接定义结构体变量时,由于省略了结构名,因此定义语句后面无法再定义这个类型的 其它结构体变量,除非把定义过程再写一遍。一般情况下,还是建议采用前面两种结构变量 的定义形式。 注意: (1)在定义了结构体变量后,系统会为之分配内存单元。例如在VC+6.0系统中,结构体 变量student1和student2在内存中各占63个字节(4+20+1+4+4+30=63)。 (2)对结构体中的成员,可以单独使用,它的作用与地位相当于普通变量。 (3)成员也可以是一个结构体变量。 (4)成员名可以与程序中其他的变量名相同,但二者不代表同一对象。 3.结构体变量的引用 引用结构体变量中成员的方式为: 结构体变量名成员名 示例1:使用赋值语句给结构体成员赋值。 student1.num=10010: studentl.num表示studentl变量中的num成员。可以对变量的成员赋值,“.”是成员运 算符,它在所有的运算符中优先级最高,因此可以把student1.num作为一个整体来看待。 示例2:使用输入函数给结构体成员赋值。 -139-
成员表列; }变量名表列; 示例: struct { int num; /* 学号 */ char name[20]; /* 姓名 */ char sex; /* 性别 */ int age; /* 年龄 */ float score; /* 成绩 */ char addr[30]; /* 地址 */ } student1,student2; 直接定义结构体变量时,由于省略了结构名,因此定义语句后面无法再定义这个类型的 其它结构体变量,除非把定义过程再写一遍。一般情况下,还是建议采用前面两种结构变量 的定义形式。 注意: (1) 在定义了结构体变量后,系统会为之分配内存单元。例如在 VC++6.0 系统中,结构体 变量 student1 和 student2 在内存中各占 63 个字节(4+20+1+4+4+30=63)。 (2) 对结构体中的成员,可以单独使用,它的作用与地位相当于普通变量。 (3) 成员也可以是一个结构体变量。 (4) 成员名可以与程序中其他的变量名相同,但二者不代表同一对象。 3. 结构体变量的引用 引用结构体变量中成员的方式为: 结构体变量名.成员名 示例 1:使用赋值语句给结构体成员赋值。 student1.num=10010; student1.num 表示 student1 变量中的 num 成员。可以对变量的成员赋值,“.”是成员运 算符,它在所有的运算符中优先级最高,因此可以把 student1.num 作为一个整体来看待。 示例2:使用输入函数给结构体成员赋值。 - 139 -
scanf("%d",&student1.num); 该示例使用输入函数输入student1.num的值。 示例3:对结构体变量初始化。 struct student long int num; char name[20]; char sex; char addr[20]; )a={10101,"LiLin",'M,"123 Beijing Road"); 【实验任务】 一、程序改错 该部分实验主要训练学生阅读简单程序的能力,并在理解程序的基础上,改正程序中出 现的错误。以下是结构体部份初学者容易犯的错误: 1)结构体类型与结构体变量混淆: 2)定义结构体变量的方法错误: 3)结构体变量的成员赋值的方法错误: 下面通过读程序改错练习,掌握结构体类型和结构体变量的正确使用方法。 1.打开c:lc-programming\8\pg8I01.cpp,该程序要求从键盘输入某个学生的学号、姓名、 性别和年龄,然后将结果输出。但程序中存在若干个问题,请查找程序中的错误并修改,使 程序能正确运行。修改后的程序以pg8101_ok.cpp保存。该源程序内容如下: #include <stdio.h> struct stu 体学生信息制 int no; 体学号*制 char name[10]; /*姓名*/ char sex[3]; 体性别*/ int age, *年龄*/ -140-
scanf("%d",&student1.num); 该示例使用输入函数输入 student1.num 的值。 示例 3:对结构体变量初始化。 struct student { long int num; char name[20]; char sex; char addr[20]; }a={10101,"LiLin",'M',"123 Beijing Road"}; 【实验任务】 一、程序改错 该部分实验主要训练学生阅读简单程序的能力,并在理解程序的基础上,改正程序中出 现的错误。以下是结构体部份初学者容易犯的错误: 1) 结构体类型与结构体变量混淆; 2) 定义结构体变量的方法错误; 3) 结构体变量的成员赋值的方法错误; 下面通过读程序改错练习,掌握结构体类型和结构体变量的正确使用方法。 1.打开 c:\c-programming\8\pg8101.cpp,该程序要求从键盘输入某个学生的学号、姓名、 性别和年龄,然后将结果输出。但程序中存在若干个问题,请查找程序中的错误并修改,使 程序能正确运行。修改后的程序以 pg8101_ok.cpp 保存。该源程序内容如下: #include <stdio.h> struct stu /* 学生信息 */ { int no; /* 学号 */ char name[10]; /* 姓名 */ char sex[3]; /* 性别 */ int age; /* 年龄 */ - 140 -
} void main (void { printf("请输入学号,姓名,性别,年龄")方 scanf("%d%s%c%d",stu.no,stu.name,stu.sex,stu.age); printf("学号:%d,姓名:%s,性别:%c,年龄:%dn",stu.no,stu.name,stu.sex,stu.age, 了提示:如何发现问题? 编译该程序,系统报告很多条语法错误。遇到这种情况时,请不要惊慌失措,可以按以 下步骤来进行检查: (1)结构体类型定义是否有错误?经检查,会发现定义结构体变量时,在结尾处缺少了 一个分号“,”。不少同学在定义结构体时,会忘记在语句后面加上分号。 (2)重新编译,仍然发现有错,系统提示:“'stu:illegal use of this type as an expression”。 这是因为上述程序中,只定义了结构体类型,没有定义结构体变量。而该程序错误地将结构 体类型名当作结构体变量名来使用。 (3)在使用scaf给函数结构体变量成员赋值时,除结构体成员是字符数组时不需要加 地址符号“&”之外,其它类型的成员均要加地址符号“&”。例如:假设结构体变量名是s, 在给结构体成员no赋值时,正确的格式应当是scanf"%d",&s.no),而在给成员name赋值时, 由于name是字符数组,可以不需要使用“&”,例如: scanf("%s",s.name); 改正程序后的运行结果示例如图8.1.1所示。 "C:\c-programming\Debug\pg8101_ok.exe" 回☒ 请输入学号、姓名、性别、年龄 101张三男,28 学号:11,姓名:张三。性别:男.年龄:28 ess any key to continue 图8.1.1Pg8101_ok.cpp的运行结果 2.打开c:lc-programming\8pg8I02.cpp,该程序要求在结构体变量初始化时给各个成员赋 值,然后将结果输出。但程序中存在若干个问题,请修改其中的错误,使程序能正确运行。 修改后的程序以pg8102_ok.cpp保存。该源程序内容如下: #include <stdio.h> -141-
} void main (void ) { printf("请输入学号,姓名,性别,年龄"); scanf("%d%s%c%d",stu.no,stu.name,stu.sex,stu.age); printf("学号:%d, 姓名:%s, 性别:%c, 年龄:%d\n",stu.no,stu.name,stu.sex,stu.age); } 提示:如何发现问题? 编译该程序,系统报告很多条语法错误。遇到这种情况时,请不要惊慌失措,可以按以 下步骤来进行检查: (1)结构体类型定义是否有错误?经检查,会发现定义结构体变量时,在结尾处缺少了 一个分号“;”。不少同学在定义结构体时,会忘记在语句后面加上分号。 (2)重新编译,仍然发现有错,系统提示:“'stu': illegal use of this type as an expression”。 这是因为上述程序中,只定义了结构体类型,没有定义结构体变量。而该程序错误地将结构 体类型名当作结构体变量名来使用。 (3)在使用 scanf 给函数结构体变量成员赋值时,除结构体成员是字符数组时不需要加 地址符号“&”之外,其它类型的成员均要加地址符号“&”。例如:假设结构体变量名是 s, 在给结构体成员 no 赋值时,正确的格式应当是 scanf("%d",&s.no),而在给成员 name 赋值时, 由于 name 是字符数组,可以不需要使用“&”,例如: scanf("%s",s.name); 改正程序后的运行结果示例如图 8.1.1 所示。 图 8.1.1 pg8101_ok.cpp 的运行结果 2.打开 c:\c-programming\8\pg8102.cpp,该程序要求在结构体变量初始化时给各个成员赋 值,然后将结果输出。但程序中存在若干个问题,请修改其中的错误,使程序能正确运行。 修改后的程序以 pg8102_ok.cpp 保存。该源程序内容如下: #include <stdio.h> - 141 -