结构体指针的定义与使用
当一个指针变量用来指向一个结构体变量时,称之为结构体指针变量。 结构体指针变量的值是所指向的结构体变量的起始地址。通过结构体指针即可访问该结构体变量,这与数组指针和函数指针的情况是相同的。
结构体指针变量定义的一般形式: 结构体名 *结构体指针变量名
当然也可以在定义结构体的同时定义这个结构体指针变量。
例如:(定义一个结构体(类型为自己定义的 student)指针变量 p)
1. struct student{ 2. char name[20]; 3. char sex; 4. float score; 5. } *p;
也可写成
1. struct student { 2. char name[20]; 3. char sex; 4. float score; 5. }; 6. student *p;
与前面讨论的各类指针变量相同,结构体指针变量也必须要赋值后才能使用。
赋值是把结构体变量的首地址赋予该指针变量,不能把结构名赋予该指针变量。
例如:如果 p 是被定义为 student 类型的结构体指针变量,boy 是被定义为 student 类型的结构体变量,则:p=&boy 是正确的,而 p=&student 是错误的。
引用结构体指针变量指向的结构体变量的成员的方法如下:
①、指针名->成员名
②、(*指针名).成员名
例如: (*p).score 与 p->score 是等价的。
【例 14】结构体指针运用举例。
1. #include<cstdio> 2. using namespace std; 3. struct student { 4. char name[20]; 5. char sex; 6. int score; 7. } s[3]={{"xiaoming",'f',356},{"xiaoliang",'f',350},{"xiaohong",'m',0}}; 8. int main() 9. { 10. student *p; 11. printf("Name Sex Score\n"); 12. for (p=s; p<s+3; p++) 13. printf("%-9s%3c%7d\n",p->name,p->sex,p->score); 14. return 0; 15. }
输出:
Name Sex Score
xiaoming f 356
xiaoliang f 350
xiaohong m 0
【说明】 这里 p++起到移动指针的作用,随着 p 的变化,输出数组不同元素内容。
自引用结构
在一个结构体内部包含一个类型为该结构体本身的成员是否合法呢?
1. struct stu { 2. char name[20]; 3. int age,score; 4. stu p; 5. };
这种类型的自引用是非法的,因为成员 p 是另一个完整的结构,其内部还将包含它自己的成员 p。这第 2 个成员又是一个完整的结构,它还将包含自己的成员 p……这样重复下 去就永无止境了。这有点像永远不会终止的递归程序。
但下面这个程序是合法的:
1. struct stu { 2. char name[20]; 3. int age,score; 4. stu *p; 5. };
这个声明和前面那个声明的区别在于 p 现在是一个指针而不是结构体。编译器在结构体的长度确定之前就已经知道指针的长度,所以这种类型的自引用是合法的。
当一个结构体中有一个或是多个成员是指针,它们所指向的类型就是本结构体类型时, 通常这种结构体称为“引用自身的结构体”,即“自引用结构”。这种自引用结构是实现其他一 些结构的基础。
自引用结构在动态数据结构中有重要作用,甚至可以说,自引用结构是 C/C++语言实 现动态数据结构的基石。包括动态的链表、堆、栈、树,无不是自引用结构的具体实现。
例如,下面的定义就可以在实际操作中建立起一个链表。
1. struct node { 2. int x,y; 3. node *next; 4. } point;