目录
9.3 结构体指针
所谓结构体变量指针就是指向结构体变量的指针,一个结构体变量的起始地址就是这个结构体变量的指针。如果把一个结构体变量的起始地址存放在一个指针变量中,那么,这个指针变量就指向该结构体变量。
9.3.1 结构体变量的指针
指向结构体对象的指针既可以指向结构体变量,也可以指向结构体数组中的元素。指针变量的基类型必须与结构体变量的类型相同。
例如:struct Stundent * p; //p可以指向struct Student 类型的变量或数组。
例题:通过指向结构体变量的指针变量输出结构体变量中的成员的信息。
#include<stdio.h>
#include<string.h>
int main(){
struct Student{
long num;
char name[20];
char sex;
float score;
};
struct Student stu1;
struct Student *p;
p = &stu1;
stu1.num = 10101;
strcpy(stu1.name, "Li lin");
stu1.sex = 'M';
stu1.score = 99;
printf("No:%d\nname:%s\nsex:%c\nscore:%lf\n", stu1.num, stu1.name, stu1.sex, stu1.score);
printf("No:%d\nname:%s\nsex:%c\nscore:%lf\n", (*p).num, (*p).name, (*p).sex, (*p).score);
return 0;
}
运行结果如下:
两个printf函数输出的结果是相同。
程序分析:声明了结构体类型struct Studen,然后定义了一个结构体变量stu1,又定义了指针变量p,它指向一个struct Student类型的对象。将结构体变量stu1的起始地址赋给指针变量p,也就是p指向stu1。然后对各个成员赋值。
第二个printf函数是通过指向结构体变量的指针变量访问它的成员,输出stu1的各个成员的值。使用的是(*p).num这样的形式。(*p)表示指向p指向的结构体变量,(*p).num
是p所指向的结构体变量中的成员num。注意*p两侧的的括号不可省略,因为成员运算符“.”优先于“*”运算符,*p.num就等价于*(p.num)了。
说明:为了使用方便和直观,C语言允许把(*p).num用p->num代替,“->”代表一个箭头,p->num表示p所指向的结构体变量中num成员。同样(*p).name等价于p->name。
“->”称为指向运算符。
如果p指向一个结构体变量stu,以下3种用法等价:
- stu.成员名(如stu.num)
- (*p).成员名(如(*p).num)
- p->成员名(如p->num)
9.3.2 指向结构体数组的指针
可以用指针变量指向结构体数组的元素。
例题:有3个学生信息,放在结构体数组中,要求输出全部学生的信息。
#include<stdio.h>
int main(){
struct Student {
int num;
char name[20];
char sex;
int age;
};
struct Student stu[3] = { { 1001, "Zhang San", 'M', 17 }, { 1002, "Li Si", 'M', 18 }, { 1003, "Wang Wu", 'M', 19 } };
struct Student *p;
for (p = stu; p < stu + 3; p++){
printf("%5d%10s%2c%4d\n",p->num, p->name, p->sex, p->age);
}
return 0;
}
运行结果如下:
0
程序分析:p是指向sturct Student结构体类型的数据的指针变量。在for循环语句中先使p的初值为stu,也就是数组的序号为0的元素的地址(即stu[0]的起始地址),在第一次循环中输出stu[0]的各个成员的值,然后执行p++,再接着输出下一个元素的各个成员。
9.3.3 结构体变量和结构体变量的指针作函数参数
将一个结构体变量的值传递给另一个函数,有3种方法:
- 用结构体变量的成员作参数。例如stu.num或stu[1].num作函数参数,将实值传给形参。属于“值传递”方式。
- 用结构体变量作实参。用结构体变量作实参时,采取的也是“值传递”方式。将结构体变量所占的内存单元的内容全部按顺序传递给形参,形参也比须是同类型的结构体变量。
- 用指向结构体变量的指针作实参。将结构体变量(或数组元素)的地址传递形参。
例题:有n个结构体变量,内含学生学号、姓名和三门课程的成绩。要求输出平均成绩最高的学生信息(学号、姓名和三名课程成绩和平均成绩)。
#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 input(struct Student stu[]){
int i;
printf("请输入各个学生的信息:学号、姓名、3门课成绩\n");
for (i = 0; i < N; i++){
scanf("%d %s %f %f %f", &stu[i].num, stu[i].name, &stu[i].score[0], &stu[i].score[1], &stu[i].score[2]);
stu[i].aver = (stu[i].score[0] + stu[i].score[0] + stu[i].score[0]) / 3.0;
}
}
struct Student max(struct Student stu[]){
int i, m=0;
for (i = 0; i < N; i++){
if (stu[i].aver>stu[m].aver){
m = i;
}
}
return stu[m];
}
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);
}
运行结果如下:
程序分析: