第十四章 结构和其他数据形式
14.1 示例问题:创建图书目录
- 为结构建立一个格式或样式;
- 声明一个适合该样式的变量;
- 访问结构变量的各个部分。
14.2 建立结构声明
结构声明(structure declaration
)描述一个结构的组织布局。声明类似如下:
struct book
{
char title[MAXTITL];
char author[MAXTITL];
float value;
};
14.3 定义结构变量
struct book library;
初始化结构
一对花括号括起来的初始化列表进行初始化,各初始化项用逗号分隔。
struct book library =
{
"The Pious Pirate and the Devious Damsel",
"Renee Vivotte",
1.95
};
/* C99,C11 指定初始化器 */
struct book gift =
{
.value = 25.99,
.author = "james Broadfool",
.title = "Rue for the Toad"
};
14.4 结构数组
struct book library[MAXBKS]
14.5 嵌套结构
14.6 指向结构的指针
/* 声明结构指针 */
struct guy* him;
/* 初始化结构指针 */
him = &barney;
/* 访问 */
him—>income;
(*him).income;
14.7 向函数传递结构的信息
- 直接传递结构体成员
- 传递结构体的地址
- 传递结构
允许一个结构体赋值给另一个结构体。
指针作为参数的优点:
- 各个版本
C
都支持 - 执行快
- 可以加
const
保护数据
复合字面量和结构(C99
)
(struct book){"The Idiot", "Fyodor Dostoyevsky", 6.99}
伸缩型数组成员(C99)
struct flex
{
int count;
double average;
double scores[]; /* 伸缩行数组成员 */
};
特性
- 该数组不会立即存在
- 使用设个伸缩型数组成员可以编写合适的代码,就好像它确实存在并具有所需数目的元素一样。
规则限制
- 伸缩型数组成员必须是结构的最后一个成员;
- 结构中必须至少有一个成员;
- 伸缩型数组的声明类似于普通数组,只是它的方括号中是空的。
不要直接赋值或拷贝含伸缩型数组成员的结构,因为不会拷贝伸缩型数组成员。
匿名结构(C11)
常用再嵌套联合中
struct person
{
int id;
struct /* 匿名结构 */
{
char first[20];
char last[20];C
}
}
struct person ted = {8483, {"Ted", "Grass"}};
/* 可以像访问普通内部成员一样访问,匿名结构成员里的元素 */
puts(ted.first);
14.8 把结构内容保存到文件中
用 fread/fwrite
。
14.9 链式结构
链式结构:结构通过结构指针成员链接到一起。
14.10 联合简介
联合(union
):能在同一个内存空间中存储不同的数据类型(不是同时存储)。语法上和结构体类似。
匿名联合(C11)
和匿名结构的工作原理相同,即匿名联合是一个结构或联合的无名联合成员。常用于描述寄存器信息。
typedef struct
{
union
{
__IO uint32_t cfglr;
struct
{
__IO uint32_t iomc0 : 2; /* [1:0] */
__IO uint32_t iofc0 : 2; /* [3:2] */
__IO uint32_t iomc1 : 2; /* [5:4] */
__IO uint32_t iofc1 : 2; /* [7:6] */
__IO uint32_t iomc2 : 2; /* [9:8] */
__IO uint32_t iofc2 : 2; /* [11:10] */
__IO uint32_t iomc3 : 2; /* [13:12] */
__IO uint32_t iofc3 : 2; /* [15:14] */
__IO uint32_t iomc4 : 2; /* [17:16] */
__IO uint32_t iofc4 : 2; /* [19:18] */
__IO uint32_t iomc5 : 2; /* [21:20] */
__IO uint32_t iofc5 : 2; /* [23:22] */
__IO uint32_t iomc6 : 2; /* [25:24] */
__IO uint32_t iofc6 : 2; /* [27:26] */
__IO uint32_t iomc7 : 2; /* [29:28] */
__IO uint32_t iofc7 : 2; /* [31:30] */
} cfglr_bit;
};
}GPIO_ST;
14.11 枚举类型
声明符号名称表示整形常量。
enum spectrum
{
red,
orange,
yellow,
green,
blue,
violet
};
enum spectrum color;
默认值为从默认起始成员为零,其他成员为前一个成员的值加一;
可以为枚举常量指定数值。
enum feline {cat, lynx = 10, puma, tiger};
那么 car
、lynx
、puma
、tiger
的值分别为 0
、10
、11
、12
。
C
中相同作用域中的变量和标记的名称可以相同,但 C++
不行。
14.12 typedef 简介
typedef
可以为某一类型自定义名称。https://www.jianshu.com/
- 与
#define
不同,typedef
创建的符号名只受限于类型,不能用于值。 -
typedef
有编译器解释,不是预处理器。 - 在其受限范围内,
typedef
比#define
更灵活。
typedef unsigned char BYTE
typedef char* PBYTE
14.13 其他复杂的声明
int board[8][8]; /* 内含 int 数组的数组 */
int **ptr; /* 指向指针的指针,被指向的指针指向 int */
int *risks[10]; /* 内含 10 个元素的数组,每个元素都是一个指向 int的指针 */
int (*rusks)[10]; /* 指向数组的指针,该数组内含 10 个 int 类型的值 */
int*oof[3][4]; /* 3x4 的二维数组,每个元素都是指向 int 的指针 */
int (*uuf)[3][4]; /* 指向 3x4 二维数组的指针,该数组中内含 int 类型值 */
int (*uof[3])[4]; /* 内含 3 个指针元素的数组,其中每个指针都指向一个内含 4 个 int 类型元素的数组 */
14.14 函数和指针
void (*pf)(char *); /* pf 是一个指向函数的指针 */
网友评论