结构
结构是一个或多个变量集合,这些变量可能为不同的类型,为了处理的方便而将这些变量组织在一个名字之下。(某些语言将结构称为“记录”,比如Pascal语言。)
ANSI标准在结构方面最主要的变化是定义了结构的赋值操作——结构可以拷贝、赋值、传递给函数,函数也可以返回结构类型的返回值。
结构的基本知识
struct point
{
int x;
int y;
};
struct point pt;
struct { ... } x, y, z;
struct后面的名字是可选的,称为结构标记。
结构标记用于为结构命名。
结构中定义的变量称为成员。
结构成员,结构标记和普通变量(即非成员)可以采用相同的名字,它们之间不会冲突,因为通过上下文分析总可以总可以对它们进行区分。
结构声明后带变量表,需为其分配空间.不带,则不必为其分配空间。
结构与函数
结构的合法操作只有几种:作为一个整体复制和赋值,通过&运算符取地址,访问其成员。
传递结构的方法:
一是分别传递各个结构成员
二是传递整个结构
三是传递指向结构的指针
struct point* pp;
将pp定义为一个指向struct point类型对象的指针。
(*pp).x中圆括号是必须。
*pp.x等价于*(pp.x),因为x不是指针,所以该表达式是非法的。
结构指针使用频度非常高,为了使用方便,C语言提供了另一种简写形式。
设p是一个指向结构的指针,可用
p->结构成员
运算符. 和 -> 都是从左到右结合
结构数组
struct key
{
char *word;
int count;
}
keytab[]
=
{
"auto", 0,
"break", 0,
"case", 0,
"char", 0,
"const", 0,
"continue", 0,
"default", 0,
/* ... */
"unsigned", 0,
"void", 0,
"volatile", 0,
"while", 0
};
或如下形式
{ "auto", 0 },
{ "break", 0 },
{ "case", 0 },
// 字节单位大小,类型size_t
// 对象可以是变量,数组,结构
// 返回指定对象或类型占用的存储空间字节数
// 对数组对象或类型,统计数组所有元素整体占据的存储空间
sizeof object
// 类型可为基础类型,派生类型,指针
sizeof (type name)
...
指向结构的指针
自引用结构
统计输入中所有单词的出现次数。
一种解决方法是,在读取输入中任意单词的同时,就将它放置到正确的位置,从而始终保证所有单词是按顺序排列的。
另一种是使用二叉树的数据结构。
自引用结构的变体:两个结构相互引用。
表查找
数组的每个元素指向某个链表的表头,链表中的各个块用于描述具有该散列值的名字。如果没有名字散列到该值,则数组元素的值为NULL。
链表中的每一块都是一个结构,它包含一个指向名字的指针、一个指向替换文本的指针以及一个指向链表后继块的指针。
如果指向链表后继块的指针为NULL,则表明链表结束。
类型定义(typedef)
typedef 用来建立新的数据类型名。
如:
typedef int Length;
将Length定义为与 int 具有同等意义的名字。
注意,typedef 中声明的类型在变量名的位置出现,而不是紧接在关键字typedef 之后。
typedef 在语法上类似于存储类extern、static等。
在这里用大写字母作为typedef 定义的类型名的首字母,以示区别。
typedef 可以使程序参数化,以提高程序的可移植性。
typedef 的第二个作用是为程序提供更好的说明性——Treeptr 类型显然比一个声明为指向复杂结构的指针更容易让人理解。
联合
联合是可以(在不同时刻)保存不同类型和长度的对象的变量,编译器负责跟踪对象的长度和对齐要求。
联合提供了一种方式,以在单块存储区中管理不同类型的数据,而不需要在程序中嵌入任何同机器有关的信息。
它类似于Pascal语言中的变体记录。
通过下列语法访问联合中的成员:
联合名.成员
或
联合指针->成员
联合就是一个结构,它的所有成员相对于基地址的偏移量都为0,此结构空间要大到足够容纳最“宽”的成员,并且,其对齐方式要适合于联合中所有类型的成员。
对联合允许的操作与对结构允许的操作相同:作为一个整体单元进行赋值、复制、取地址即访问其中一个成员。
联合只能用其第一个成员类型的值进行初始化。
位字段
在存储空间很宝贵的情况下,有可能需要将对各对象保存在一个机器字中。
一种常见方法是,使用类似编译器符号表的单个二进制位标志集合。
外部强加的数据格式(如硬件设备接口)也经常需要从字的部分位中读取数据。
程序中的每个标识符都有与之相关的特定信息,例如,它是否为关键字,它是否是外部的且(或)是静态的,等等。
对这些信息进行编码的最简洁的方法就是使用一个char 或 int 对象中的位标志集合。
C语言提供了两一种可替代的方法,即直接定义和访问一个字中的位字段的能力,而不需要通过按位逻辑运算符。
位字段(bit-field),或简称字段,是“字”中相邻的集合。
“字”(word)是单个的存储单元,它同具体的实现有关。
学习参考资料:
《C程序设计语言》第2版 新版