C Primer Plus(十四)

第十四章 结构和其它数据形式14.1 建立结构声明

结构声明是描述结构如何组合的主要方法。声明如下:struct book{char title[MAXTITL];char author[MAXAUTL];float value;};该声明描述了一个由两个字符数组和一个float变量组成的结构。它并没有创建一个实际的数据对象,而是描述了组成这类对象的元素。以后可以这样声明: struct book library;它把library声明为一个使用book结构设计的结构变量。结构中的成员可以是任何一种C的数据结构,甚至可以是其它结构。介绍花括号后的分号表示结构设计定义的结束。标记名是可选的。

14.2 定义结构变量

struct book library编译器会创建一个变量library。编译器使用book模版为该变量分配空间:一个具有MAXTITIL个元素的char数组等。这些存储空间是以一个名字library被结合在一起的。struct book所起作用就像int和float类似。

14.2.1 初始化结构

struct book library={“the pirate”,”rense vio”,1.95};简而言之,使用一个用花括号括起来的、逗号分隔的初始化项目进行初始化。如果初始一个具有静态存储时期的结构,初始化项目列表中的值必须是常量表达式。

14.2.2 访问结构成员

用结构成员运算符点(.)可以访问结构成员。例如library.value。

14.2.3 结构的指定项目初始化

C99支持结构的指定初始化项目,其语法与数组的指定初始化项目相似。例如struct book library={.value=10.99};并且指定顺序可以任意。另外对特定成员的最后一次赋值是它实际获得的值。

14.3 结构数组

当使用一个含有大量个结构的数组,可能会因为该数组是一个自动存储类的对象,将这些信息放置在堆栈里,要求一大块存储空间,可能会因为编译器使用了一个太小的默认大小堆栈空间导致运行错误。为满足需要,可以使用编译器把堆栈大小设置为10000或者可以将数组设为静态的或外部的(这样就不会把数组放在堆栈里)。

14.3.1 声明结构数组

声明一个结构数组和声明其它任何类型的数组一样。struct book library[MAXBKS];这条语句声明library为一个具有MAXBKS个元素的数组,数组的每个元素都是book类型的结构。因此library.[num]是一个book结构。library本身不是结构名,它是元素类型为struct book结构的数组名。

14.3.2 标识结构数组的成员

在结构名后加一个点运算符,然后是成员名。例如library[0].value;一个经典的判断条件while(count<MAXBKS&&gets(library[count].title)!=NULL&&library[count].title[0]!=’\0′)注意键入下列信息12.50[enter]这个语句传送了下面的字符序列12.50\n因此添加while(getchar()!=’\n’) continue;清空输入行

14.4 嵌套结构

stuct names{char first[LEN]; char last[LEN];};struct guy{struct names handle; char job[LEN];float income;};struct guy fellow={{“Ewen”,”Villard”},”salmon”,58112.00};对嵌套结构的访问fellow.handle.first.

14.5 指向结构的指针

14.5.1 声明和初始化结构指针

struct guy *him;如果barney是一个guy类型的结构,可以这样him=&barney;和数组不同,一个结构的名字不是该结构的地址,必须使用&运算符。在一些系统中,结构的大小有可能大于它内部各成员大小之和,那是因为系统对结构的对齐存储需求会导致缝隙。

14.5.2 使用指针访问成员

第一、使用一个新运算符:-> 例如him->income 不能使用him.income 因为him不是一个结构名第二、如果him=&barney,那么*him=barney,可以使用(*him).income 必须使用圆括号,因为.运算符比*的优先级更高。

14.6 向函数传递结构信息

14.6.1 传递结构成员

只要结构成员是具有单个值的数据类型,就可以把它作为参数传递给一个接受这个特定类型的函数。如果想让被调函数影响调用函数中的成员值,可以传递成员地址。也可以定义函数原型double sum(const struct guy *me); 通过sum(&barney)来调用。也可以用double sum(struct guy me); 通过sum(barney)来调用。

14.6.2 其它结构特性

现在C允许把一个结构赋值给另一个结构,不能对数组这么做。结构不仅可以作为参数传递给函数,也可以作为函数返回值返回。

14.6.3 结构,还是指向结构的指针

把指针作为参数的方法优点是:能够兼容老版本的C,切执行起来速度块,只须传递一个单个地址。缺点是缺少对数据的保护。不过可以通过限定词const来解决。把结构作为参数的方法优点是:函数处理的是原始数据的副本,保护了数据安全,程序风格也清晰。缺点是早期C可能不能处理,并且浪费时间和空间。通常程序员为了追求效率而使用结构指针作文函数参数,虚拟主机,等你更需要保护数据时指针使用const限定词,传递结构值是处理小型结构最常用的方法。

14.6.4 在结构中使用字符数组还是字符指针

因为结构使用指针,但是没有初始化,以后使用的过程中,可能覆盖其它地址。所以如果需要一个结构来存储字符串,请使用字符数组成员。

14.6.5 结构、指针和malloc()

在结构中使用指针处理字符串的一个有意义的例子是使用malloc()分配内存,并用指针来存放地址。struct namect{char * fname; char * lname; int letters;};void getinfo(struct namect *pst){char temp[81];gets(temp);pts->fname=(char *)malloc(strlen(temp)+1);strcpy(pts->fname,temp);gets(temp);pts->lname=(char *)malloc(strlen(temp)+1);strcpy(pts->lname,temp);}

14.6.6 复合文字和结构

C99新增的符合文字特性不仅适用于数组,也适用于结构。例如(struct book){“Hello”,”you”,6.99}

14.6.7 伸缩型数组成员(C99)

声明一个伸缩型数组成员的规则:一、伸缩型数组成员必须是最后一个数组成员。二、结构中必须至少有一个其它成员。三、伸缩型数组就像普通数组一样被声明,除了它的方括号内是空的。例如:struct flex{int count;double average;double scores[];};你不能使用scores做任何事情,因为它没分配任何内存空间。C99意图是让你用malloc()来分配足够的空间,以存放struct flex结构的常规内容和伸缩型数组成员需要的任何额外空间。例如想要用scores表示含有5个duoble型数值的数组,那么可以 struct flex *pf;pf=malloc(sizeof(struct flex)+5*sizeof(double));

14.6.8 使用结构数组的函数

例如double sum(const struct funds money[],int n); struct funds jones[2];调用它可以使用sum(jones,N);或者sum(&jones[0],N);

14.7 联合简介我就想是一只草原中被牧童遗忘的羊,

C Primer Plus(十四)

相关文章:

你感兴趣的文章:

标签云: