在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,则可以直接使用
结构体名 变量名。
阅读(1786) | 评论(0) | 转发(1) |