结构体是一种构造数据类型 把不同的数据类型整合起来 称为一个自定义的数据类型
1 结构体初始化 定义结构体Man
struct Man{ char name[20]; int age; }; void main(){ //初始化结构体的变量 只能在声明变量是赋值 struct Man man = { "赵信", 21 }; printf("%s,%d\n",man.name,man.age); getchar(); }打印结果:
赵信,21在打印之前修改名字
strcpy(man.name, "德玛");或者是
sprintf(man.name,"皇子");打印结果为
德玛,21 皇子,212 结构体的几种写法
struct Man{ char name[20]; int age; } m1, m2 = { "张辽", 30 }; typedef int age; void main(){ strcpy(m1.name, "高飞"); m1.age = 20; printf("%s,%d\n", m1.name, m1.age); printf("%s,%d\n", m2.name, m2.age); getchar(); }打印结果
高飞,20 张辽,30匿名结构体
struct{ char name; int age; } s1;结构体嵌套
struct Teacher{ char name[20]; }; struct Student{ int age; struct Teacher t; };或者是
struct Student{ char name[20]; int age; struct Teacher{ char name[20]; } t; }; void main(){ struct Student student = { 21, {"亚索"} }; printf("%d,%s\n",student.age,student.teacher.name); getchar(); }打印结果
21,亚索3 结构体与指针数组
struct Man{ char name[20]; int age; }; void main(){ struct Man mans[] = { { "Kobe", 38 }, { "Gready", 37 } }; struct Man *p = mans; //遍历方式 1 /*for (; p < mans+2;p++){ printf("%#x\n",p); printf("%s,%d\n",p->name,p->age); }*/ //遍历方式 2 int i = 0; for (; i < sizeof(mans) / sizeof(struct Man); i++){ printf("%#x\n", mans[i]); printf("%s,%d\n", mans[i].name, mans[i].age); } system("pause"); }打印结果
0x97fbd8 Kobe,38 0x97fbf0 Gready,373 结构体大小 (字节对齐)
struct Man{ int age; double weight; }; void main(){ struct Man m = {20,50.6}; printf("%#x,%d",&m,sizeof(m)); getchar(); }打印结果
0xfaf79c,16结构体中,int占4个字节,double占8个字节。所以m应该占12个字节才对。但是实际上m占16个字节。 这是因为结构体变量的大小,必须是最宽基本数据类型的整数倍。这样做会提升读取的效率。
4 结构体动态内存分配
struct Man{ int age; char *name; }; void main(){ struct Man* man = (struct Man*)malloc(sizeof(struct Man) * 10); struct Man *p = man; //赋值 p->name = "Davis"; p->age = 23; p++; p->name = "Rose"; p->age = 25; struct Man *loop = man; for (; loop < man + 2; loop++){ printf("%s,%d\n", loop->name, loop->age); } free(man); getchar(); }5 typedef结构体取别名
typedef int* Ap; typedef struct Women* Wp; //Women结构体指针的别名 typedef struct Women W; //Women结构体的别名 typedef struct Women{ char name[20]; int age; }; void main(){ int i = 5; Ap p = &i; //结构体变量 W w1 = { "Rose", 25 }; //结构体指针 Wp wp1 = &w1; printf("%s,%d\n", w1.name, w1.age); printf("%s,%d\n", wp1->name, wp1->age); getchar(); }打印结果
Rose,25 Rose,251 不同名称代表不同的操作 2 不同情况使用不同的别名 3 书写简洁
6 结构体函数指针
struct Girl{ char *name; int age; //函数指针 void(*sayHi)(char*); }; //Girl结构体类似于Java中的类,name和age类似于属性,sayHi类似于方法 void sayHi(char*text){ MessageBox(0, text, "title", 0); } void main(){ struct Girl g1; g1.name = "Lucy"; g1.age = 17; g1.sayHi = sayHi; g1.sayHi("hello"); getchar(); }运行后 弹窗 下面是使用取别名的方式
typedef struct Girl{ char *name; int age; //函数指针 void(*sayHi)(char*); }Girl; //Girl结构体指针取别名GirlP typedef Girl* GirlP; void sayHi(char* text){ MessageBoxA(0, text, "title", 0); } //改名 void rename(GirlP gp1){ gp1->name = "Lily"; } void main(){ Girl g1 = { "Lucy", 18, sayHi }; GirlP gp1 = &g1; gp1->sayHi("Byebye!"); //传递指针,改名 rename(gp1); getchar(); }