250 likes | 381 Views
第 十 一 章. 结 构 体. 例: 描述一个学生的姓名、学号、性别、年龄。 每个学生都有这样的属性,它们构成一个描述学生具体情况的一个整体。而每个属性又是一个基本的类型,本例中可分别用字符数组、长整型、字符型、和整型来描述。. 一、结构体类型的定义. 结构体概念的引入. 数据的描述: 基本类型 :整型、实型、字符型。 数组 :属于同一种类型的元素的集合。 有时,需要用不同的数据类型来描述一个事物的各方面属性,故此, C 语言引入了 结构体 的概念。. 结构体类型的定义. struct 结构体类型名 { 类型标识符 成员名 1 ;
E N D
第 十 一 章 结 构 体
例: 描述一个学生的姓名、学号、性别、年龄。 每个学生都有这样的属性,它们构成一个描述学生具体情况的一个整体。而每个属性又是一个基本的类型,本例中可分别用字符数组、长整型、字符型、和整型来描述。 一、结构体类型的定义 结构体概念的引入 数据的描述: 基本类型:整型、实型、字符型。 数组:属于同一种类型的元素的集合。 有时,需要用不同的数据类型来描述一个事物的各方面属性,故此,C语言引入了结构体的概念。
结构体类型的定义 struct 结构体类型名 { 类型标识符 成员名1; 类型标识符 成员名2; …… 类型标识符 成员名n; }; 如: struct student { char name[10]; long id; char gender; int age; } 注意: struct student 应作为一个类型整体, name[10]、id、gender、age都是其成员。 struct及花括号后的“;”不能省。
struct student { int no; /*学号*/ char name[10]; /*姓名*/ char sex; /*性别*/ int age; /*年龄*/ float score[10]; /*成绩*/ }; 定义结构体类型, 描述下列数据 结构体类型的举例 (1) 学生情况: 包含学生的学号、 姓名、 性别、 年龄、10门课程成绩:
(2) 个人数据: 包含姓名、性别、年龄、身高、体重、住址: struct person { char name[20]; /*姓名*/ char sex; /*性别*/ int age; /*年龄*/ float height; /*身高*/ float weight; /*体重*/ char addr[50]; /*住址*/ };
(3) 平面上的点: struct point2 { float x; /*横坐标*/ float y; /*纵坐标*/ }; 如考虑空间中的点, 可作如下定义:struct point3 { float x; /*X坐标*/ float y; /*Y坐标*/ float z; /*Z坐标*/ };
(4) 日期,包括年、月、日: struct date { int year; /*年*/ month; /*月*/ day; /*日*/ }; 如职工信息结构体类型为: struct person { char name[20]; /*姓名*/ char address[40]; /*地址*/ float salary; /*工资*/ float cost; /*扣款*/ struct date hiredate; /*聘任日期*/ }; 注意 结构体类型可以嵌套定义 即一个结构体类型中的某些成员又是其他结构体类型
二、结构体变量 结构体变量的定义 三种方法: 1.先定义结构体类型, 再定义结构体变量 格式: struct 结构体名 结构体变量名表; 例如,对已定义的结构体类型struct student ,可以定义结构体变量: struct student zhang ,stu1; struct person p[50]; /*50个职工人的数据*/
2.在定义结构体类型的同时定义变量 格式: struct 结构体类型名 { 类型标识符 成员名1; 类型标识符 成员名2; …… 类型标识符 成员名n; } 变量名表; 例如:struct student { char name[10]; char sex; int age; float score; } stu1,stu2;
3. 用匿名形式直接定义结构体类型变量(不出现结构体名) 格式: struct { 类型标示符 成员名1; 类型标示符 成员名2; …… 类型标示符 成员名n; } 变量名表; 例如:struct { char name[10]; char sex; int age; float score; } stu1,stu2; 结构体的说明 (1)类型与变量是不同的概念,不要混同。对结构体变量来说,在定义时一般先定义一个结构体类型,然后定义变量为该类型。只能对变量赋值、存取或运算,而不能对一个类型赋值、存取或运算。在编译时,对类型是不分配存储空间的,只对变量分配存储空间。 (2)对结构体中的成员,可以单独使用,它的作用相当于普通变量。 (3)成员也可以是一个结构体变量。 (4)成员名可与程序中的变量同名,两者不代表同一对象。
例。定义结构体变量stu1: struct student stu1; stu1.age=20; scanf("%f",&stu1.score); stu1.age 表示引用结构体变量stu1中的age成员,因该成员的类型为int型,所以可以对它执行任何int型变量可以执行的运算。 结构体变量的使用 结构体变量一般不整体引用,而是引用其成员变量。 成员变量引用格式 结构体变量名.成员名 其中的圆点运算符称为成员运算符,它的运算级别是最高的。
说明 (1) 结构体类型变量的各成员(分量)必须单独引用,成员运算符“•”具有最高优先级。 (2) 不允许对结构体变量进行整体的输入输出 如:scanf(“%s%c%d%f”,&stu1); (3) 如果结构体变量类型相同,可以互相赋值。 stu1=stu2; (4) 严格区分类型与变量的概念。 (5) 如果结构体成员本身又是结构体类型的,则可继续使用成员运算符取结构体成员的结构体成员,逐级向下,引用最低一级的成员。程序只能对最低一级的成员进行运算。例如,对stu1某些成员的访问: stu1.birthday.day=23; stu1.birthday.month=8; stu1.birthday.year=1985;
结构体变量的初始化 结构体变量可以在定义时初始化。 格式 struct 结构体名 { 成员表; } 结构体变量={初始化数据表}; 例 struct student { char name[10]; char sex; int age; float score; }stu1,stu2={“Wangwu”,’m’,20,88.5};
stru1 1000 name[10] 1010 sex 1011 age 1013 score 1017 结构体变量存储分配
例 11.1 求某同学上学期6门课程的总成绩与平均成绩。 思路分析: 可以先构建一个结构体,包含学生的姓名、八门课的成绩、以及总成绩及平均成绩。 struct student { char name[10]; float score[6]; float total, average; }; 然后在程序中输入姓名及各科成绩后即可进行运算,运算结果存放到total和average两个成员变量中。
程序如下: main( ) { int i; struct student { char name[10]; float score[6]; float total, average; } stu; scanf(″%s″,stu.name); for(i=0;i<6;i++) scan(″%f″,&stu.score[i]); stu.total=0; for(i=0;i<6;i++) stu.total+=stu.score[i]; stu.average=stu.total/6; printf(”%s的总成绩=%.2f\n平均成绩=%.2f”, stu.total,stu.average); } 输入数据: CHEN 80 86 79 98 88 72 运行结果: CHEN的总成绩=477.00 平均成绩= 72.13
与结构体变量定义类似,只是结构体变量名为结构体数组变量名,如:struct student stu[3]; 数组各元素在内存中连续存放 三、结构体数组 结构体数组的定义 例。 struct student { int num; char name[20]; char sex; int age; float score; char addr[30]; }stu[3]={{101,”WGJ”,’M’,28,88.5,”CS”}, {102,”DYH”,’F’,26,88.0,”CS”}, {103,”DYC”,’M’,24,78.5,”CZ”}}; 结构体数组的初始化 一般形式是在定义的数组后面加上 ={初值表列};
101 ”WGJ” ’M’ 28 88.5 ”CS” 102 ”DYH” ’F’ 26 88.0 ”CS” 103 ”DYC” ’M’ 24 78.5 ”CS” num name sex age score addr stu[0] 101 WGJ M 28 88.5 CS stu[1] 102 DYH F 26 88.0 CS stu[2] 103 DYC M 24 78.5 CS stu[0] stu[1] stu[2] 结构体数组的存储分配
通过下面的示例说明结构体数组的使用方法[例11.2] 候选人得票的统计。设有三个候选人,每次输入一个得票的候选人的名字,要求最后输出各人得票结果。 结构体数组的使用 程序如下: struct person { char name[20]; int count; }leader[3]={"Zhang",0,"Li",0,"Wang",0};
main() { int i,j; char leader_name[20]; for (i=1;i<=10;i++) { scanf("%s",leader_name); for (j=0;j<3;j++) if (strcmp(leader_name,leader[j].name)==0) leader[j].count++; } printf("\n"); for (i=0;i<3;i++) printf("%5s:%d\n",leader[i].name,leader[i].count); }
一个结构体变量的指针就是该变量所占据的内存段的起始地址。可以定义一个指针变量,用来指向一个结构体变量,此时该指针变量的值是结构体变量的起始地址 。 四、结构体类型指针
例如: struct student *pstu, stu; pstu=&stu; 定义了一个指针变量pstu,并使指针指向结构体变量stu 。 *pstu 表示指针pstu所指示的结构体变量(对象)stu,因而,其成员表示为(*pstu).name ,(*pstu).age。 指向结构体变量的指针 定义格式 struct 类型名 *指针变量名; 为方便起见,C语言定义了结构体的指针变量引用结构体成员的特殊形式: 指针变量名->成员名 “->”为指向运算符 上面示例(*pstu).name,(*pstu).age。可以等价表示为: pstu->name, pstu->age
main() { struct student { long int num; char sex; float score; } student ,*p; p=&stu_1; stu_1.num=200301; stu_1.sex='M'; stu_1.score=89.5; printf("No.:%ld\nsex:%c\nscore:%f\n", stu_1.num,stu_1.sex,stu_1.score); printf("\nNo.:%ld\nsex:%c\nscore:%f\n", (*p).num,(*p).name,(*p).sex,(*p).score); printf("\nNo.:%ld\nsex:%c\nscore:%f\n", p->num,p->name,p->sex,p->.score); } 例11.3 比较结构体成员的几种引用方式
请分析下列几种运算: ①p->n ②p->n++ ③++p->n 总结:结构体成员变量引用方式 ①结构体变量.成员名 ②(*p).成员名 ③p->成员名 其中,->称为指向运算符 可转换为: ①p->n ②(p->n)++ ③++(p->n)
本课程就讲到这里 谢谢大家!