您现在的位置:首页 > 计算机软件及应用 >

程序设计与C语言第8章结构体、共用体及枚举类型-文档资料_图文


第8章 结构体、共用体及枚举类型

第8章 结构体、共用体及枚举类型
8.1 结构体类型 8.2 动态数据结构

8.3 共用体
8.4 位段

8.5 枚举类型

《程序设计C语言》

第8章 结构体、共用体及枚举类型

8.1 结构体类型
8.1.1 结构体变量的定义及初始化

1. 结构体类型的定义
要定义结构体变量,首先要定义结构体类型。结构 体类型定义的一般形式是:

struct[<结构名>]
{ <成员表>; }; <成员表>∷=<分量1>;[<分量2>;…]

<分量>∷=<类型标识符><分量名>
《程序设计C语言》

第8章 结构体、共用体及枚举类型

其中,符号“∷ =” 表示“定义为”,方括号中的
内容是可选的。例如语句 struct date { int year;

int month;
int day; };

《程序设计C语言》

第8章 结构体、共用体及枚举类型

就定义了一个表示日期的结构体类型,类型名为 struct date。它的三个分量的类型均为整型。对结构体 来说,分量的类型可以互不相同,这是它与数组的区 别。数组也是构造类型,但要求其元素具有相同的类 型。再如
struct student

{
unsigned num; char name[10]; int age; float score;

};
《程序设计C语言》

第8章 结构体、共用体及枚举类型

(1)两个结构体变量的定义是分离的,后者可以把 前者作为其分量类型。比如上面已经定义了日期类型, 则可以用它来定义学生类型:

struct student
{ unsigned num; char name[10]; int age;

float score;
struct date birthday; };
《程序设计C语言》

第8章 结构体、共用体及枚举类型

(2)还可以在一个结构体内部直接嵌套定义:
Struct student { unsigned num; char name[10]; int age; float score; struct { int year;

int month;
int day; }birthday;

};
《程序设计C语言》

第8章 结构体、共用体及枚举类型

2.结构体变量的定义
在定义了类型名之后,就可以定义该类型的变量了。 定义结构体变量的方法有三种: (1)如结构体类型已定义好,则可以用来定义变量。如: struct date date1,date2;

struct student stu1,stu2;
注意:在使用结构体类型名时,初学者往往会忽略 保留字struct,其实struct date和struct student都是一个统一 的整体,二者缺一不可。

《程序设计C语言》

第8章 结构体、共用体及枚举类型

(2)定义结构类型的同时直接定义变量,如
struct date { int year; int month;

int day;
} date1,date2; (3)定义结构体类型的同时定义变量,但没有结构名。

《程序设计C语言》

第8章 结构体、共用体及枚举类型

3.结构体变量赋初值
结构体变量可以在定义时赋初值,如语句 structst udent stu1,stu2={63001,″zhang″,18, 642.5}; 就对结构体变量stu2进行了初始化,实际上是用右 边的值对stu2各分量进行初始化,因此提供的初值必须

和相应分量的类型一致。
两个相同类型的结构体变量之间可以进行赋值操 作。如:

stu1=stu2;
则使stu1的各分量具有了和stu2各分量一样的值。

《程序设计C语言》

第8章 结构体、共用体及枚举类型

4. 结构体指针变量的定义
除了定义结构体变量之外,还可定义结构体指针 变量。如: struct student stu1,*p; p是结构体类型指针。像其它类型的指针一样,结

构体指针只有和某个结构体变量发生了联系,即得到
了结构体变量的首地址之后才能被使用。如 p=&stu1;

这样就把 stu1 的首地址,即第一个分量的地址赋
给了p,p于是指向这个结构体变量。

《程序设计C语言》

第8章 结构体、共用体及枚举类型 8.1.2 结构体数组及结构体分量的引用 1.结构体数组 一个结构体变量可以处理一个对象,如果有多个对象,则需 要多个结构体变量,这时应该用结构体数组来处理多个同类型的 对象。例如,定义一个产品类型的数组prod: struct product { unsigned long no; char name[15]; int num; float price; } prod[3];

《程序设计C语言》

第8章 结构体、共用体及枚举类型

定义结构体变量的其它两种方法也可以用来定义结构体
数组。 对结构体数组可以初始化,例如 struct student prod[3]={ {112346,″football″,56,284.5},

{112347,″basketball″,108,256},
{112348,″valleyball″,35,96.4} };

《程序设计C语言》

第8章 结构体、共用体及枚举类型

图8―1 结构体数组的逻辑结构

《程序设计C语言》

第8章 结构体、共用体及枚举类型

2. 对结构体分量的引用
对结构体分量的引用有三种方法:用点运算符引 用法;用指向运算符引用法;对数组元素的分量用下 标加点或指向运算符引用法。下面分别加以说明。 (1)用点运算符引用结构体变量的分量的方法,有 两种引用形式: <结构体变量名>.<分量名> (*<结构体指针>).<分量名>

《程序设计C语言》

第8章 结构体、共用体及枚举类型

即在结构体变量和其分量名之间加一个点运算符。
例如: struct product prod,*p=&prod; 则可有 prod.num=35; /*等价于(*p).num=35;*/ strcpy(prod.name,″football″);

这是对结构体变量 prod的分量进行赋值的运算。这
时prod.num(或(*p).num)、prod.name作为一个独立的变 量使用,可以直接进行输入/输出操作。

《程序设计C语言》

第8章 结构体、共用体及枚举类型

【例8―1】 #include<stdio.h>

struct product
{ unsigned long no; char name[15]; int num;

float price;
};

《程序设计C语言》

第8章 结构体、共用体及枚举类型

main()
{ struct product prod;

prod.no=117364;
prod.num=46; prod.price=287.5 scanf(″%s″,prod.name); printf(″%lu,%s,%d,%f\n″,prod.no,prod.name,prod.num, prod.price); return 0; }
《程序设计C语言》

第8章 结构体、共用体及枚举类型

运行输出:
football 117364,football,46,287.5 注意: name 分量的输入,因它是字符数组,所以 不能用赋值语句直接赋值,只能用字符串处理函数

strcpy或用scanf函数的控制符“%s”控制输入。

《程序设计C语言》

第8章 结构体、共用体及枚举类型

(2) 用指向运算符引用结构体指针所指对象的分量 的方法,是用结构体指针处理结构体的常用形式,其 引用形式为: <结构体指针变量>-><分量名> 指向运算符由两个字符“ -” 和“ >” 组成,它是一

个整体,中间没有空格。例如:
p->no=117368; strcpy(p->name,″basketball″);

《程序设计C语言》

第8章 结构体、共用体及枚举类型

【例8―2】用指针重做例8―1。
#include<stdio.h> struct product

{
unsigned long no; char name[15];

int num;
float price; };

main()
{ struct product prod,*p; 《程序设计C语言》

第8章 结构体、共用体及枚举类型

p=&prod;
scanf(″%lu%s%d%f″,&p->no,p->name,&p->num, &p->price); printf(″%lu,%s,%d,%f\n″,p->no,p->name,p->num, p->price);

return 0;
} 运行输出: 117364 valleyball 75 197.6 117364 ,valleyball, 75, 197.6
《程序设计C语言》

第8章 结构体、共用体及枚举类型

(3) 用下标加点运算符引用结构体数组元素的分量
的方法,其引用形式为: <数组名>[<下标>].<分量名> 注意:下标和数组名紧密相连,不可分离,不能 把下标放在分量名后面。例如: struct product prod[3]; 则 prod[2].price=78.5;是正确的引用, 而 prod.price[2]则是错误的写法。

《程序设计C语言》

第8章 结构体、共用体及枚举类型

【例8―3】建立和输出有3个元素的产品结构体数组,并输出 价格最高的产品的所有信息。
#include<stdio.h> struct product

{
unsigned long no; char name[15];

int num;
float price; struct { int year,month,day; } outdate; } prod[3]; 《程序设计C语言》

第8章 结构体、共用体及枚举类型

main() { int i,j; float max=0;

struct product *p=prod;
puts(″Input prod[3]:\n″); for(i=0;i<=2;i++) scanf(″%lu%s%d%f%d%d%d″, &prod[i].nu,prod[i].name,&prod[i].num,&prod[i].price, &prod[i].outdate.year,&prod[i].outdate.month, &prod[i].outdate.day);
《程序设计C语言》

第8章 结构体、共用体及枚举类型

printf(″the prod[3]array is:\n″);
for(i=0;i<=2;i++) {

print(″%lu,%s,%d,%.2f,&d/%d/%d\n″,
p->no,p->name,p->num,p->price, p->outdate.year,p->outdate.month,p->outdate.day);

p++;
printf(″\n″); }

for(i=0;i<=2;i++)
if(prod[i].price>max) {

《程序设计C语言》

第8章 结构体、共用体及枚举类型

max=prod[i].price;
j=i; } printf(″Element having highest price:\n″); printf(″%lu,%s,%d,%.2f,%d,%d,%d\n″,

prod[j].no,prod[j].name,prod[j].num,
prod[j].price,prod[j].outdate.year, prod[j].outdate.month,prod[j].outdate.day); return 0; }
《程序设计C语言》

第8章 结构体、共用体及枚举类型

运行输出:
Input prod[3]: 11111 aaaaa 89 99.2 2001 11 9

22222 bbbbb 76 100.4 2002 1 8
33333 ccccc 96 187 The prod array is: 11111 aaaaa 89 99.20 2001/11/9 22222 bbbbb 76 100.40 2002/1/8 2002 8 4

33333 ccccc 96 187.00 2002/8/4
Elements having highest price: 33333 ccccc 96 187.00 2002/8/4
《程序设计C语言》

第8章 结构体、共用体及枚举类型

(4) 用指向运算符也可以引用结构体数组元素的分 量,因为对结构体数组可以用指针进行处理,令 p=prod; 则p指向数组prod的第1个元素,p++指向下一个元 素,每个元素又是结构体,仍要用“->”运算符求其分

量。如图8―2所示。

《程序设计C语言》

第8章 结构体、共用体及枚举类型

图8―2 结构体数组的指针处理

《程序设计C语言》

第8章 结构体、共用体及枚举类型

【例8―4】分析下面程序的输出结果。
#include<stdio.h> struct sinl

{
char *s; int i; struct sinl *slp; };

main()
{ static struct sinl a[]=

{{“abcd″,1,a+1},
《程序设计C语言》

第8章 结构体、共用体及枚举类型

{“efgh″,2,a+2},
{“ijkl″,3,a} }; struct sinl *p=a; int i; printf( ″a[0].s=%s\tp->s=%s\ta[2].slp->s=%s\n\n″,

a[0].s,p->s,a[2].slp->s);
for(i=0;i<2;i++) printf(″--a[%d].i=%d\t++a[%d].s[3]=%c\n″, i,--a[i].i, i,++a[i].s[3]);

《程序设计C语言》

第8章 结构体、共用体及枚举类型

printf(“++(p->s)=%s\ta[(++p)->i].s=%s\t″
“a[--(p->slp->i)].s=%s\n″,++(p->s), a[(++p)->i].s,a[--(p->slp->i)].s); return 0; }

运行输出:
A[0].s=abcd --a[0].i=0 --a[1].i=1 p->s=abcd a[2].slp->s=abcd ++a[0].s[3]=e ++a[1].s[3]=i

++(p->s)=bce a[(++p)->i].s=efgh a[--(p->slp->i)].s=ijkl
《程序设计C语言》

第8章 结构体、共用体及枚举类型

p p a[0 ] a[1 ] a[2 ] 总示意图 a[0 ]

a[1 ]

a[2 ]

s 1 slp s 2 slp s 3 slp 内部细节图

a

b c

d \0

e

f

g h \0

i

j

k

l \0

图8―3 结构体中指针的指向 《程序设计C语言》

第8章 结构体、共用体及枚举类型

8.1.3 结构体变量作参数
结构体变量和结构体指针都可以作为函数的参数 及函数的返回值。若形参为结构体变量,实参也为结 构体变量时,则参数传递的是结构体的拷贝,属于函 数的传值调用。但这样做既费时间又费空间。如果把 形参定义成指针类型,就可以解决这两方面的问题。 这样实参传递的是结构体变量的地址,函数中对形参 的处理就是对实参的直接处理。下面的例子说明了这 种情况。

《程序设计C语言》

第8章 结构体、共用体及枚举类型

【例8―5】求两个复数的和与积。
编程思路:复数相加的公式为: (a+bi)+(c+di)=(a+c)+(b+d)i 即两个复数相加结果仍为一复数,结果的实部为原 两个复数的实部之和,结果的虚部为原两个复数的虚部 之和。 复数相乘的公式为: (a+bi)*(c+di)=(ac-bd)+(bc+ad)i

复数可以设计成一个结构体类型。复数相加与相乘
用两个函数表示。复数结构体类型在各个函数中都要使 用,因此把它放到所有函数之外,作为全局类型定义。
《程序设计C语言》

第8章 结构体、共用体及枚举类型

8.1.4 类型名定义typedef
在上面的例子中,我们定义了一个复数类型 struct complex,这是个不能分开的整体,利用这个类型 名可以定义变量、函数值等。但这个类型名很长,稍 不留心就会出错。如果程序中有很多的复数类型的变 量和函数需要定义,书写起来更是不胜其烦。能不能 简单一些呢? 答案是肯定的。 C语言提供了一种机制, 利用保留字typedef就可以用一个简单的名字来代替像

struct complex这样的长序列。

《程序设计C语言》

第8章 结构体、共用体及枚举类型

例如:typedef struct complex COMPLEX;
则 COMPLEX 即是和struct complex等价的类型名, 可以用它定义变量: COMPLEX a,b,c,*pa;这样用起来就方便多了。 用typedef说明类型名的一般形式如下:

typedef <原类型名> <新类型名>
新类型名一般用大写表示,以便与原名在性质上 区别开来,即它不是新创造的类型,而是原类型的代 名词或化身,它代表了原类型。

《程序设计C语言》

第8章 结构体、共用体及枚举类型

说明新类型的方法十分简单,可按下列步骤进行: (1)先定义原类型的变量;

(2)把变量名大写,以示它为新类型名;
(3)在前面加上typedef保留字。

《程序设计C语言》

第8章 结构体、共用体及枚举类型

8.2 动态数据结构
到目前为止我们所使用的数据结构如数组等,其 大小是一开始就定义好的,程序中不能改动,这对内 存的合理使用及某些操作非常不便。而动态数据结构 是一开始并不指定大小,可以随需要不断增加,不用 时随时取消的结构,如链表、堆栈、队列、树等,这 些动态结构在信息科学中非常有用。

《程序设计C语言》

第8章 结构体、共用体及枚举类型

8.2.1 动态分配内存
建立和维护动态数据结构需要进行动态的内存分 配,即在程序执行过程中可以动态地得到内存和回收 内存。动态分配内存的极限是计算机中可用的物理内 存空间。为实现动态分配内存,C语言提供了几个专用 的函数和运算符,它们是函数malloc、calloc、free和运 算符sizeof。

《程序设计C语言》

第8章 结构体、共用体及枚举类型

1. malloc函数
该函数原型为: void *malloc(unsigned size) 功能:在内存中开辟size个字节大小的连续空间。返 回值为该空间的起始地址。若分配不成功,则返回0值。 2. calloc函数 calloc函数的原型为: void *calloc(unsigned n, unsigned size); 功能:在内存中开辟 n 个大小为 size 个字节 ( 共 n*size 字节 ) 的连续空间。 分配不成功,则返回0值。
《程序设计C语言》

。若

第8章 结构体、共用体及枚举类型

图8―4 返回指针的指向 《程序设计C语言》

第8章 结构体、共用体及枚举类型

【例8―6】编一函数strsave,它可接收一个字符串,
然后动态地开辟一个能放得下这个字符串的内存空间, 把接收到的字符串复制到其中,并返回该空间的起始 地址。 #include<stdio.h> #include<stdlib.h> #include<string.h> char * strsave(char*); main( )

《程序设计C语言》

第8章 结构体、共用体及枚举类型 { char*str=″China″,*cp; cp=strsave(srt); printf(″str=%s,cp=%s\n″,str,cp); return 0; } char * strsave(char * s) { char *p; if((p=(char*)calloc(strlen(s)+1,1))! =NULL) strcpy(p,s); return p; } 《程序设计C语言》

第8章 结构体、共用体及枚举类型

运行输出:
str=China cp=China

标准函数calloc分配strlen(s)+1个大小为1的内存空间, 这是因为 strlen 函数统计字符串长度时不包含 ′\0′ 字符, 但在复制字符串中还需要把′\0′加进去,所以分配空间时 要加1。原calloc函数返回的是空类型指针,现在把它强 制转换成char型指针,把该指针值赋给p,再判断p是否 为 NULL(0) ,若不为 NULL ,就调用字符串拷贝函数来

完成拷贝工作。

《程序设计C语言》

第8章 结构体、共用体及枚举类型

8.2.2 链表
链表是用链表指针连在一起的自引用结构 ( 称为 “结点”)的线性集合,如图8―5所示。 其中,head是指向链表第一个结点的指针,通过它 来访问链表。后面的结点是通过它前面结点中的链接 指针来访问的。链表的最后一个结点中的链接指针被 置为NULL(画成反斜杠以表示链尾)。链表中的结点是 在需要时建立的,链表中的数据是动态存储的。

《程序设计C语言》

第8章 结构体、共用体及枚举类型

h ead 15 27 … 99

图8―5 链表的结构 《程序设计C语言》

第8章 结构体、共用体及枚举类型

我们可以把动态的链表和静态的数组作一对比,
以说明它们的特点。 (1) 在数据元素的个数不可预知时,使用链表是合 适的,因为可在需要时增加或减少链表中结点的个数; 数组是在编译时分配内存的,其大小是不可改变的。 (2) 当数组定义得很大以备不时之需时会造成空间 的浪费;链表随用随增,不会造成空间的浪费。

《程序设计C语言》

第8章 结构体、共用体及枚举类型

(3) 对插入和删除操作,用数组费时费力,而链表
可以方便地在合适的位置插入和删除结点,只要把有 关结点的链接指针修改一下即可。

(4) 数组中的元素在内存中是连续存放的,根据相
对于数组的起始位置可以计算出数组元素的地址,所 以可以立即访问到任意位置的数组元素;链表中的结 点不能被立即访问到,因为链表中的结点在逻辑上是 连续的,但在内存中是不连续的。

《程序设计C语言》

第8章 结构体、共用体及枚举类型

下面我们研究链表的建立、插入、删除及输出等操作。
1.建立链表 首先定义链表中结点的类型,它应该是个自引用的 结构体。如 struct node { int data; struct node *next;

};
typedef struct node Node; Node为新类型名。
《程序设计C语言》

第8章 结构体、共用体及枚举类型

先建立只有一个结点的链表,使head、p1、p2都指
向它,如图8―6所示。其操作步骤如下: (1) 产生一个结点,用p1指向它: p1=(Node *)malloc(sizeof(Node)); (2)把p1赋给head和p2: p2=head=p1;

(3)对新结点的数据域输入数据,而把其指针域置
为NULL。

《程序设计C语言》

第8章 结构体、共用体及枚举类型

p2 p1

h ead 8
图8―6 链表的建立

p2 ⑤ 8 ④ 10 ③ ② ①

p1

图8―7 建立两个结点的链表
《程序设计C语言》

第8章 结构体、共用体及枚举类型

2. 输出链表
当链表的头指针为NULL时说明链表是空的,不采 取行动。只有当链表非空时才从链表头部开始,输出 一个结点的值,然后移动指针,再输出下一个结点的 值,…… 直至表尾结束。可用下面的函数完成此项功能。 void printList(Node *h) { Node *p; p=h;

if(h==NULL)

《程序设计C语言》

第8章 结构体、共用体及枚举类型

printf(″list is empty!\n\n″);
else { while(p! =NULL) { printf(″%d->″,p->data);

p=p->next;
} printf(″NULL\n\n″); } }
《程序设计C语言》

第8章 结构体、共用体及枚举类型

3. 插入结点
在一个链表中插入结点,首先要确定插入的位置, 这里要考虑几种情况: (1)空表情况; (2)插在表头;

(3)插在表中;
(4)插在表尾。

《程序设计C语言》

第8章 结构体、共用体及枚举类型

(1)结点插在表头:设原头结点数值为8,把数值为
6的结点插入其中,如图8―8所示。

newp ②

h

6 ①

8

10

12

14

图8―8 结点插入表头 《程序设计C语言》

第8章 结构体、共用体及枚举类型

(2) 结点插在表中间:在上表的基础上插入数值为
9的结点,如图8―9所示。
h p2 p1

6

8 ① n ewp 9

10 ②

12

14

图8―9 结点插入表中间 《程序设计C语言》

第8章 结构体、共用体及枚举类型

(3) 结点插在表尾:在上表基础上插入数值为 16 的
结点,如图8―10所示。插在表尾,意味着在while循环 中以p1=NULL为条件而退出循环。
h p2

6

8

9

10

12

14

① ②

n ewp

① — p2 - > n ex t= n ewp ; ② — ne wp - > n ex t= p 1 ;

16

图8―10 结点插在表尾 《程序设计C语言》

第8章 结构体、共用体及枚举类型

4. 删除结点
从一个链表中删除结点也应考虑几种情况: (1)删除表头结点; (2)删除表中或表尾结点; (3)找不到要删的结点。

《程序设计C语言》

第8章 结构体、共用体及枚举类型

完成该功能的函数中使用了三个工作指针: p1 指
向当前考查结点, p2 指向当前结点的前一结点, temp 指向被删结点。函数如下: Node *delete(Node *h, int value) { Node *p1,*p2,*temp;

if(value==h->data)
{ temp=h;

/*删除表头结点*/

h=h->next; /*解除表头与链表的连接*/ free(temp); /*释放该结点的内存*/ }
《程序设计C语言》

第8章 结构体、共用体及枚举类型

else
{ p2=h; p1=h->next;

while(p1!=NULL&&p1->data!=value)
{ p2=p1; p1=p1->next; /*移到…*/ /*…下一个结点*/

}
if(p1! =NULL) { temp=p1; /*即p1->data==value */

p2->next=p1->next;
free(temp); }

《程序设计C语言》

第8章 结构体、共用体及枚举类型

else
printf(″%d not found\n″,value); } return h; }

《程序设计C语言》

第8章 结构体、共用体及枚举类型

h ②

① — temp = h ; ② — h = h - > n ex t;

temp



8

10

12

14

16

图8―11 删除表头结点

《程序设计C语言》

第8章 结构体、共用体及枚举类型

我们以图示来说明删除结点的操作。 (1) 删 除 表 头 结 点 : 删 除 数 值 为 8 的 结 点 , 如 图 8―11所示。 (2)删除中间结点:删除数值为12的结点,如图 8―12所示。

(3)删除表尾结点:删除数值为16的结点,如图
8―13所示。

《程序设计C语言》

第8章 结构体、共用体及枚举类型

h

p2

temp ①

p1

① — te m p =p1 ; ② — p 2 - > n ex t= p 1 - > n ex t;

8

10 ②

12

14

16

图8―12 删除中间结点 《程序设计C语言》

第8章 结构体、共用体及枚举类型
① — te mp=p 1; ② — p2 -> n ex t=Nu ll;(或p 2-> n ex t=p 1-> n ex t; 因为 p 1指向最后一个结点, 所以 p 1-> n ex t的值为Nu ll)

p2

temp ①

p1

8

10

14 ②

16

图8―13 删除表尾结点 《程序设计C语言》

第8章 结构体、共用体及枚举类型

【例8―7】
#include<stdlib.h> #include<stdio.h>

struct node
{ int data; struct node *next;

};
typedef struct node Node; main()

{ Node *head1,*head2;
int i; head1=create(); 《程序设计C语言》

第8章 结构体、共用体及枚举类型

printf(″The list is follows! \n″);
printList(head1); printf(″Input a integer:\n″);

scanf(″%d″,&i);
while(i! =0) { head2=insert(head2,i); printf(″Input a integer:\n″); scanf(″%d″,&i);

}
printf(″the ordered list as follows:\n″); printList(head2);
《程序设计C语言》

第8章 结构体、共用体及枚举类型

printf(″Input a integer to delete:\n″);
scanf(″%d″,&i); while(i! =0)

{ head2=delete(head2,i);
printf(″Input a integer to delete:\n″); scanf(″%d″,&i); } printf(″the list after delete as follow:\n″);

printList(head2);
return 0; }
《程序设计C语言》

第8章 结构体、共用体及枚举类型

【例8―8】指出下面程序的运行结果。
#include<stdio.h> #include<stdlib.h>

typedef struct node
{ int d; struct node *next;

}t-node;
int t=0; void create(t-node **h)

{
int i; t-node *p; 《程序设计C语言》

第8章 结构体、共用体及枚举类型

scanf(″%d″,&i);
if(i) { p=(t-node *)malloc(sizeof(t-node)); p->d=i+t; t=i;

p->next=NULL;
*h=p; create(&((*h)->next)); } }
《程序设计C语言》

第8章 结构体、共用体及枚举类型

main()
{ t-node *h=NULL, *p; puts(″\n Input integer,0 to end:″);

create(&h);
p=h; printf(″The output is:\n\n″);

while(p)
{ printf(″%d″,p->d);

p=p->next;
} } 《程序设计C语言》

第8章 结构体、共用体及枚举类型

运行输出:
Input integer,0 to end: 22 33 44 0 The output is: 22 55 77

《程序设计C语言》

第8章 结构体、共用体及枚举类型

该程序中定义了一个全局变量t,将它赋初值为0,
在函数调用过程中t的值在不断地变化。 函数create 用以产生链表,其参数是一个指向结构 体的二级指针,因此在调用时实在参数必须是一级指 针的地址。主函数中初始调用时一级指针的内容为 NULL,以后在每次递归调用时都要保证当时的一级指 针的内容均为NULL,这在函数中是通过&((*h)->next) 来实现的,因为在函数递归调用前已有p->next=NULL

和 *h=p 这样的操作,这就使得 (*h)->next 的值为 NULL 。
如图8―14所示。

《程序设计C语言》

第8章 结构体、共用体及枚举类型

h

h

p

*h

Nu ll (调用前)

*h (调用后)

Nu ll

图 8-14

《程序设计C语言》

第8章 结构体、共用体及枚举类型

8.2.3 堆栈
堆栈是一种受限制的链表,即添加和删除操作只 能从一端进行的链表,其结构如图 8-15 所示。进行 操作的这一端称为栈顶。向栈中添加对象只能加在当 前的栈顶上,使它成为新的栈顶对象,这种操作称为 “入栈”或“进栈”。

《程序设计C语言》

第8章 结构体、共用体及枚举类型

进栈

出栈

栈顶

99

栈底

图8―15 堆栈的结构 《程序设计C语言》


8 5

第8章 结构体、共用体及枚举类型

1. 堆栈的类型定义
类型定义如下: struct stackNode {int data; struct stackNode *next;

}
typedef struct stackNode snode; typedef snode *snodep;

《程序设计C语言》

第8章 结构体、共用体及枚举类型

(1) 进栈函数push:
void push(snodep *top, int info) { snodep newp;

newp=(snodep)malloc(sizeof(snode));
if(newp! =NULL) {

newp->data=info;
newp->next=*top; *top=newp;

}
else printf(″%d not inserted, No memory available.\n″,info); } 《程序设计C语言》

第8章 结构体、共用体及枚举类型

把新结点压入栈顶的操作步骤有下列三步:
①调用malloc函数,动态地建立一个新结点,把该 结点的内存地址赋给 newp ,把要压入栈顶的数值 info 赋给newp->data(结点的数值域); ②把栈顶指针(*top)赋给newp->next(结点的指针域),

从而使新结点的指针域指向原来的栈顶结点;
③把newp赋给*top,从而使*top指向新的栈顶结点。 其操作示意图如图8―16所示。

《程序设计C语言》

第8章 结构体、共用体及枚举类型
n ewp * top n ewp ② * top

11

8

11



8

5

5

(a)

(b)

图8―16 push的操作过程 (a)push操作前的栈状态;(b)操作过程 《程序设计C语言》

第8章 结构体、共用体及枚举类型

(2)出栈函数pop:
int pop(snodep *top) { snodep temp; int value; temp=*top; value=(*top)->data; top=(*top)->next;

free(temp);
return value; }
《程序设计C语言》

第8章 结构体、共用体及枚举类型
* top temp ① ② * top

11

11

8

8

5

5

(a)

(b)

图8―17 pop的操作过程

(a)pop操作前的栈状态;(b)出栈过程
《程序设计C语言》

第8章 结构体、共用体及枚举类型

【例8―9】
#include<stdio.h> #include<stdlib.h>

struct stackNode
{ int data; struct stackNode *next; }; typedef struct stackNode Snode;

typedef Snode * Snodep;
void push(Snodep *, int); int pop(Snodep *);
《程序设计C语言》

第8章 结构体、共用体及枚举类型

void prints(Snodep);
void instruction(void); main()

{ snodep stackp=NULL;
int i,v; instruction(); printf(″?″); scanf(″%d″,&i);

while(i! =3)
{ switch(i)
《程序设计C语言》

{

第8章 结构体、共用体及枚举类型

case1:/*进栈操作*/ printf(″Enter an integer\n″); scanf(″%d″,&v);

push(&stackp,v);
prints(stackp); break; case2/*出栈操作*/ if(stackp! =NULL)

printf(“popped value is:%d\n″,pop(&stackp));
prints(stackp); break; default: 《程序设计 C语言》

第8章 结构体、共用体及枚举类型 printf(″Invalid choice\n″); instruction(); break; } printf(″?″); scanf(″%d″,&i); } printf(″End of run\n″); return 0; } void instruction(void) { printf(″Enter choice:\n″

″1.to push a value into stack.\n″
《程序设计C语言》

第8章 结构体、共用体及枚举类型

″2.to pop a value from stack.\n″
″3.to end program\n″); }

void prints(Snodep p)
{if(p==NULL) printf(″The stack is empty.\n\n″);

else
{ printf(″The stack is:\n″); while(p!=NULL)

{ printf(″%d->″,p->data);
p=p->next; } 《程序设计C语言》

第8章 结构体、共用体及枚举类型

printf(″NULL\n\n″);
} } 运行输出: Enter your choice: 1.To push a value into stack 2.To pop a value from stack 3.To end program ?1 Enter an integer 5 The stack is: 5->NULL 《程序设计C语言》

第8章 结构体、共用体及枚举类型

?1
8 The stack is: 8->5->NULL ?1 11 The stack is: 11->8->5->NULL ?2 The popped value is:11

The stack is:
8->5->NULL ?4 《程序设计C语言》

第8章 结构体、共用体及枚举类型

Invalid choice
Enter your choice: 1.to push a value into stack 2.to pop a value from stack 3.to end program

?3
End of run

《程序设计C语言》

第8章 结构体、共用体及枚举类型

8.2.4 队列
队列也是一种受限的链表,即对它增加新结点的 操作只能在其尾部进行,从中删除结点的操作只能在 头部进行,因而它是一种“先进先出(first in,first out,即 FIFO)” 的数据结构。插入和删除的操作分别称为“入 队 (enqueue)” 和“出队 (dequeue)” 操作。因此对队列的 操作需要两个指针,一个指向队列头部 (headp) ,另一 个指向队列尾部 (tailp) 。图 8―18 的队列中箭头的指向

就是从头部指向尾部。

《程序设计C语言》

第8章 结构体、共用体及枚举类型

h eadp

tailp

8

7



18

图8―18 队列的结构 《程序设计C语言》

第8章 结构体、共用体及枚举类型

1. 队列的类型定义
类型定义如下: struct queuenode { int data; struct queuenode *next;

};
typedef struct queuenode Qnode; typedef Qnode *Qnodep;

《程序设计C语言》

第8章 结构体、共用体及枚举类型

2. 入队和出队函数的定义
入队和出队操作都涉及对指针值的改变,因此函数中采用 传引用调用方法,函数的形参定义为二级指针,实参为指针的 地址。 (1)入队函数enqueue: 函数形参是两个指针的指针以及要插入到队列中的值。入 队操作主要有以下六个步骤: ①建立一个新结点,调用malloc 函数开辟内存空间,把新

结点的地址赋给newp;
②把要插入队列中的数值赋给结点的数值域newp->data;

《程序设计C语言》

第8章 结构体、共用体及枚举类型

③对新结点的指针域赋以NULL值(这对插入的每个
结点都要进行,因为新结点是插在队尾,而队尾的指 针域必须是NULL);

④如果原队列为空,则新结点应为队列中的唯一结
点,指向队列头的指针也必须指向它,即把 newp赋给 *headp; ⑤如果原队列不空,则不涉及队列头指针,只对队 尾指针进行操作就可以了,即把newp赋给(*tailp)->next,

则新结点就加入队尾了。
⑥使队尾指针指向新结点,即把newp赋给*tailp。

《程序设计C语言》

第8章 结构体、共用体及枚举类型

* h eadp

* tailp ③

n ewp ① 9 ②

① — ne wp =

② — (* tailp

8

5

7

③ — * tailp =

图8―19 入队操作的过程 《程序设计C语言》

第8章 结构体、共用体及枚举类型

(2)出队函数dequeue:
int dequeue(Qnodep *headp, Qnodep *tailp) {

int value;
Qnodep temp; value=(*headp)->data;

tamp=*headp;
*headp=(*headp)->next; if(*headp==NULL) /*摘除队列头结点*/

*tailp=Null;
free(temp); return value;

/*队列中无结点*/

}
《程序设计C语言》

第8章 结构体、共用体及枚举类型

* h eadp ② ①

* tailp

temp

8

5

7

9

① — te m p =* h ea dp ; ② — *h eadp =* h ea dp -> n ex t;

图8―20 出队操作的过程 《程序设计C语言》

第8章 结构体、共用体及枚举类型

8.2.5 二叉树
前面讨论的数据结构都是线性数据结构,它们的共 同特点是除第一个结点和最后一个结点外,其他结点都 有且只有一个前驱结点和后继结点。树是一种非线性的 数据结构,如图 8―21(a) 所示。在这种数据结构中,除 第一个结点(常称为树根)外,其他结点都有且只有一个 前驱结点;所有的结点(包括根结点)都可以有0个或多个 后继结点。在树结构中,前驱结点又称为“父结点”; 后继结点又称为“子结点”;具有同一个父结点的结点 称为“兄弟结点”;没有子结点的结点称为“叶结点”; 自然,没有父结点的结点即为“根结点”。
《程序设计C语言》

第8章 结构体、共用体及枚举类型

A

A

B

C

D

B

C

E

F

G (a)

D

E (b)

F

G

图8―21 树的结构 (a)普通树;(b)二叉树 《程序设计C语言》

第8章 结构体、共用体及枚举类型

T: T1

A T2

T1 : T1 1

B T12

T1 1: 空 T12 : 空

D 空 E 空 F 空 空 G 空 空

T2 : T2 1

C T2 2

T21 :

T2 2:

图8―22 二叉树的分解
《程序设计C语言》

第8章 结构体、共用体及枚举类型

对二叉树的处理有三种次序:
(1)先根次序:先处理根结点,再处理子结点; (2) 中根次序:先处理根的一棵子树,接着处理根 结点,最后处理另一棵子树。 (3) 后根次序:先处理两棵子树,最后再处理根结

点。

《程序设计C语言》

第8章 结构体、共用体及枚举类型

图8―23 二叉树的结构 《程序设计C语言》

第8章 结构体、共用体及枚举类型

70 50 40 55 80 94 1 00

20

45

51

60

90

图8―24 二叉查找树 《程序设计C语言》

第8章 结构体、共用体及枚举类型

在处理二叉查找树的程序中所用的主要函数是插 入结点函数和遍历结点函数。在插入结点的函数中,因 为要对指针进行修改,所以形参应定义成指针的指针, 而实参是指针的地址。
1.定义二叉查找树的数据类型 类型定义如下:

struct treeNode
{ struct treeNode *leftp; int data; struct treeNode *rightp; };

typedef struct treeNode treeN;
《程序设计C语言》

第8章 结构体、共用体及枚举类型

2.插入结点函数和遍历结点函数的定义 (1)插入结点函数insert如下: void insert(treeN **treep, int value)

{ if(*treep==NULL)
{*treep=(treeN*)malloc(sizeof(treeN)); if(*treep! =NULL) {(*treep)->data=value; (*treep)->leftp=NULL; (*treep)->rightp=NULL; }

else
《程序设计C语言》

第8章 结构体、共用体及枚举类型

printf(″%d not inserted,No memory available\n″,value);
} else if(value<(*treep)->data) insert(&((*treep)->leftp),value);

else if(value>(*treep)->data)
insert(&((*treep)->rightp),value); else printf(″dup″);/*标记重复*/ }
《程序设计C语言》

第8章 结构体、共用体及枚举类型

(2) 遍历结点的函数因遍历的次序不同而有三个,
这三个函数的构成语句都完全一样,差别只在于语句 的次序上。下面以中序遍历为例说明函数的构成:

void inorder(treeN *treep)
{ if(treep! =NULL) { inorder(treep->leftp); /*遍历左子树*/ printf(″%3d″,treep->data); /*输出根结点*/ inorder(treep->rightp); /*遍历右子树*/ } }
《程序设计C语言》

第8章 结构体、共用体及枚举类型

【例8―10】
#include<stdio.h> #include<stdlib.h> #include<time.h> Struct treeNode

{ struct treeNode *leftp;
int data; struct treeNode *rightp; }; typedef struct treeNode treeN;
《程序设计C语言》

第8章 结构体、共用体及枚举类型

void insert(treeN**, int);
void inorder(treeN*); void preorder(treeN*);

void postorder(treeN*);
main() {

int i,item;
treeN *rootp=NULL; srand(time(NULL));

printf(″The number being placed in the tree are:\n″);
for(i=1;i<=10;i++) { item=10+rand()%41;

printf(″%3d″,item);
《程序设计C语言》

第8章 结构体、共用体及枚举类型

insert(&rootp, item);
} printf(″\n\nThe preorder traversal is:\n″);

preorder(rootp);
printf(″\n\nThe inorder traversal is:\n″); inorder(rootp); printf(″\n\nThe postorder traversal is:\n″); postorder(rootp);

return 0;
} void postorder(treeN *treep)
《程序设计C语言》

第8章 结构体、共用体及枚举类型

{ if(treep! =NULL)
{ postorder(treep->leftp); postorder(treep->rightp);

printf(″%3d″,treep->data);
} } void preorder(treeN *treep) {

if(treep! =NULL)
{ printf(″%3d″,treep->data); preorder(treep->leftp);
《程序设计C语言》

第8章 结构体、共用体及枚举类型

preorder(treep->right);
} } void inorder(treeN *treep) {if(treep! =NULL)

{ inorder(treep->leftp);
printf(″%3d″,treep->data); inorder(treep->rightp); } }
《程序设计C语言》

第8章 结构体、共用体及枚举类型

8.3 共用体
程序中的变量有两种情况:一种是变量之间互不
相关,都有自己的名字和存储空间;另一种是变量之 间是相关的,它们虽然有各自的名字,但共用同一段

内存空间,让这段空间轮流地为它们服务,这样就可
以减少空间的浪费。让这些变量共用同一内存空间的 方法是把它们组织成共用体。共用体是一种新的数据 类型,它的定义与结构体的定义相似: union <共同体名> {成员列表};

《程序设计C语言》

第8章 结构体、共用体及枚举类型

例如:
union number { int x; float y;
p x c y

char c;
};

图8―25 共用体对内存空间的占用 《程序设计C语言》

第8章 结构体、共用体及枚举类型

在这个共用体类型中定义了三个分量,它们的类
型各不相同,但都占用同一内存空间,由于各个分量 类型不同,所以这段空间应足够大,以便能放下最大 的分量,所以这个共用体要占用4个字节空间,因为其 中的分量 y 是 float 类型,是最长的类型,占 4 字节,如 图8―25所示。

《程序设计C语言》

第8章 结构体、共用体及枚举类型

【例8―11】
#include<stdio.h> main() { union number { int i; long l; }a; a.i=-32768; printf(″int:%d,l ong:%ld\n″,a.i, a.l);

a.l=65536;
printf(″int:%d,long:%ld\n″,a.i.,a.l); return 0;

}
《程序设计C语言》

第8章 结构体、共用体及枚举类型

运行输出:
int:-32768, long:32768 int:0, long:65536 共用体类型和结构体类型可以互相嵌套,即可以 互为对方分量的类型。一般的使用是在结构体中设一

个类型标志分量,由该标志确定当前对共用体中哪个
分量进行处理。

《程序设计C语言》

第8章 结构体、共用体及枚举类型

【例 8―12】某单位招聘博士人员,国内博士应注 明取得博士学位的年份,国外博士要注明取得博士学 位的国家。
#include<stdio.h>
main() { struct doctor

{ char name[15];
int age; int tag; union { int date; char country[15]; } catalogue; 《程序设计C语言》

第8章 结构体、共用体及枚举类型 }person; printf(″input name,age,tag:\n″); scanf(″%s%d%d″,person.name,&person.age,&person.tag); if(person.tag==1) { puts(″input date -year:″); scanf(″%d″,&person.calalogue.date); } if(person.tag==2) { puts(″Input country name:\n″); scanf(″%s″,person.catalogue.country); }

《程序设计C语言》

第8章 结构体、共用体及枚举类型

printf(″\n%s,%5d,″,person.name,person.age);
if(person.tag==1) printf(″%10d\n″,person.catalogue.date); if(person.tag==2) printf(″%s\n″,person.catalogue.country);

return 0;
}

《程序设计C语言》

第8章 结构体、共用体及枚举类型

运行输出: Input name,age,tag: Zhang dong 35 1

Input date
2000

-year:

Zhang dong, 35, 2000 再运行: Input name,age,tag: Zhaotian 32 2 Input country name: France

zhaotian,32 ,France
《程序设计C语言》

第8章 结构体、共用体及枚举类型

注意:在嵌套的定义中,共用体类型名可以不写,
但其分量名catalogue必须写,因对其分量进行引用时 要用到这个分量;只有对最底层的分量才能进行输入/

输出操作,如
person.catalogue.date,person.catalogue.country等,它们 相当于两个变量,其类型分别是int和char*的类型,因 此输入/输出的控制字符应和它们相一致。 标志 tag 取不同值时进行不同的操作,在程序中应 予以提示说明,不然在输入时会造成困惑,甚至会输 入不正确的数值。

《程序设计C语言》

第8章 结构体、共用体及枚举类型

8.4 位段
为了节约内存,C语言允许以位而不是以字节为单 位来定义变量的大小。这样的变量一般用来定义结构 体的成员。这些用存储位表示的变量称为“位段”。 {unsigned|int}<位段名>:<位数>

《程序设计C语言》

第8章 结构体、共用体及枚举类型

花括号中的内容是必须的,而“|”两侧的内容任选
其一。<位段名>是标识符,<位数>指二进制位。如 unsigned a:4; 则说明位段 a 占 4 位。位数决定了取值范围。 4 位二 进制位的取值范围是0到15,超过15则a就容纳不下了。 若位段用int类型定义,则必须留出最高位为符号位, 如 int b:4

则定义b的数值位只有3位,其所能表示的数的范围
是-8到7。

《程序设计C语言》

第8章 结构体、共用体及枚举类型

对于只有1位的位段,必须定义成unsigned类型,如
struct ex { unsigned a:12; unsigned b:3;

unsigned c:1;
int d:4; }

《程序设计C语言》

第8章 结构体、共用体及枚举类型

对于不指定名字的位段表示不用它的空间,如
struct exam { unsigned a:3; unsigne d:4;

unsigned b:8;
};

《程序设计C语言》

第8章 结构体、共用体及枚举类型

【例8―13】设计一个打印扑克牌的程序。
编程思路:牌的面值(face)共有13种(从Ace到King), 可用4位二进制数表示(4位能表示0到15之间的值);牌 在 花 色 (suit) 有 4 种 ( 方 块 Diamonds, 红 桃 Hearts , 梅 花 Clubs,黑桃Spades),可用2位二进制数表示 (2位二进制数 可以有 4 种不同的状态 ) ;牌的颜色 (color) 有两种 ( 红、 黑),用1位即可。

《程序设计C语言》

第8章 结构体、共用体及枚举类型

先定义用位段表示的反映牌的特性的结构体类型:
struct bcard { unsigned face:4; unsigned suit:2;

unsigned color:1;
}; typedef struct bcard card;

《程序设计C语言》

第8章 结构体、共用体及枚举类型

然后建立有52个card元素的数组deck。定义一个洗 牌函数fillDeck,其功能是在数组deck中插入52张牌。函 数deal把52张牌打印出来。 程序如下: #include<stdio.h>

struct bcard
{ unsigned face:4; unsigned suit:2; unsigned color:1; };
《程序设计C语言》

第8章 结构体、共用体及枚举类型

typedef struct bcard card;
void fillDeck(card*); void deal(card*); main() { card deck[52];

printf(″\n\n″);
fillDeck(deck); deal(deck); return 0; }
《程序设计C语言》

第8章 结构体、共用体及枚举类型

void fillDeck(card *wDeck)
{ inti; for(i=0;i<=51;i++) { wDeck[i].face=i%13; wDeck[i].suit=i/13;

wDeck[i].color=i/26;
} } void deal(card *wDeck) { int k1,k2;
《程序设计C语言》

第8章 结构体、共用体及枚举类型

for(k1=0,k2=k1+26;k1<=25;k1++,k2++)
{ printf(″face:%3dsuit:%2dcolor:%2d″, wDeck[k1].face,wDeck[k1].suit,wDeck[k1].color); printf( ″face:%3dsuit:%2dcolor:%2d″, wDeck[k2.face,wDeck[k2].suit,wDeck[k2].color);

printf(″\n″);
} }

《程序设计C语言》

第8章 结构体、共用体及枚举类型

运行输出:
face:0 suit:0 color:0 face:0 suit:2 color:1 face:1 suit:0 color:0 face:1 suit:2 color:1 face:2 suit:0 color:0 face:2 suit:2 color:1 ……

face:11 suit:0 color:0 face:11 suit:2 color:1
face:12 suit:0 color:0 face:12 suit:2 color:1

《程序设计C语言》

第8章 结构体、共用体及枚举类型

face:0 suit:1 color:0 face:0 suit:3 color:1 face:1 suit:1 color:0 face:1 suit:3 color:1 face:2 suit:1 color:0 face:2 suit:3 color:1 …… face:11 suit:1 color:0 face:11 suit:3 color:1

face:12 suit:1 color:0 face:12 suit:3 color:1

《程序设计C语言》

第8章 结构体、共用体及枚举类型

按suit值的0,1,2,3输出四个方块,分别代表方 块、红桃、黑桃和梅花,每一块中牌的面值从0到12代 表13张牌。方块、红桃的color均为0,代表红色;黑桃、 梅花的color均为1,代表黑色。

《程序设计C语言》

第8章 结构体、共用体及枚举类型

8.5 枚举类型
自然界有很多事物虽然可以用数字来标识它们, 但用具体的名字称之则含义更为明确。比如一个星期 的各天,可以用1,2,3,…,7来表示,但用 monday,tuesday,…,sunday来说明更清晰直观。其他比如 一年中的 12 个月, 4个季度, 5 种颜色等等都是类似的 情况。为了在程序中能够直呼其名,见文知义,C语言 又 提 供 了 一 种 用 户 可 定 义 的 构 造 类 型 —— 枚 举 (enumeration)类型。
《程序设计C语言》

第8章 结构体、共用体及枚举类型

枚举类型定义时用关键字enum开头,其一般形式是:

enum <类型名> {枚举标识符表};
例如: enum color {red,yellow,green,white,black}; enum week {sun,mon,tue,wed,thu,fri,sat}; enum months{ jan,feb,mar,apr,may,jun,jul,aug,sep,oct,nov,dec};

《程序设计C语言》

第8章 结构体、共用体及枚举类型

花括号中是标识符表,但它们都是标识符常量,
不是变量,因而不能作为赋值语句的左值使用。对于 这些标识符常量,可以指定它代表某个整数值,如不 指定,则系统会自动指定,它们分别是其所处位置的 序号。序号从 0 开始,即第一个标识符常量的值是 0 , 以后的值依次递增 1。例如在枚举类型 enum months 中, 标识符被自动设置为 0 到 11 ,如果想让它们的值为 1 到 12,只需把第一个标识符的值置成1即可。

《程序设计C语言》

第8章 结构体、共用体及枚举类型

enum months{jan=1,feb,mar,…,dec};
枚举类型变量的定义方法和定义结构体变量一样, 可以在定义类型的同时定义,也可以先定义类型名, 再定义该类型的变量。例如: enum color{red,yellow,green=-10,blue,black=1,white} c1,c2; enum week{mon,tue,wed,thu,fri} workday; enum color c3; 各标识符的值在前一个值的基础上加1。比如red 为0,yellow为1,blue为-9(-10+1),white为2。

《程序设计C语言》

第8章 结构体、共用体及枚举类型

枚举变量可以作为整型量用“%d”进行输入 / 输出,
因为枚举型也是和整型相通的,它本身就是范围有限 的整数。但是不能通过scanf函数和printf函数直接输入/

输出其标识符名。要使枚举变量具有某个标识符值,
只能用赋值语句,如 c1=red; workday=mon; 当然对枚举变量赋其它的整数值也是合法的,如

c1=400;
不过这时的c1已和枚举中的标识符没什么关系了。

《程序设计C语言》

第8章 结构体、共用体及枚举类型

【例8―14】打印12个月份。
#include<stdio.h> enum months {jan=1,feb,mar,apr,may,jun,jul,aug,sep ,oct,nov,dec}; main()

{enum months month;
Char*mname[]={ ″″,″January″,″February″,″March″, “April″,″May″,″June″,″July″,″August″,″September”,″October″,″N ovember″,″December″};

《程序设计C语言》

第8章 结构体、共用体及枚举类型

for(month=jan;month<=dec;month++)
printf(″%-2d\t%-12s\n″,month,mname[month]); return0;

}
运行输出: 1 January 2 February 3 March

4 April
5 6 May June

《程序设计C语言》

第8章 结构体、共用体及枚举类型

7 July
8 9 August September

10 October 11 November

12 December
程序中枚举常量以“ %d” 格式输出时是一整数, 用它作下标时也被当作整数处理。注意:若以枚举常 量作索引,则其序号就不应随意设置,而应与其位置 保持一致。

《程序设计C语言》



热文推荐
友情链接: 简历 面试求职范文 职业规划 自我管理 社交礼仪 76242百科