三.结构体数组元素的引用
如: stu[0].num stu[1].name stu[2].age
例:对候选人得票的统计程序。设有3个候选人,每次输入一个得票的候选人的名字,要求最后输出各人得票结果。
#include “string.h” struct person { char name[20]; int count;
}leader[3]={“Li”,0,”Zhang”,0,”Wang”,0};
main() { int i,j;
char leader_name[20]; for (i=1;i<=10;i++)
{ scanf(“%s”,leader_name); for (j=0;j<3;j++)
if (strcmp(leader_name,leader[j].name)==0) leader[j].count++;
}
printf(“\\n”); for (i=0;i<3;i++)
printf(“%5s:%d\\n”,leader[i].name,leader[i].count); }
§10.6 指向结构体类型数据的指针
一个结构体变量的指针就是该变量所占据的内存段的起始地址。
一.指向结构体变量的指针
1.定义
struct student stu1,*p; 2.引用 p=&stu1;
stu1.num 即为 (*p).num 或 p->num stu1.name 即为 (*p).name 或 p->name
括号不能省略,否则*p.num相当于*(p.num)。 ->为指向结构体成员运算符。 二.指向结构体数组的指针
struct student { long num; char name[20]; char sex; int age;
char addr[30];
} stu[3]={ {99031,”Lilin”,’M’,18,”123 Beijing Road”},{99032,”Zhang san”,’M’,20,”130 Shanghai Road”},{99033,”Lisi”,’F’,19,”1010 Zhongshan Road”}};
main()
{ struct student *p;
printf(“ No Name Sex Age Addr\\n”); for (p=stu; p printf(“%ld%-20s,M%-30s\\n”,p->num,p->name,p->sex,p->age,p->addr); } 注意:若p指向stu的第一个元素(即p=stu),则: p->age++ 相当于 stu[0].age++ ++p->age 相当于 ++stu[0].age (p++)->age 先得到p->age值为18,而后p++即p指向stu[1] (++p)->age 先p++即p指向stu[1],再取p->age值为20 三.用指向结构体的指针作函数参数 例:有一个结构体变量stu,内含学生学号,姓名和3门课程的成绩。要求在main中赋值,在函数print中将它们打印输出。 #include “string.h” #define FORMAT “%d\\n%s\\n%f\\n%f\\n%f\\n” struct student { int num; char name[20]; float score[3]; }; main() { void print(struct student *p); struct student stu; stu.num=1234; strcpy(stu.name,”Lili”); stu.score[0]=67.5; stu.score[1]=89; stu.score[2]=78.6; print(&stu); } void print(struct student *p) { printf(FORMAT,p->num,p->name,p->score[0], p->score[1],p->score[2]); } 也可以用结构体变量的成员作为参数: print(stu.num,stu.name,stu.score[0], stu.score[1], stu.score[2]); 另外,ANSI C允许用结构体变量作为参数,但必须保证实参与形参的类型相同。 print(stu); 但这两种方法都必须把成员一个个传递,费时费空间。一般采用指针作参数 较好,能提高运行效率。 §10.7 用指针处理链表 一.链表概述 链表是一种常见的重要的数据结构,它是动态地进行存储分配的一种结构。(数组是静态的存储结构)。 下面介绍最简单的一种链表(单向链表)的结构: head 1249 1249 A 1356 1356 B 1475 1475 C 1021 1021 D NULL 链表由“结点”构成,结点包括两部分的内容:一部分为用户的信息(数据),通常包括各种类型的数据。另一部分为指向下一个结点的指针。 为了表示链表的起始位置(起始结点),有一个指针指向第一个结点,存放这个指针的变量称为“头指针”变量(一般变量名为head)。 结点一般采用结构体类型: struct student1 { int num; float score; struct student1 *next; } 二.结点的插入操作 head ? p ? s 要将结点s插入在p结点之后,可用如下操作: s->next=p->next; p->next=s; 三.结点的删除操作 要将p结点的后一个结点删除,可用如下操作: s=p->next; p->next=p->next->next; (p->next=s->next;) free(s); head ? p ? 四.处理动态链表所需的函数 这些函数所包含的文件: ANSI标准包含在“stdlib.h”中; 而多数C系统包含在“malloc.h”中; Turbo C包含在“alloc.h”中。 1.malloc函数 函数原型:void *malloc(unsigned int size) 作用:在内存中分配一个长度为size字节的连续空间。 返回指向分配域的起始地址指针,若不成功则返回空指针(NULL)。 如: int *p; p=(int *)malloc(sizeof(int));