定义和使用结构体
自己建立结构体类型
用户自己建立由不同类型数据组成的组合型的数据结构,它称为结构体
例如,一个学生的学号、姓名、性别、 年龄、成绩、家庭地址等项,是属于同一个学生的,因此组成一个组合数据,如student1和student2的变量,反 映它们之间的内在联系
声明一个结构体类型的一般形式为:
struct 结构体名
{成员表列 (类型名 成员名)};
说明:
(1)结构体类型并非只有一种,而是可以设计出许多种结构体类型,例如
struct Teacher
struct Worker
struct Date等结构体类型(各自包含不同的成员)
说明:
(2) 成员可以属于另一个结构体类型。
struct Date
{ int month;
int day;
int year; };
struct Stu
{ int num;
char name[20];
char sex;
int age;
struct Date birthday;
char addr[30];
};
说明:
(3) 成员可以属于另一个结构体类型。
定义结构体类型变量
前面只是建立了一个结构体类型,它相当于一个模型,并没有定义变量,其中并无具体数据,系统对之也不分配存储单元。
相当于设计好了图纸,但并未建成具体的房屋。为了能在程序中使用结构体类型的数据,应当定义结构体类型的变量,并在其中存放具体的数据。
1. 先声明结构体类型,再定义该类型变量
声明结构体类型struct Student,可以用它来定义变量
struct Student //结构体类型名
student1,student2; //结构体变量名
2.在声明类型的同时定义变量
struct Student
{ int num;
char name[20];
char sex;
int age;
float score;
char addr[30];
} student1,student2;
3. 不指定类型名而直接定义结构体类型变量
其一般形式为:
struct
{ 成员表列 }变量名表列;
指定了一个无名的结构体类型 。
(1) 结构体类型与结构体变量是不同的概念,不要混同。只能对变量赋值、存取或运算,而不能对一个类型赋值、存取或运算。在编译时,对类型是不分配空间的,只对变量分配空间。
(2) 结构体类型中的成员名可以与程序中的变量名相同,但二者不代表同一对象。
(3)对结构体变量中的成员(即“域”),可以单独使用,它的作用与地位相当于普通变量。
结构体变量的初始化和引用
输入两个学生的学号、姓名和成绩,输出成绩较高学生的学号、姓名和成绩
#include "stdio.h"
int main()
{
struct Student
{
int num;
char name[20];
float score;
}student1,student2;
scanf("%d%s%f",&student1.num,student1.name, &student1.score);
scanf("%d%s%f",&student2.num,student2.name, &student2.score);
printf("The higher score is:\n");
if(student1.score>student2.score)
printf("%d %s %6.2f\n",student1.num,student1.name, student1.score);
else if (student1.score<student2.score)
printf("%d %s %6.2f\n",student2.num,student2.name, student2.score);
else
{
printf("%d %s %6.2f\n",student1.num,student1.name, student1.score);
printf("%d %s %6.2f\n",student2.num,student2.name, student2.score);
}
return 0;
}
使用结构体数组
定义结构体数组
有3个候选人,每个选民只能投票选一人,要求编一个统计选票的程序,先后输入被选人的名字,最后输出各人得票结果
#include <string.h>
#include <stdio.h>
struct Person
{ char name[20];
int count;
} leader[3]={"Li",0,"Zhang",0,"Sun",0};
int 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++;
}
for(i=0;i<3;i++)
printf("%5s:%d\n",leader[i].name,leader[i].count);
return 0;
}
说明:
(1)定义结构体数组一般形式是
① struct 结构体名
{成员表列} 数组名[数组长度];
② 先声明一个结构体类型,然后再用此类型定义结构体数组:
结构体类型 数组名[数组长度];
如:
struct Person leader[3];
(2)对结构体数组初始化的形式是在定义数组的后面加上:
={初值表列};
如:
struct Person leader[3]={"Li",0,"Zhang",0,"Fun",0};
结构体数组的应用举例
有n个学生的信息(包括学号、姓名、成绩),要求按照成绩的高低顺序输出各学生的信息
#include "stdio.h"
struct Student
{ int num;
char name[20];
float score;
};
int main()
{
struct Student
stu[5]={{10101,"Zhang",78},{10103,"Wang",98.5},{10106,"Li", 86},{10108,"Ling", 73.5},
{10110,"Fun", 100 }};
struct Student temp;
const int n = 5 ;
int i,j,k;
printf("The order is:\n");
for(i=0;i<n-1;i++)
{
k=i;
for(j=i+1;j<n;j++)
if(stu[j].score>stu[k].score) k=j;
temp=stu[k];
stu[k]=stu[i];
stu[i]=temp;
}
for(i=0;i<n;i++)
printf("%6d %8s %6.2f\n",stu[i].num,stu[i].name,stu[i].score);
printf("\n");
return 0;
}
结构体指针
指向结构体变量的指针
指向结构体对象的指针变量既可以指向结构体变量,也可以用来指向结构体数组中的元素。
指针变量的基类型必须与结构体变量的类型相同。例如:
struct Student *pt;
说明:
(1)为了使用方便和直观,C语言允许把(*p).num用p->num来代替
(2)(*p).name等价于p->name
(3)如果p指向一个结构体变量stu,以下等价:
① stu.成员名(如stu.num)
② (*p).成员名(如(*p).num)
p->成员名(如p->num)
用结构体变量和结构体变量的指针作函数参数
将一个结构体变量的值传递给另一个函数,有3个方法。
(1) 用结构体变量的成员作参数。
例如,用stu[1].num或stu[2].name作函数实参,将实参值传给形参。
u用法和用普通变量作实参是一样的,属于“值
传递”方式。
u应当注意实参与形参的类型保持一致。
(2) 用结构体变量作实参。
u用结构体变量作实参时,将结构体变量所占的内存单元的内容全部按顺序传递给形参,形参
也必须是同类型的结构体变量
u在函数调用期间形参也要占用内存单元。这种
传递方式在空间和时间上开销较大
u在被调用函数期间改变形参(也是结构体变量)的值,不能返回主调函数
u一般较少用这种方法
(3)用指向结构体变量(或数组元素)的指针作实参,将结构体变量(或数组元素)的地址传给形参。
有n个结构体变量,内含学生学号、姓名和3门课程的成绩。要求输出平均成绩最高的学生的信息(包括学号、姓名、3门课程成绩和平均成绩)
#include "stdio.h"
#define N 3
struct Student
{
int num;
char name[20];
float score[3];
float aver;
};
int main()
{
void input(struct Student stu[]);
struct Student max(struct Student stu[]);
void print(struct Student stu);
struct Student stu[N],*p=stu;
input(p);
print(max(p));
return 0;
}
void print(struct Student stud)
{
printf("\n成绩最高的学生是:\n");
printf(“学号:%d\n姓名:%s\n三门课成绩:%5.1f,%5.1f,%5.1f\n平均成
绩:%6.2f\n", stud.num,stud.name,stud.score[0],
stud.score[1],stud.score[2],stud.aver);
}