| 
 
| 结构体指针变量的定义 定义结构体变量的一般形式如下:
 形式1:
 struct结构体标识符
 {
 成员变量列表;…
 };
 struct 结构体标识符 *指针变量名;
 形式2
 struct结构体标识符
 {
 成员变量列表;…
 } *指针变量名;
 形式3:
 struct
 {
 成员变量列表;…
 }*指针变量名;
 其中“指针变量名”为结构体指针变量的名称。形式1是先定义结构体,然后再定义此类型的结构体指针变量;形式2和形式3是在定义结构体的同时定义此类型的结构体指针变量。例如:定义struct Point类型的指针变量pPoints的形式如下:
 struct Point
 {
 double x;
 double y;
 double z;
 } *pPoints;
 结构体指针变量的初始化
 TAG:结构体,结构体指针
 TEXT:结构体指针变量在使用前必须进行初始化,其初始化的方式与基本数据类型指针变量的初始化相同,在定义的同时赋予其一结构体变量的地址。例如
 struct Point oPoint={0,0,0};
 struct Point pPoints=& oPoint; /*定义的同时初始化*/
 在实际应用过程中,可以不对其进行初始化,但是在使用前必须通过赋值表达式赋予其有效的地址值。例如:
 struct Point oPoint={0,0,0};
 struct Point *pPoints2;
 pPoints2=& oPoint; /*通过赋值表达式*/
 
 结构体指针变量的引用
 TAG:结构体,结构体指针
 TEXT:与基本类型指针变量相似,结构体指针变量主要作用是存储其结构体变量的地址或结构体数组的地址,通过间接方式操作对应的变量和数组。在C语言中规定,结构体指针变量可以参与的运算符如下:
 ++,--,+ ,* ,->,.,|,&,!
 下面通过例题说明,如何引用结构体指针变量存储结构体变量地址,以及如何通过结构体指针变量间接的引用结构体变量以及其成员变量。
 例9-3 应用结构体指针变量,打印结构体成员变量的信息。
 #include <stdio.h>
 struct Point
 {
 double x; /*x坐标*/
 double y; /*y坐标*/
 double z; /*z坐标*/
 };
 int main()
 {
 struct Point oPoint1={100,100,0};
 struct Point oPoint2;
 struct Point *pPoint; /*定义结构体指针变量*/
 pPoint=& oPoint2; /*结构体指针变量赋值*/
 (*pPoint).x= oPoint1.x;
 (*pPoint).y= oPoint1.y;
 (*pPoint).z= oPoint1.z;
 printf("oPoint2={%7.2f,%7.2f,%7.2f}",oPoint2.x, oPoint2.y, oPoint2.z);
 return(0);
 }
 程序运行结果如下:
 oPoint2={ 100.00,100.00,0.00}
 其中表达式&oPoint2的作用是获得结构体变量oPoint2的地址。表达式pPoint=&oPoint2的作用是将oPoint2的地址存储在结构体指针变量pPoint中,因此pPoint存储了oPoint2的地址。*pPoint代表指针变量pPoint中的内容,因此*pPoint 和oPoint2等价。
 通过结构体指针变量获得其结构体变量的成员变量的一般形式如下:
 (*结构体指针变量). 成员变量
 其中“结构体指针变量”为结构体指针变量,“成员变量”为结构体成员变量名称,“.”为取结构体成员变量的运算符。
 另外C语言中引入了新的运算符“->”,通过结构体指针变量直接获得结构体变量的成员变量,一般形式如下:
 结构体指针变量-> 成员变量
 其中“结构体指针变量”为结构体指针变量,“成员变量”为结构体成员变量名称,“- >”为运算符。
 因此,例9-3中的部分代码
 ……
 (*pPoint).x= oPoint1.x;
 (*pPoint).y= oPoint1.y;
 (*pPoint).z= oPoint1.z;
 ……
 等价于
 ……
 pPoint->x= oPoint1.x;
 pPoint->y= oPoint1.y;
 pPoint->z= oPoint1.z;
 ……
 下面介绍如何应用结构体指针变量存储结构体数组的首地址,以及如何通过结构体指针变量获得结构体数组的元素及其成员变量。
 例9-4 应用结构体指针变量改写例9-3,主要介绍修改部分Mutiline函数,其他部分略。
 /*多边形绘制函数,形式参数为struct Point 类型指针变量pPoints */
 void Mutiline(struct Point *pPoints)
 {
 int i;
 struct Point *pOPoint; /*定义结构体指针变量*/
 pOPoint=pPoints; /*存储结构体数组的首地址*/
 moveto(pPoints->x,pPoints->y) ; /*将绘图点移动到第0个点*/
 for( i=0; i<NPOINTS ; ++i )
 {
 lineto(pPoints->x, pPoints->y); /*从上一点向当前点绘制直线*/
 pPoints++;
 }
 pPoints=pOPoint; /*指向结构体数组的首地址*/
 lineto(pPoints->x,pPoints->y); /*封闭曲线*/
 }
 函数void Mutiline(struct Point *pPoints)的输入参数为struct Point指针变量pPoints。在主函数中调用形式为Mutiline(oPoints),将struct Point类型数组oPoints的首地址信息拷贝给形式参数struct Point *pPoint,此时pPoint指向结构体数组oPoints的第一个元素,如图所示。
 主函数调用Mutiline的过程如下,首先将struct Point类型数组oPoints的首地址信息拷贝给形式参数struct Point *pPoint,等价于
 pPoint= oPoints;
 接下来,程序的控制权交给Mutiline函数,进入函数Mutiline。在程序进入函数Mutiline之后,pPoints 指向oPoints的首地址,跟踪程序表明此时变量pPoints的当前值为0X0F82。另外,由于数组第一个元素oPoints[0]的地址与数组的首地址相同。亦可以理解为此时pPoints指向了数组元素oPoints[0]的地址,因此*pPoints与oPoints[0]等价,表达式pPoints->x可以访问oPoints[0]的成员变量x,同样表达式pPoints->y可以访问oPoints[0]的成员变量y。执行pPoints++语句之后,pPoints的当前值为0X 0F9A。
 
  0X0F9A- 0X0F82=0X0018=24=sizeof(struct Point),24个字节正好为struct Point的大小。
 此时pPoints指向数组元素oPoints[1]的地址, 因此*pPoints与oPoints[1]的等价。依次类推,通过pPoints的加法运算可以访问结构体数组oPoints中的所有元素。
 因此要正确理解结构体指针变量的算术运算,pPoints++或pPoints= pPoints+1的作用不是简单的地址值加1,而是当前的地址值加上结构体类型的大小。
 结构体指针变量+1= 结构体指针变量+sizeof(struct 结构体)
 例9-5 输入10个同学的姓名、数学成绩、英语成绩和物理成绩,确定总分最高的同学,并打印其姓名及其三门课程的成绩。
 #include "stdio.h"
 struct Student /*定义结构体struct Student*/
 {
 char Name[20]; /*姓名*/
 float Math; /*数学*/
 float English; /*英语*/
 float Physical; /*物理*/
 };
 void main()
 {
 /*定义struct Student类型结构体数组存储所有同学的相关信息*/
 struct Student oStudents[10]={{"",0,0,0}};
 /*定义struct Student类型指针存储总分最高的同学的地址信息*/
 struct Student *pMaxStu;
 struct Student *pStudent;
 float fMaxScore,fTotal;
 float fMath,fEnglish,fPhysical;
 char szName[20];
 printf("\nPlease input 10 students and there score\n");/*提示信息*/
 printf("---------------------------- ------------\n");
 printf("Name Math English Physical \n");
 printf("---------------------------- ------------\n");
 fMaxScore=0;
 pMaxStu=oStudents;
 for(pStudent=oStudents;pStudent<oStudents+10;pStudent++)
 {
 /*读入当前同学的相关信息*/
 scanf("%s %f %f %f",szName,&fMath,&fEnglish,&fPhysical);
 strcpy(pStudent->Name,szName);
 pStudent->Math=fMath;
 pStudent->English=fEnglish;
 pStudent->Physical=fPhysical;
 fTotal=pStudent->Math+pStudent- >English+pStudent->Physical;
 /*获得当前最高分的同学*/
 if(fMaxScore<fTotal)
 {
 pMaxStu=pStudent;
 }
 }
 printf("---------------------------- ------------\n");
 printf("%s,%f,%f,%f",
 pMaxStu->Name,pMaxStu->Math,pMaxStu->English,pMaxStu- >Physical);
 }
 首先定义长度为10的struct Student类型结构体数组用于存储所有同学的相关信息,定义struct Student类型指针pMaxStu存储最高总分同学的地址信息。定义struct Student类型指针oStudents指向结构体数组oStudents 。
 循环语句
 for(pStudent=oStudents;pStudent<oStudents+10;pStudent++)
 中pStudent=oStudents的作用是令pStudent指向数组的第一个元素;循环条件是pStudent<oStudents+10,即循环10次。其中语句
 pStudent->Math=fMath;
 pStudent->English=fEnglish;
 pStudent->Physical=fPhysical;
 的作用是保存当前同学的相关信息。
 | 
 |