首页 > 代码库 > C语言的结构体

C语言的结构体

 

举例,一个结构体的定义如下:

typedef struct _foo {
    char name[30];
    int age;
    int sex;
} foo;

 

 

对齐

如果直接对上面的结构体作sizeof()运算:

printf("%d\n", sizeof(foo));   // 40

 

如果在成员名后面加上冒号,指定占用的bits数,可以节省结构体的大小,例如:

typedef struct _foo {
    char name[30];
    int age:5;
    int sex:1;
} foo;

 

可以使用下面的宏计算结构体中某个成员的偏移位置:

#define offset(type, member)  ((int) &((type*)0) ->member)

演示如何计算成员的位置:

foo f1 = {"cq", 32, 1};
char *p = &f1;
int age = *(int*) (p + offset(foo, age));       // equivalent f1->age

 

 

 

 

初始化

结构体变量在定义的同时进行初始化,类似于数组的初始化:

foo f1 = {"zy", 26, 1}; 

 

也可以只对部分成员进行初始化:

foo f2 = {"zy", 26};

未显示初始化的成员会有默认值。

 

还可以使用如下的初始化方法:

foo f3 = { 
        .age = 30, 
        .name = "cq",
        .sex = 0,
    };

这种方法可以打乱结构体成员赋值的顺序,在Linux内核中经常使用这种赋值方法,增强代码的可移植性(比如有些成员在不同平台可能被编译,可能不编译)。

 

下面这种写法也是一样的:

foo f4 = { 
        age : 18,
        sex : 0,
        name : "cq",
};  

 

 

赋值

同类型的结构体变量之间可以互相赋值:

foo f1 = {"zy", 26, 1}; 
foo f2 = f1;

 

但如果有指针成员,就要特别小心了,例如:

typedef struct _foo {
    char *name;
    int age;
    int sex;
} foo;

foo f1;
 f1.name = strdup("bush");
 f1.age = 31;
 f1.sex = 0;

 foo f2 = f1;

这里的 f1.name 和 f2.name 两个成员指针指向的是同一块内存(即浅拷贝),释放其中任何一个,都会影响另外一个。

 

C语言的结构体