在Linux移植过程中,看到源代码中对struct应用很多。特别是在复杂应用结构中,有两种基本的用法,以前没有用过。现在整理总结一下,提高认识。
1、struct在代码中常见两种基本形式。
1)struct A {
成员
};
2) struct {
成员
}A;
这两种用法是不同的。1)是结构体类型定义,也就是说定义了一个叫做A的结构体;2)是结构体变量定义,也就是为该匿名结构体定义了一个变量。当然,这两种用法也可以结合起来,如:
struct A {
成员
}a;
表示定义了一个叫做A的结构体,并且为A定义了一个变量a。
2、常见的结构体定义过程中初始化的方法如下:
struct A {
成员
}a = {
初始化值
};
这种用法在程序设计时也常用到。但是,不方便的地方在于,必须严格按照成员与成员初始化值一一对应的方式,而且如果设计复杂结构体嵌套,对成员就不是非常清晰了。所以,为了能够为某个或者某些成员赋值,而且忽略顺序,C99提供了"."(C99 designated initializer)。设计了一个简单的实例来说明用法。
#include <stdio.h>
typedef unsigned int u_int32_t;
/* get number of members in array or struct */
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
/* 结构体类型定义 */
struct mtd_partition {
char *name;
u_int32_t size;
u_int32_t offset;
u_int32_t mask_flags;
};
/* 定义结构体数组,采用两种方式进行部分成员初始化 */
struct mtd_partition nor_partion[] = {
/* 1 c99 usage */
{
.name = "NOR Partion 1",
.offset = 0,
.size = 1,
},
/* 2 gcc extension */
{
name : "NAND Partion 1",
offset : 0,
size : 1,
}
};
int main(void)
{
int i, n;
n = ARRAY_SIZE(nor_partion);
for (i=0; i<n; i++) {
printf("%s\t%d\t%d\n", nor_partion[i].name,
nor_partion[i].offset,
nor_partion[i].size);
}
return 0;
}
|
上面的nor_partion的第一个成员的初始化是C99标准,基本用法是
.成员=初始值,第二个成员的初始化则是采用gcc扩展用法(
成员:初始值)。这两种用法在Linux内核源代码中应用广泛,应该掌握。
3、用到了struct,也需要考虑typedef。typedef是C语言的关键字,作用就是为一种数据类型定义一个新的名字。在程序设计中使用typedef,我所知道的作用有:1)提高程序的可移植性。比如,有些数据类型的长度在不同机器上是不一致的,linux/types.h中即是使用typedef来实现了可移植的数据类型。2)提高程序的可读性。可以为有多种用途的结构体赋予不同的别名,有助于阅读。3)简化一些复杂的类型声明。比如,函数指针类型声明。对应前面struct,应用typedef也可以有两种:
1)typedef struct A {
成员
}AA;
2) typedef struct {
成员
}AA;
其中,1)为结构体A起了一个别名AA,2)为一个匿名结构体起了一个名字AA。使用比较广泛的是2)。当然,有些时候必须使用1)。注意,使用struct进行结构体定义,那么定义变量时必须使用
struct 结构体名 变量名;,而使用typedef,则可以直接使用
结构体名 变量名。
阅读(5572) | 评论(1) | 转发(1) |