前言:
此篇是针对 指向结构体数组的指针 方面的练习。
解题思路:
用指向结构体变量的指针来处理:
(1)声明结构体类型 struct Student ,并定义结构体数组,同时使之初始化;
(2)定义一个指向 struct Student 类型数据的指针变量 p;
(3)使 p 指向结构体数组的首元素,输出它指向的元素中的有关信息;
(4)使 p 指向结构体数组的下一个元素,输出它指向的元素中的有关信息;
(5)再使 p 指向结构体数组的下一个元素,输出它指向的元素中的有关信息。
正文:
#include<stdio.h>
struct Student{ //声明结构体类型struct Student
int num;
char name[20];
char sex;
int age;
};
struct Student stu[3]={{10101,"Li Lin",'M',18},{10102,"Zhang Fang",'M',19},
{10104,"Wang Min",'F',20}}; //定义结构体数组并初始化
int main() {
struct Student *p; //定义指向struct Student结构体变量的指针变量
printf(" No. Name sex age\n");
for(p=stu;p<stu+3;p++)
printf("%5d %-20s %2c %4d\n",p->num,p->name,p->sex,p->age);
//输出结果
return 0;
}
程序分析:
p 是指向 struct Student 结构体类型数据的指针变量。在 for 语句中先使 p 的初值为 stu,也就是数组 stu 第1个元素的起始地址,见图9.6 中 p 指向。在第1次循环中输出 stu[0] 的各个成员值。然后执行 p++,使 p 自加1.p 加1意味着 p 所增加的值为结构体数组 stu 的一个元素所占的字节数。执行 p++后 p 的值等于 stu+1,p 指向 stu[1],见图9.6 中 p’ 的指向。在第2次循环中输出 stu[1] 的各成员值。在执行 p++ 后,p 的值等于 stu+2,它的指向 见图9.6 中的 p’’,再输出 stu[2] 的各成员值。在执行 p++ 后,p 的值变为 stu+3,已不再小于 stu+3了,不再指向循环。
注意:
(1)如果 p 的初值为 stu ,即指向 stu 的第1个元素,p 加1后,p 就指向下一个元素。例如:
(++p)->num 先使 p 自加1,然后得到 p 指向的元素中的 num 成员值(即10102)。
(p++)->num 先求得 p->num 的值(即10101),然后再使 p 自加1,指向 stu[1]。
请注意以上二者的不同。
(2)程序定义了 p 是一个指向 struct Student 类型对象的指针变量,它用来指向一个 struct Student 类型的对象(在例9.6中的 p 的值是 stu 数组的一个元素(如 stu[0]或 stu[1] )的起始地址),不应用来指向 stu 数组元素中的某一成员。例如,下面的用法是不对的:
p=stu[1].name; //stu[1].name是stu[1]元素中的成员name的首字符的地址
编译时将给出 “警告” 信息,表示地址的类型不匹配。不要认为反正 p 是存放地址的,可以将任何地址赋给它。如果要将某一成员的地址赋给 p,可以用强制类型转换,先将成员的地址转换成 p 的类型。例如:
p=(struct Sutdent*)stu[0].name;
此时,p 的值是 stu[0]元素的 name 成员的起始地址。可以用 “printf("%s”,p);“输出 stu[0] 中成员 name 的值。但是,p 仍保持原来的类型。如果执行 ”printf(”%s“,p+1);“,则会输出 stu[1] 中 name 的值。执行 p++时,p的值增加了结构体 struct Student 的长度。
总结:
运行结果: