1.1 结构体1.1.1 定义结构体struct和初始化struct man { char name[100]; int age; }; struct man m = { 'tom', 12 }; struct man m = { .name = 'tom', .age = 12 }; |
1.1.2 访问结构体成员.操作符 1.1.3 结构体的内存对齐模式编译器在编译一个结构的时候采用内存对齐模式 struct man{ char a; int b; }; |
1.1.4 指定结构体元素的位字段定义一个结构体的时候可以指定具体元素的位长 struct test{ char a : 2;//指定元素为2位长,不是2个字节长 }; |
1.1.5 结构数组struct man m[10] = { { 'tom', 12 }, { 'marry', 10 }, { 'jack', 9 } }; |
1.1.6 嵌套结构一个结构的成员还可以是另一个结构类型 struct names{ char first[100]; char last[100]; }; struct man{ struct names name; int age; }; struct man m = { { 'wang', 'wu' }, 20 }; |
1.1.7 结构体的赋值struct name a = b; 1.1.8 指向结构体的指针–>操作符 1.1.9 指向结构体数组的指针 1.1.10 结构中的数组成员和指针成员一个结构中可以有数组成员,也可以有指针成员,如果是指针成员结构体成员在初始化和赋值的时候就需要提前为指针成员分配内存。 struct man { char name[100]; int age; }; | struct man { char *name; int age; }; |
1.1.11 在堆中创建的结构体如果结构体有指针类型成员,同时结构体在堆中创建,那么释放堆中的结构体之前需要提前释放结构体中的指针成员指向的内存。 struct man { char *name; int age; }; struct man *s = malloc(sizeof(struct man) * 2); s[0].name = malloc(10 * sizeof(char)); s[1].name = malloc(10 * sizeof(char)); |
1.1.12 将结构作为函数参数将结构作为函数参数 将结构指针作为函数参数 1.1.13 结构,还是指向结构的指针在定义一个和结构有关的函数,到底是使用结构,还是结构的指针? 指针作为参数,只需要传递一个地址,所以代码效率高 结论就是当一个结构做为函数的参数时候,尽量使用指针,而不是使用结构变量,这样代码效率很高 void print_student(const struct student *s)//一般来讲,不要把结构变量做为函数的参数传递 { printf('name = %s, age = %d\n', s->name, s->age); } void set_student(struct student *s, const char *name, int age) { strcpy(s->name, name); s->age = age; } |
1.2 联合体联合union是一个能在同一个存储空间存储不同类型数据的类型。 联合体所占的内存长度等于其最长成员的长度,也有叫做共用体。 联合体虽然可以有多个成员,但同一时间只能存放其中一种。 union variant{ int ivalue; char cvalue; double dvalue; }; int main() { union variant var; var.cvalue = 12; printf('%d\n', var.ivalue); printf('%p, %p, %p\n', &(var.cvalue), &(var.ivalue), &(var.dvalue)); return 0; } |
1.3 枚举类型1.3.1 枚举定义可以使用枚举(enumerated type)声明代表整数常量的符号名称,关键字enum创建一个新的枚举类型。 实际上,enum常量是int类型的。 enum spectrum { red, yellow, green, blue, white, black }; enum spectrum color; color = black; if (color != red) |
1.3.2 默认值默认时,枚举列表中的常量被指定为0,1,2等 enum spectrum { red, yellow, green, blue, white, black }; printf('%d, %d\n', red, black); |
指定值 可以指定枚举中具体元素的值 enum spectrum { red = 10, yellow = 20, green, blue, white, black }; printf('%d, %d\n', red, black); |
1.4 typedeftypedef是一种高级数据特性,它能使某一类型创建自己的名字 typedef unsigned char BYTE |
1与#define不同,typedef仅限于数据类型,而不是能是表达式或具体的值 2typedef是编译器处理的,而不是预编译指令 3typedef比#define更灵活 直接看typedef好像没什么用处,使用BYTE定义一个unsigned char。使用typedef可以增加程序的可移植性。 1.5 通过typedef定义函数指针typedef const char *(*SUBSTR)(const char *, const char *); const char *getsubstr(const char *src, const char *str) { return strstr(src, str); } const char *func(const char *(*s)(const char *, const char *), const char *src, const char *str) | const char *(*p[3])(const char *, const char *); |
|