2. 记录在C语言中的使用
在C语言中创建一个记录,需要执行如下两个步骤:
(1) 定义一个新的结构类型。
在声明变量前,必须先定义一个新的结构类型。类型定义指明了记录是由哪些字段组成,字段的名称,以及字段中信息的类型。这种结构类型为所有具有新类型的对象定义了一个模式,但并不分配任何存储空间。
(2) 声明新类型的变量。
数据值存入其中。

2.1 定义一个结构类型
在C语言中定义结构,本书采用上述句法框中的定义方式。新类型的名称在最后一行出现,之前为组成该结构的字段说明。字段由一系列的字段声明定义,这些声明和函数中的变量声明类似。
例如,下列代码定义了名为employeeT的结构类型,用以表示雇员记录:
typedef struct{
string name;
string title;
string ssnum;
double salary;
int withholding;
} employeeT;
2.2 声明结构变量
定义了一个新类型后,下面的一步就是声明该类型的变量。
例如,有了employeeT这个类型,就可以通过下列代码定义该类型的一个变量emp:
employeeT emp;
2.3 记录选择
当声明了变量emp后,就可以用这个名称指代该记录。
有时需要打开该记录结构并对单个字段进行操作。如,需要引用记录中的某一个字段,这需要写下整个记录的名称,后面跟符号“.”以及该字段的名称。
因此,为引用存储在emp中雇员的职位,需要以下代码:
emp.title
在此,符号“.”称为“点”,通过点运算符选择字段被称为记录选择(record selection)。
2.4 记录初始化
和对待其他类型的变量一样,可以通过赋值的方式对记录变量进行初始化。
点运算符返回一个左值,表示可以对一个记录选择表达式进行赋值。例如,如果执行下列语句:
emp.name = "Ebenezer Scrooge";
emp.title = "Partner";
emp.ssnum = "271-82-8183";
emp.salary = 250.00;
emp.withholding = 1;
将会创建出前面例子中使用的Ebenezer Scrooge的记录。
如果声明的变量为一个静态全局变量,则可以对其内容进行静态初始化。
记录的初始化部分需要按照结构定义中的顺序出现。
因此,可以对一个名为manager的静态全局记录进行声明和初始化,该记录包含了Mr.Scrooge的数据,如下所示:
static employeeT manager = {
"Ebenezer Scrooge", "Partner", "271-82-8183", 250.00, 1
};
2.5 简单记录
为了用单独的实体描述一个点,第一步应定义类型pointT为一组坐标值,如下所示:
typedef struct{
double x, y;
} pointT;
接下来可以编写处理pointT的函数和过程,如下所示的函数将两个坐标结合起来形成一个pointT的值:
pointT CreatePoint(double x, double y) {
pointT p;
p.x = x;
p.y = y;
return p;
}
可以利用下面的代码对一个pointT类型的变量进行初始化:
pointT origin;
origin = CreatePoint(0, 0);
这个例子说明了数组和记录之间的一个重大差别。在C语言中,记录变量是一个左值,而数组变量不是左值。
当将一个记录赋值给另一个记录时,两个记录必须为相同类型。下面的赋值表示rec2中所有字段的内容都是从rec1中相应的字段复制过来的:
rec1 = rec2;
pointT AddPoint(pointT p1, pointT p2) {
pointT p;
p.x = p1.x + p2.x;
p.y = p1.y + p2.y;
return p;
}
记录也可以作为函数的参数进行传递。如果有如下定义的函数AddPoint:
当调用函数Add Point(p1, p2)时,(其中p1,p2都为pointT类型的值),函数返回的点的坐标是p1和p2相应坐标的和。
当调用参数为记录的函数时,记录参数的值就复制到相应的实参。
当函数改变实参的值,或改变某个字段内容时,形参还保留着原来的值。这种处理方式和C语言处理所有参数(除数组以外)一样。
参考
《C语言的科学和艺术》 —— 16 记录