c语言把链表设置为空号,C语言第09章--结构和联合.doc

union ic

{

int i;

unsigned char ch[2];

};

main()

{ union ic u;

u.i=32767;

printf("u.ch[1]=%X,u.ch[0]=%X\n",u.ch[1],u.ch[0]);

u.i=32768;

printf("u.ch[1]=%X,u.ch[0]=%X\n",u.ch[1],u.ch[0]);

}

结果为:

u.ch[1]=7F,u.ch[0]=FF

u.ch[1]=80,u.ch[0]=0

由此可知一个int型数据的低字节存放其低8位,而高字节存放其高8位。这正是利用了无符号字符数组ch与整形变量i共享同一块存储空间的特点。

在使用联合类型数据时要注意以下一些特点:

l 在任一时刻,联合变量只有一个成员有意义,其它成员则无意义。正确地存取联合变量的某个成员是程序设计者的职责。

l 联合变量中有意义的成员即是其最后一次赋值的成员。

l 联合变量的地址和其各成员的地址相同。

l 不能在定义联合变量的同时对其进行初始化。

9.9 枚举类型

枚举类型是ANSI C新标准所增加的。如果一个变量只有几种可能的值,则可以定义其为枚举类型。所谓“枚举”是指将变量的可能取值一一列举出来,变量的值只限于列举出来的值的范围。定义枚举类型用保留字enum。其定义形式为:

enum [枚举类型名] {枚举常量名[=整形值], ...} [变量列表];

例如:

enum weekday {sun,mon,tue,wed,thu,fri,sat};

定义了一个枚举类型weekday。该枚举类型有7个枚举常量,分别是sun、mon、tue、wed、thu、fri和sat。和结构或联合类型一样,我们可以用枚举类型来定义相应的枚举变量。如:

enum weekday d1,d2; (enum不能省略)

定义了两个weekday型的枚举变量d1和d2,它们的值可以是sun到sat之一。例如:

d1=mon;

d2=sun;

我们也可以直接定义枚举变量,例如:

enum {red,yellow,blue} color1,color2;

同样,也可以同时定义枚举类型及枚举变量,例如:

enum color {red,yellow,blue} color1,color2;

枚举类型实际上是一个int型常量的“集合”。亦即每一个枚举常量实际上是一个int型常量,而枚举变量实际上是一个int型变量。使用枚举类型时要注意以下几点:

1) 上述的枚举常量sun,mon,red,blue等是int型常量,所以不能对它们赋值。

2) 枚举常量的值满足:第i个枚举常量的值 = 第i-1个枚举常量的值 + 1 。

3) 按C的缺省规定,第一个枚举常量的值为0。

4) 在定义枚举类型时,可以指定每个枚举常量的值。如不指定,则按第2条的规定决定其值。

5) 使不同的枚举常量具有不同的值是程序员的责任。

6) 枚举变量同int型变量,同样,使其值落在合法的枚举常量的范围之内也是程序员的责任。

7) 对枚举变量可进行同int型变量一样的运算和操作。

[例9.6]

#include enum color {red=3,green,blue=4};

enum workday {mon,tue,wed=7,thu,fri};

main()

{ enum color c1,c2;

enum workday d1,d2;

c1=red;

c2=++c1;

d1=mon;

d2=wed;

printf("c1=%d,c2=%d\n",c1,c2);

printf("d1=%d,d2=%d\n",d1,d2);

printf("red=%d,green=%d,blue=%d\n",red,green,blue);

printf("mon=%d,tue=%d,wed=%d,thu=%d,fri=%d\n",mon,tue,wed,thu,fri);

}

结果为:

c1=4,c2=4

d1=0,d2=7

red=3,green=4,blue=4

mon=0,tue=1,wed=7,thu=8,fri=9

使用枚举类型及枚举变量的目的是增加C程序的直观性和易读性。

9.10 用typedef定义类型

在C语言中,还可以用typedef来定义一个新的“类型名”。例如:

typedef int INTEGER;

就定义了一个新的类型名“INTEGER”,即使INTEGER与int成为同义词。此后 INTEGER 就能用在类型int能出现的任何地方,且作用完全相同。例如:

INTEGER i1,i2; 等价于 int i1,i2;

INTEGER a[10],*p; 等价于 int a[10],*p;

同样,

typedef char *STRING;

则定义了一个新类型名“STRING”,且其和类型(char *)成为同义词,即STRING为字符指针类型。以后我们就可以用STRING来定义字符指针变量。例如:

STRING p,lines[MAX_LINES]; 等价于 char *p,*lines[MAX_LINES];

注意,用typedef定义的新类型名并不是紧跟在保留字typedef之后,且具体的语法也不太容易用一个语法表达式来刻画。我们可以这样来描述typedef的用法:

如果要定义一个新类型名,则首先定义一个与之同名的“同类型”的变量,然后再在该“变量的定义”前面加上保留字typedef,则该“变量”名便上升成为“类型”名。例如:

struct {

int month;

int day;

int year;

} DATE;

定义了一个“结构变量”DATE,而

typedef struct {

int month;

int day;

int year;

} DATE;

则定义了一个相应的“结构类型”DATE。且

DATE date1,date2;

等价于

typedef struct {

int month;

int day;

int year;

} date1,date2;

可见,通过用typedef定义新类型可以简化程序的书写并提高程序的易读性。而程序的“易读性”是现代程序设计最重要的特性之一。他对程序的维护、功能扩充、移植等都具有举足轻重的作用。从前面的C的预处理程序到现在的类型名定义,可以看出C在这方面比别的程序设计语言有独到的设计,这也是C之所以风靡全球的原因之一。

为了和C的保留字以及变量名相区别,用typedef定义的类型名通常总是用大写英文字母来命名。但必须强调的是,typedef并不是“创建”了一个新的数据类型,它只是为现有的某些数据类型起了一个新的名字而已,并没有扩展C的数据类型。

typedef与#define有相似之处。但事实上,它们二者是不同的。主要区别在:

l typedef是C的“保留字”,即不能用其来命名变量等对象,但define并不是C的“保留字”,我们可以用其来命名变量,只不过不提倡这样做而已。

l #define是在预处理时处理的,它只能做简单的字符串替换,而typedef是在编译时处理的。实际上它并不是做简单的字符串替换,例如:

typedef int INTEGER; 在某些情况下可代之以 #define INTEGER int

typedef int NUM[10];

却无法以任何#define代之。

使用typedef有两个主要的理由:其一是有利于程序移植。如果把typedef用于可能与机器有关的数据类型,则在程序移植时仅需改变typedef,从而减少大量的程序修改工作。第二个原因是使用typedef能为程序提供更多的可读信息,用一个适当的符号名表示一个复杂的结构类型会增强程序的可读性。

习 题

9.1 填空

① C语言提供了三种构造数据类型,它们是 、 和 。

② 使几个不同类型的量共享同一段内存的结构,称为“ ”。

9.2 单项选择

① 说明语句

struct student

{

int num;

char name[20];

char sex;

};

定义了( )。

(1) 结构类型student (2) 联合类型student

(3) 结构变量student (4) 数组类型student

② typedef struct

{

int month;

int day;

int year;

} DATE;

定义了( )

(1) 宏名为DATE (2) 结构变量DATE

(3) 联合类型DATE (4) 新类型名DATE

③ typedef struct

{

int month;

int day;

int year;

} *PDATE;

定义了( )。

(1) 结构类型PDATE (2) 联合类型PDATE

(3) 宏PDATE (4) 指向结构的指针类型PDATE

④ union

{

int i;

char ch;

float f;

} a;

定义了( )。

(1) 联合类型a (2) 联合变量a

(3) 结构类型a (4) 结构变量a

⑤ 若定义

student node

{

int key;

struct node *next;

} a;

则引用结构变量a的next成员需要采用( )。

(1) a.next (2) node.next

(3) a->next (4) node->a.next

⑥ 若定义

enum color{red,yellow,blue,white};

那么yellow的值为( )。

(1) 0 (2) 1 (3) 2 (4) "yellow"

⑦ 若定义

enum color{red=2,yellow,blue,white};

那么blue的值为( )。

(1) 0 (2) 2 (3) 2 (4) 无定义

9.3 结构和联合有何区别?

9.4 设每个学生的数据包括学号、姓名、年龄、五门课的成绩。试说明相应的结构类型student。

9.5 设有50个学生的档案,数据结构同上,编制一个程序,它读入每个学生的档案数据,然后计算出每个学生的平均成绩和总成绩。最后将所有平均成绩高于总平均成绩的学生档案输出。

9.6 电话簿中每个人的数据由姓名和电话号码两项构成,试设计一个结构数组来表示电话簿,读入每个人的数据并按电话号码从小到大排序。然后等待用户输入一个电话号码,如果电话簿中有该号码,则输出相应用户的姓名,否则输出此号码是空号的信息。

9.7 建立一个链表,每个结点包括姓名和年龄。然后按年龄从小到大排序。

9.8 学生的数据包括学号、姓名、性别、民族、出生日期、家庭住址及本人简历。其中出生日期和本人简历又分别是一个结构,分别由年、月、日和起止年月、简历、证明人构成。试说明相应的结构。

9.9 要用计算机对图书馆中的图书进行管理,一本图书的信息包括:书名、作者、摘要、索引号、ISBN号、出版社、出版日期和页数。其中出版社包括出版社名称和地址。鉴于书和出版社之间是多对一的关系,为了减少数据的冗余,应该如何设计所需要的结构?

9.10 typedef int INTEGER;和宏替换#define INTEGER int有何区别?

9.11 枚举类型在C内部是如何表示的?引入它的主要目的是什么?

9.12 定义复数类型并分别写出完成复数加、减、乘、除运算的函数。

9.13 建立一个函数,它建立由siz个整数组成的动态数组,并能从键盘上读入数据,初始化这个数组。函数成功返回1,否则返回0。

9.14 设计一个函数,其参数是一个一维数组名和数组中元素的个数,函数的返回值是数组元素的个数。若数组元素的数据类型为

struct elem{

int key; /* 查询关键字 */

int freq; /* key的查询频率 */

}

设计这个函数,从键盘接收一个整数,在数组中查询该数是否存在,如果没有,就把它做为一个新项存入数组的key中。用freq记录查询频率。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值