C Primer Plus: 第十四章 结构和其他数据形式
14.2 建立结构声明
struct book {
char title;
char author;
int value ;
};
struct book library;
该声明只描述了该对象由什么组成,称之为模板。(区别C++中的模板) 右花括号后面的分号是必需的,表示结构布局定义结束。可以将声明放在所有函数的外部,也可以放在一个函数定义的内部。如果放在函数内部,则它的标记就只限于函数内部使用。 声明结构变量时,struct不可以省略,在C++中可以省略。
14.3 定义结构变量
struct book library={
"the book name" ,
"Renene" ,
14
};
使用在一对花括号括起来的初始化列表进行初始化,各初始化项用逗号分隔。或者使用点运算符和成员名标识特定的元素。
struct book sur = {.value = 10 };
struct book git = {
.value = 25 ,
.author = "Jame',
.title = " abs"
};
自动储存类别对象的信息被储存在栈(stack)中。
14.6 指向结构的指针
选择指针的原因:
指向结构的指针通常比结构本身更容易操控。 传递指针通常更有效率。 一个结构的大小可能大于它的各成员大小之和。这是因为系统对数据进行校准的过程中产生了一些“缝隙”。例如,有些系统必须把每个成员都放在偶数地址上,或4的倍数的地址上。在这种系统中,结构的内部就存在未使用的“缝隙”。 如何选择是使用结构指针还是结构:
把大型结构传递给函数,而函数只使用一两个成员时————传递指针或者只传递函数所需的成员更合理. 对于小型结构,使用按值传递结构。
14.7 其他结构特性
现在的C允许把一个结构赋值给另一个结构,但是数组不能这样子做。 赋值时,会把结构的每一个成员的值都赋给另一个成员。即使成员是数组,也能完成赋值。 可以把一个结构初始化为相同类型的另一个结构。
伸缩型数组成员:
第一个特性是,该数组不会立即存在。 第二个特性是,使用这个伸缩性数组成员可以编写合适的代码,就好像它确实存在并具有所需数目的元素一样。 规则:
伸缩型数组成员必须是结构的最后一个成员; 结构中必须至少有一个成员; 伸缩数组的声明类似于普通数组,只是它的方括号是空的。
struct flex
{
int count;
double ave;
double scores[];
}
struct flex * pf;
pf = malloc (sizeof (struct flex)+5 *sizeof (double ));
处理要求:
不能用结构进行赋值或拷贝。这种做法只能拷贝除伸缩型数组成员以外的其他成员。确实要进行拷贝,应使用memcpy()函数。 不要以按值方式把这种结构传递给结构。原因如1,需要把结构的地址传递给函数。 不要使用带有伸缩数组成员的结构座位数组成员或另一个结构的成员。
14.8 把结构内容保存到文件中
使用fread()和fwrite()函数读写结构大小的单元。
fwrite(&primer, sizeof (struct book), 1 , pbooks);
fread()函数从文件中拷贝一块结构大小的数据到&primer指向的位置。简而言之,这两个函数一次读写整个记录,而不是一个字段。 rewind(pbook)函数确保文件指针位于文件开始处。为读文件做好准备。
14.10 联合简介
联合(union)是一种数据类型,它能在同一个内存空间中存储不同的数据类型(不是同时储存) 典型用法是,设计一种表示以储存既无规律、事先也不知道顺序的混合模型。每个联合可以储存各种数据类型。 创建联合和创建结构的方式相同,需要一个联合模板和联合变量。
union hold{
int digit;
double bigfl;
char letter;
};
union hold fit;
union hold save[10 ];
fit.letter = 'h' ;
fit.digit = 23 ;
fit.bigfl = 2.0 ;
以上声明的联合只能储存一个int类型的值或一个double类型的值或char类型的值。即使有足够空间,也只能储存一个值。 编译器分配足够的控件以便它能储存联合声明中占用最大字节的类型。
14.11 枚举类型
可以用枚举类型声明符号名称来表示整型常量。实际上,enum常量是int类型。 枚举类型的目的是提高程序的可读性。它的语法与结构的语法相同。 常用于case语句中。
enum spectrum{red, orange, yellow, green, blue, violet};
enum spectrum color;
color = blue;
if (color == yellow)...
默认情况下,枚举列表中的常量被赋予0,1,2等 在枚举声明中,可以为枚举常量指定整数值:
enum levels {low=100 , medium=500 , high=2000 };
如果只给一个枚举常量赋值,没有对后面的枚举常量赋值,那么后面的常量会被赋予后续的值。
typedef简介
利用typedef可以为某一类型自定义名称。目的是为经常出现的类型创建一个方便、易标识的类型名。 这方面与#define类似,但两者有3出不同:
与#define不同,typedef创建的符号名只受限于类型,不能用于值 。 typedef由编译器解释,不是预处理器。 在其受限范围内,typedef比#define更灵活 例:
typedef unsigned char BYTE ;
BYTE x, y[10 ];
#define STRING char *
STRING name, sing;
char * name, sign;
14.14 函数和指针
可以声明一个指向函数的指针,传递给另一个函数,告诉该函数要使用哪个函数。 指向函数的指针中储存着函数代码的起始处的地址。 声明一个函数指针时,必须声明指针指向的函数类型。为指明函数类型,要指明函数签名,即函数的返回类型和参数类型。
void ToUpper(char *);
void ;
要声明一个指向特定类型函数的指针,可以先声明一个该类型的函数,然后把函数名替换成(*pf)形式的表达式。然后pf就成为指向该类型函数的指针。 调用方法: 1.(*fp)(arg); 2.fp(arg); 作为函数参数的原型:
void show(void , char * str);
ANSI C是什么
第一个C标准由ANSI发布,ISO进行完善 ANSI C ISO C Standard C 都是C语言的一些标准