一、主要内容
关键字:struct、union、typedef
运算符:. ->
什么是C结构,如何创建结构模板和结构变量
如何访问结构的成员,如何编写处理结构的函数
联合和指向函数的指针
二、生活中的实例
书店老板要去打印一份图书目录。她想打印每本书的各种信息,如作者,书名,出版社、价格等等,这些项目可以存放在不同的数组中,可是用这么多数组表示有点麻烦和繁琐了,因此如果能把图书目录的信息都包含在一个数组里更好,其中每个元素包含一个本书的相关信息
C结构就能满足这个需求
实例
#include <stdio.h> #include <string.h> char * s_gets(char * st,int n); #define MAXTITL 41 /*书名的最大长度+1*/ #define MAXAUTL 31 /*作者姓名的最大长度*/ struct book { //结构模板:标记是book char title[MAXTITL]; char author[MAXAUTL]; float value; }; //结构模板结束 int main(void) { struct book library; //把library声明为一个book类型的变量 printf("Please enter the book title.\n"); s_gets(library.title,MAXTITL); //访问title部分 printf("Now enter the author.\n"); s_gets(library.author,MAXAUTL); printf("Now enter the value.\n"); scanf("%f",&library.value); printf("%s by %s: $%.2f\n",library.title,library.author,library.value); printf("%s: \"%s\" ($%.2f)\n",library.author,library.title,library.value); printf("Done.\n"); } char * s_gets(char * st,int n) { char * ret_val; char * find; ret_val = fgets(st,n,stdin); if (ret_val) { find = strchr(st,'\n'); if (find) *find = '\0'; else while (getchar() != '\n') continue; } return ret_val; }
输出的结果为:
PS D:\Code\C\结构> cd "d:\Code\C\结构\" ; if ($?) { gcc struct.c -o struct } ; if ($?) { .\struct } Please enter the book title. Now enter the author. 罗贯中 Now enter the value. 99.9 三国演义 by 罗贯中: $99.90 罗贯中: "三国演义" ($99.90) Done.
程序中创建的结构有3部分,每个部分都称为成员(member))或字段(field)。这3部分中,一部分储存书名,一部分储存作者名,一部分储存价格。下面是必须掌握的3个技巧:
为结构建立一个格式或样式;
声明一个适合该样式的变量;
访问结构变量的各个部分。
三、建立结构声明
结构声明(structure declaration)描述了一个结构的组织布局。声明类似下面这样:
struct book { //结构模板:标记是book char title[MAXTITL]; char author[MAXAUTL]; float value; };
该声明描述了一个由两个字符数组和一个float类型变量组成的结构。该声明并未创建实际的数据对象,只描述了该对象由什么组成。(有时,我们把结构声明称为模板,因为它勾勒出结构是如何储存数据的.如果读者知道C++的模板,此模板非彼模板,C++中的模板更为强大。)我们来分析一些细节。首先是关键字struct,它表明跟在其后的是一个结构,后面是一个可选的标记(该例中是 book),稍后程序中可以使用该标记引用该结构。所以,我们在后面的程序中可以这样声明:
struct book library;
这把library声明为一个使用book 结构布局的结构变量。
四、定义结构变量
结构有两层含义。一层含义是“结构布局”,刚才已经讨论过了。结构布局告诉编译器如何表示数据,但是它并未让编译器为数据分配空间。下一步是创建一个结构变量,即是结构的另一层含义。程序中创建结构变量的一行是:
struct book library;
编译器执行这行代码便创建了一个结构变量library。编译器使用book模板为该变量分配空间:个内含MAXTITL个元素的char数组、一个内含MAXAUTL个元素的char数组和一个float类型的变量。这些存储空间都与一个名称library结合在一起
在结构变量的声明中,**struct book所起的作用相当于一般声明中的int或float。**例如,可以定义两个struct book类型的变量,或者甚至是指向struct book类型结构的指针:
struct book doyle, panshin, * ptbook;
结构变量 doyle和 panshin中都包含title、author和 value部分。指针 ptbook可以指向doyle,panshin或任何其他book类型的结构变量。从本质上看, book结构声明创建了一个名为structbook的新类型。
就计算机而言,下面的声明:
struct book library;
是以下声明的简化:
struct book { char title [ MAXTITL]; char author [AXA0TL]; float value; }library; //声明的右右花括号后跟变量名
换言之,声明结构的过程和定义结构变量的过程可以组合成一个步骤。如下所示,组合后的结构声明和结构变量定义不需要使用结构标记:
struct { //无结构标记 char title [ MAXTITL]; char author [ MAXAUTL]; float value; } library;
然而,如果打算多次使用结构模板,就要使用带标记的形式;在这个例子中,并未初始化结构变量。
4.1 初始化结构
初始化变量和数组如下:
int count = 0 ; int fibo [ 7] = {0,1,1,2,3,5,8 };
结构变量是否也可以这样初始化?是的,可以。初始化一个结构变量(ANSI之前,不能用自动变量初始化结构:ANSI之后可以用任意存储类别)与初始化数组的语法类似!
简而言之,我们使用在一对花括号中括起来的初始化列表进行初始化,各初始化项用逗号分隔
因此,**title成员可以被初始化为一个字符串,value 成员可以被初始化为一个数字。**为了让初始化项与结构中各成员的关联更加明显,我们让每个成员的初始化项独占一行。这样做只是为了提高代码的可读性,对编译器而言,只需要用逗号分隔各成员的初始化项即可。
不是我说,这本书写的真好!
4.2 访问结构成员
结构类似于一个“超级数组”,这个超级数组中,可以是一个元素为char类型,下一个元素为forat类型,下一个元素为int 数组。可以通过数组下标单独访问数组中的各元素,那么,如何访问结构中的成员﹖使用结构成员运算符——一点( .)访问结构中的成员。
例如,library.value即访问library的value部分。可以像使用任何float类型变量那样使用library.value。与此类似,可以像使用字符数组那样使用library.title。因此,上面的程序中有 s_gets(library.title,MAXTITL);和scanf("“号f”,&library.value);这样的代码。
C语言不亏是基础,如果首先学会C语言,学面向对象这种访问方式应该更好理解了!
学过其他语言应该会很好理解,就像Java中访问类中的方法也是类名.方法名()