5.3.6 C51的结构指针
结构指针是指用来指向一个结构变量的指针变量。结构指针的值是所指向的结构变量的首地址。与数组指针类似,在C51语言中,通过结构指针可以访问结构变量。
1.结构指针的声明
结构指针声明的一般形式如下。
struct结构名*结构指针变量名
其中,struct为关键字,说明指针的类型为结构指针,结构名为已声明的结构,即结构指针变量要指向的结构变量的结构类型。
声明结构指针的方法与声明结构变量相类似,可以先声明结构,再声明结构指针,示例如下。
struct student//声明结构
{
int num;//学号
char name[20];//姓名
char sex[2];//性别
int age;//年龄
float score;//成绩
};
struct student*ps;//声明结构指针
本例中,先声明结构student,再声明结构指针ps为结构student的结构指针。当然也可在定义结构时,同时声明结构指针,示例如下。
struct student//定义结构
{
int num;//学号
char name[20];//姓名
char sex[2];//性别
int age;//年龄
float score;//成绩
}*ps;//声明结构指针
2.结构指针的赋值
结构指针变量要在程序中使用,必须先对其进行赋值,即将结构变量的首地址赋值给该结构指针。
要注意的是,在程序中不能把结构名赋予指针变量。例如,声明Alice为结构student类型的结构变量。
ps=&Alice//正确的表示
ps=&student//错误的表示
因为声明后的结构名只是一个结构形式,系统不对其分配内存空间,因而没有所谓结构的首地址。而结构变量是被声明为某种类型的结构的变量,声明后系统会对该变量分配内存空间。所以可以定义指针指向结构变量而不能指向结构。
3.结构指针的使用
声明结构指针变量并对其赋值后,就可以在程序中通过结构指针间接地访问结构变量的各结构成员。结构指针访问结构变量的成员的一般形式如下。
(*结构指针变量).成员名
或者
结构指针变量->成员名
其中,“.”和“->”为成员符,成员名即结构中的结构成员变量。
注意因为成员符“.”的优先级高于“”,所以表达式中的括号不可少。如果省略括号,则变成“结构指针变量.成员名”,其等效于“*(结构指针变量.成员名)”,这样意义就完全不同了。
对于前面已声明的结构指针变量ps,可以采用如下的两种方式来访问score成员,示例如下。
(*ps).score
ps->score
至此,用户可以采用如下的3种方式表示结构成员。
❑结构变量.成员名
❑(*结构指针变量).成员名
❑结构指针变量->成员名
介绍完结构指针的声明、赋值和使用方法后,下面以一个完整的程序示例,来进一步说明结构指针在程序中的应用。结构指针的程序示例如下。
include<stdio.h>//头文件
struct student//声明结构
{
int num;//学号
char name[20];//姓名
char sex[2];//性别
int age;//年龄
float score;//成绩
}Bob={101,“Bob”“M”,22,90.0};//声明并初始化结构变量
void main()//主函数
{
struct student*ps;//声明结构指针
ps=&Bob;//为结构指针赋值
//采用第一种方式输出成员值
printf(“Name=%s,Num=%d\n”,Bob.name,Bob.num);
printf(“Age=%d,Sex=%s,score=%f\n”,Bob.age,Bob.sex,Bob.score);//采用第二种方式输出成员值
printf(“Name=%s,Num=%d\n”,(pstu).name,(pstu).num);
printf(“Age=%d,Sex=%s,score=%f\n”,(pstu).age,(pstu).sex,(*pstu).score);//采用第三种方式输出成员值
printf(“Name=%s,Num=%d\n”,pstu->name,pstu->num);
printf(“Age=%d,Sex=%s,score=%f\n”,pstu->age,pstu->sex,pstu->score);
}
该程序可以在KeilµVision3编译环境中执行,运行的结果如下。
Name=Bob,Num=101
Age=24,Sex=M,score=90.000000
Name=Bob,Num=101
Age=24,Sex=M,score=90.000000
Name=Bob,Num=101
Age=24,Sex=M,score=90.000000
在本例中,先声明了结构student和结构变量Bob,并同时对结构变量Bob进行了初始化。然后在主函数中定义结构指针并赋值,使其指向结构变量Bob。最后分别使用结构变量引用成员和结构指针引用成员的两种方式来输出结构变量中的成员值。
从本例的运行结果可以看出,这3种用于表示结构成员的形式是完全等效的。
4.指向结构数组的结构指针
结构指针变量除了可以指向一般的结构变量外,还可以指向结构数组。此时结构指针变量的值是整个结构数组的首地址。结构指针变量也可以指向结构数组中的一个数组元素,此时结构指针变量的值是该结构数组元素的首地址。
若声明ps为指向结构数组的指针变量,则ps指向该结构数组的0号元素,ps+1指向1号元素,ps+i则指向i号元素。与指向普通数组的指针的情况是完全相同的。
指向结构数组的结构指针的程序示例如下。
include<stdio.h>//头文件
struct student//声明结构
{
int num;//学号
char name[20];//姓名
char sex[2];//性别
int age;//年龄
float score;//成绩
}class1[4]={//声明结构数组并初始化
{101,“Bob”,“M”,24,90.0},
{102,“Jack”,“M”,25,88.5},
{103,“Twis”,“M”,23,78.5},
{104,“Bohm”,“M”,21,82.5}};
void main()//主函数
{
struct student*ps;//声明结构指针
printf(“Num\tName\tSex\tAge\tscore\n”);//输出标题
for(ps=class1;ps<class1+4;ps++)//输出各元素的成员值
printf(“%s\t%d\t%d\t%s\%f\n”,(ps).name,(ps).num,ps->age,ps->sex,ps->score);
}
该程序可以在KeilµVision3编译环境中执行,运行的结果如下。
Num Name Sex Age score
101 Bob M 24 90.000000
102 Jack M 25 88.500000
103 Twis M 23 78.500000
104 Bohm M 21 82.500000
本例中,先定义了结构student,并同时声明并初始化了结构数组class1[4]。然后分别采用了结构指针的两种表示方式来输出各个结构数组元素的成员值。
在程序中使用结构指针时,要注意结构指针变量可以指向结构变量,也可以指向结构数组和结构数组元素,但是结构指针变量不能指向其结构成员,即不允许将结构成员的首地址来赋值给结构指针变量。示例如下。
ps=&class1[1].sex;//是错误的。不能将结构成员的首地址赋值给结构指针
ps=class1;//是正确的,赋予结构指针数组首地址
ps=&class1[3];//是正确的,赋予结构指针数组元素首地址