p是指向struct student结构体类型数据的指针变量。在for语句中先使p的初值为stu,也就是数组stu的起始地址,见图11.8中p的指向。在第一次循环中输出stu[0]的各个成员值。然后执行p++,使p自加1。p加1意味着p所增加的值为结构体数组stu的一个元素所占的字节数(在本例中为2+20+1+2=25字节)。执行p++后p的值等于stu+1,p指向stu[1]的起始地址,见图11.8中p‘的指向。在第二次循环中输出stu[1]的各成员值。在执行p++后,p的值等于stu+2,它的指向见图11.8中的p″。再输出stu[2]的各成员值。 在执行p++后,p的值变为stu+3, 已不再小于stu+3了,不再执行循环。 注意以下两点: (1) 如果p的初值为stu,即指向第一个元素,则p加1后p就指向下一个元素的起始地址。例如: (++p)->num 先使p自加1,然后得到它指向的元素中的num成员值(即10102)。 (p++)->num 先得到p->num的值(即10101),然后使p自加1,指向stu[1]。 请注意以上二者的不同。 (2) 程序已定义了p是一个指向struct student类型数据的指针变量,它用来指向一个struct student型的数据(在例11.4中p的值是stu数组的一个元素(如stu[0],stu[1])的起始地址),不应用来指向stu数组元素中的某一成员。例如,下面的用法是不对的: p=stu[1].name 编译时将给出警告信息,表示地址的类型不匹配。千万不要认为反正p是存放地址的,可以将任何地 址赋给它。如果地址类型不相同,可以用强制类型转换。例如: p=(struct student *)stu[0].name; 此时,p的值是stu[0] 元素的name成员的起始地址。可以用“printf("%s",p);”输出stu[0]中成员name的值,但是,p仍保持原来的类型。执行“printf("%s",p+1);”,则会输出stu[1]中name的值。执行p+1时,p的值增加了结构体struct student的长度。
C程序实例:指向结构体数组的指针的应用 |
例11.4指向结构体数组的指针的应用 |
程序实例 |
例11.4指向结构体数组的指针的应用。
struct student {int num; char name[20]; char sex; int age; }; struct student stu[3]={{10101,“Li Lin”,‘M’,18},{10102,“Zhang Fun”,‘M’,19},{10104,“Wang Min”,‘F’,20}}; main() {struct student*p; printf(" No.Namesexage\n"); for (p=stu;p<stu+3;p++) printf("%5d %-20s %2c %4d\n",p->num, p->name, p->sex, p->age); } |
程序运行 |
No. Name sex age 10101 Li Lin M 18 10102 Zhang Fun M 19 10104 Wang Min F 20 |
程序分析 |
p是指向struct student结构体类型数据的指针变量。在for语句中先使p的初值为stu,也就是数组stu的起始地址,见图11.8中p的指向。在第一次循环中输出stu[0]的各个成员值。然后执行p++,使p自加1。p加1意味着p所增加的值为结构体数组stu的一个元素所占的字节数(在本例中为2+20+1+2=25字节)。执行p++后p的值等于stu+1,p指向stu[1]的起始地址,见图11.8中p‘的指向。在第二次循环中输出stu[1]的各成员值。在执行p++后,p的值等于stu+2,它的指向见图11.8中的p″。再输出stu[2]的各成员值。 在执行p++后,p的值变为stu+3, 已不再小于stu+3了,不再执行循环。 注意以下两点: (1) 如果p的初值为stu,即指向第一个元素,则p加1后p就指向下一个元素的起始地址。例如: (++p)->num 先使p自加1,然后得到它指向的元素中的num成员值(即10102)。 (p++)->num 先得到p->num的值(即10101),然后使p自加1,指向stu[1]。 请注意以上二者的不同。 (2) 程序已定义了p是一个指向struct student类型数据的指针变量,它用来指向一个struct student型的数据(在例11.4中p的值是stu数组的一个元素(如stu[0],stu[1])的起始地址),不应用来指向stu数组元素中的某一成员。例如,下面的用法是不对的: p=stu[1].name 编译时将给出警告信息,表示地址的类型不匹配。千万不要认为反正p是存放地址的,可以将任何地 址赋给它。如果地址类型不相同,可以用强制类型转换。例如: p=(struct student *)stu[0].name; 此时,p的值是stu[0] 元素的name成员的起始地址。可以用“printf("%s",p);”输出stu[0]中成员name的值,但是,p仍保持原来的类型。执行“printf("%s",p+1);”,则会输出stu[1]中name的值。执行p+1时,p的值增加了结构体struct student的长度。 |
图11.8 |
|
|
|
|
|