struct 结构体名
{
数据类型 成员1;
数据类型 成员2;
};记得加分号
结构体尽量放在函数外,放在声明前
结构体嵌套中,结构体要遵循先定义后使用原则,嵌套定义使用struct 结构体名 变量名 来声明,同时可以把结构体写到结构体里面嵌套
成员引用:变量名. 成员名 指针->成员名 (*指针). 成员名
结构体中部分变量声明,例如 struct student_st stu = {.math = 98,.chinese = 97};
用指针p引用结构体数组地址时,p+1表示跳一个结构体大小的地址。
结构体由于地址对齐,存放char型1字节的变量会地址偏移,根据addres%sizeof计算地址偏移,能整除直接存放,不能整除向下偏移,例如int,char,float为12个字节,int,char,float,char为16个字节,int,char,char,float为12个字节。
在结构体尾部加上_attribute_((packed))表示按变量实际大小存储,为所有变量大小的和。
函数如果使用结构体传参,开销较大,尽量使用指向结构体的指针传参。
无头结构体要在定义的时候把所有内容赋值完,无法中途赋值。
基于结构体设计的一个学生成绩录入系统:
#include共用体#include #include #define NAMESIZE 32 //学生基本信息 struct std_st { int id; char name[NAMESIZE]; int math; int chinese; }; //信息录入 void std_set(struct std_st *p,struct std_st *q) { *p = *q; } //信息展示 void std_show(struct std_st *p) { printf("%dn%sn%dn%dn",p->id,p->name,p->math,p->chinese); } //学生姓名更改 void std_changename(struct std_st *p,const char *newname) { strcpy(p->name,newname); } //菜单显示,q表示退出 void menu(int step) { if(step==0) printf("Please enter the student's sequence[5] or enter q fot quit:n"); else { printf("n1:set 2:changename 3:shown"); printf("Please enter:n"); } } int main() { struct std_st std[5],tmp; int seq,ret,oper; char newname[NAMESIZE]; do { menu(0); ret = scanf("%d",&seq); if(ret != 1) break; menu(1); scanf("%d",&oper); switch(oper) { case 1: printf("Please enter message[id name math chinese]:n"); scanf("%d%s%d%d",&tmp.id,tmp.name,&tmp.math,&tmp.chinese); std_set(&std[seq],&tmp); break; case 2: printf("Please enter the newename:n"); scanf("%s",newname); std_changename(&std[seq],newname); break; case 3: std_show(&std[seq]); break; default: exit(1); } sleep(1); }while(1); exit(0); }
与struct基本类似,但同一时刻有多个情况存在,但只能选择一种情况,即只能使用其中的一个成员。
union 共用体名
{
数据类型 成员名1;
数据类型 成员名2;
。。。。
};
共用体的存储空间默认为最大成员的大小
共用体成员声明后,其他成员都不可用,只能使用声明的成员,得到的存储空间也存放的是已声明的成员变量。
共用体同样适用地址传参
利用union求32位变量的前16位与后16位的和:
#include枚举#include #include //利用union的存储特性实现特殊功能 union { struct { int16_t i; int16_t j; }x; int32_t y; }a; int main() { a.y = 0x11223344; printf("%xn",a.x.i+a.x.j); exit(0); }
enum 标识符
{
成员1,
成员2,
。。。。
};
enum成员默认值为从0,1,2开始顺序排列,如果赋值,则从赋值位重新排列。
enum可以当作宏来使用,把事件的多种状态枚举出来。



