结构体指针
在 C 语言中,几乎可以为任何类型(包括用户定义类型)创建指针。为结构体创建指针极其常见。示例如下所示:
typedef struct { char name[21]; char city[21]; char state[3]; } Rec; typedef Rec *RecPointer; RecPointer r; r = (RecPointer)malloc(sizeof(Rec));
指针 r 是一个结构体指针。请注意,r 是一个指针,因此像其他任何指针一样占用四个字节的内存。然而,malloc 语句从堆中分配了 45 字节的内存。*r 是一个结构体,就像类型为 Rec 的其他任何结构体一样。以下代码显示了指针变量的典型用法:
广告
strcpy((*r).name, "Leigh"); strcpy((*r).city, "Raleigh"); strcpy((*r).state, "NC"); printf("%s\n", (*r).city); free(r);
你像处理普通结构体变量一样处理 *r,但在 C 语言中必须注意运算符的优先级。如果你省略 *r 周围的括号,代码将无法编译,因为“.”运算符的优先级高于“\*”运算符。由于在处理结构体指针时输入大量括号会变得繁琐,C 语言提供了一种速记表示法,其功能完全相同:
strcpy(r->name, "Leigh");
r-> 记法与 (\*r). 完全等效,但字符数少两个。
数组指针
也可以创建数组指针,如下所示:
int *p; int i; p = (int *)malloc(sizeof(int[10])); for (i=0; i<10; i++) p[i] = 0; free(p);
或
int *p; int i; p = (int *)malloc(sizeof(int[10])); for (i=0; i<10; i++) *(p+i) = 0; free(p);
请注意,当你创建一个指向整数数组的指针时,你只是创建了一个普通的 int 指针。malloc 调用会分配所需大小的数组,指针指向该数组的第一个元素。你可以使用普通数组索引来遍历 p 指向的数组,也可以使用指针算术来完成。C 语言认为这两种形式是等效的。
这种特定技术在处理字符串时非常有用。它允许你分配足够的存储空间来精确容纳特定大小的字符串。
指针数组
有时,通过声明指针数组可以节省大量空间,或者解决某些内存密集型问题。在下面的示例代码中,声明了一个包含 10 个结构体指针的数组,而不是声明一个结构体数组。如果改为创建结构体数组,则该数组将需要 243 * 10 = 2,430 字节。使用指针数组可以使数组占用最小空间,直到实际记录通过 malloc 语句分配。以下代码仅分配一个记录,在其中放置一个值,然后释放该记录以演示此过程:
typedef struct { char s1[81]; char s2[81]; char s3[81]; } Rec; Rec *a[10]; a[0] = (Rec *)malloc(sizeof(Rec)); strcpy(a[0]->s1, "hello"); free(a[0]);
包含指针的结构体
结构体可以包含指针,如下所示:
typedef struct { char name[21]; char city[21]; char phone[21]; char *comment; } Addr; Addr s; char comm[100]; gets(s.name, 20); gets(s.city, 20); gets(s.phone, 20); gets(comm, 100); s.comment = (char *)malloc(sizeof(char[strlen(comm)+1])); strcpy(s.comment, comm);
当只有某些记录的注释字段中实际包含注释时,此技术非常有用。如果记录没有注释,则注释字段将仅包含一个指针(4 字节)。那些有注释的记录会根据用户输入的字符串长度精确分配足够的空间来存储注释字符串。