结构——由于结构将一组相关的变量看作一个单元而不是各自独立的实体,因此结构有助于组织复杂的数据
- 结构的基本知识
- 结构与函数
- 结构数组
- 指向结构的指针
- 自引用结构
- 表查找
- 类型定义
- 联合
- 位字段
/
1.结构的基本知识
//结构体定义
关键字struct引入结构声明,结构声明由包含在话括号内的一系列声明组成。struct后面的名字是可选的,称为结构标记。结构标记用于为结构命名,在定义之后,结构标记就代表花括号内的声明,可以用它作为该声明的简写形式。如:
struct point{
int x;
int x;
};
结构中定义的变量称为成员。结构成员,结构标记和普通变量(非成员)可以采用相同的名字,不会冲突。另外,不同结构中的成员可以使用相同的名字。
struct声明定义了一种数据结构。在标志结构成员表结束的右话括号之后可以跟一个变量表,这与其他基本类型的变量声明是相同的。如:
struct {...} x, y, z;
从语法角度讲,这种方式的声明与声明
int x, y, z;
具有类似的意义。这两个声明都将x, y, z声明为指定类型的变量,并且为它们分配存储空间。
//初始化
如果结构声明的后面不带变量表,则不需要为它分配存储空间,它仅仅描述了一个结构的模板或轮廓。但是,如果结构声明中带有标记,那么在以后定义结构实例时便可以使用该标记定义。如:
struct point pt;
定义了一个struct point类型的变量pt。结构的初始化可以在定义的后面使用初值表进行。初值表中每个成员对应的初值必须是常量表达式,如:
struct point maxpt = {200, 100};
//点运算
在表达式中,可以使用下列形式引用某个特定结构中的成员:
结构名.成员
其中的结构成员运算符“.”将结构名与成员名连接起来。如,打印点pt的坐标:
printf("%d,%d",pt.x,pt.y);
//结构可以嵌套
可以用对角线上的两个点来定义矩形,定义如下:
struct rect{
struct point pt1;
struct point pt2;
};
结构rect包含两个point类型的成员。如果按照下列方式声明screen变量:
struct rect screen;
则可以用语句
screen.pt1.x;
引用screen的成员pt1的x坐标
/
2.结构与函数
//结构的操作
a.作为一个整体复制和赋值,包括向函数传递参数以及从函数返回值
b.通过&运算符取地址
c.访问其成员
d.结构之间不可以进行比较
e.用一个常量成员值列表初始化结构
f.自动结构也可以通过赋值进行初始化
//结构传递
a.分别传递各个结构成员
b.传递整个结构
c.传递指向结构的指针
传值和传引用的区别?
如果传递给函数的结构很大,使用指针方式的效率通常比复制整个结构的效率要高。结构指针类似普通变量指针。声明:
struct point *pp;
将pp定义为一个指向struct point类型对象的指针。如果pp指向一个point结构,那么*pp即为该结构,而(*pp).x和(*pp).y则是结构体成员。可按照下例中的方式使用pp:
struct point origin, *pp;
pp = &origin;
printf("origin is (%d %d)\n", (*pp).x, (*pp).y);
注意:点运算符号的优先级高于*运算符
//指针运算符
结构指针的使用频度非常高,为使用方便,C语言提供了一种简写方式。假定p是一个指向结构的指针,可以用
p->结构成员
这种形式引用相应的结构成员。
运算符.和->都是从左至右结合的,所以,对于下面的声明
struct rect r, *rp=&r;
以下四个表达式是等价的
r.pt1.x
rp->pt1.x
(r.pt1).x
(rp->pt1).x
/
3.结构数组
//应用实例:实现统计输入中各个C语言关键字出现的次数的程序
struct key {
char *word; //存放关键字名字
int count; //存放相应关键字的出现次数
} keytab[NKEYS];
声明了一个结构类型key,并定义了该类型的结构数组keytab,同时为其分配存储空间。数组keytab的每个元素都是一个结构。初始化可在定义的后面通过一个用圆括号括起来的初值表进行初始化,如
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 },
...
但是,如果初值是简单变量或字符串,并且其中的任何值都不为空,则内层的花括号可以省略。通常情况下,如果初值存在并且方括号[ ]中没有数值,编译程序将计算数组keytab中的项数。
/
4.指向结构的指针