
1. 引言为什么需要结构体在 C 语言中数组只能存放同类型的数据而现实中的实体如学生、商品、订单往往由多种不同类型的属性组成。结构体struct正是为此而生——它允许我们把不同类型的数据组合成一个自定义类型让代码更贴近真实世界也更易维护。本文通过一个「学生信息管理」的完整示例带你掌握结构体的定义、变量声明、成员访问点运算与箭头运算以及结构体指针传参等核心用法。2. 结构体的定义与变量声明结构体使用struct关键字定义语法如下struct结构体名{成员类型 成员名;// ...}变量名;其中struct Stu是结构体类型名而s1、p是声明的结构体变量非类型名。定义结构体时可以同时声明变量也可以先定义类型、后声明变量。3. 结构体变量的初始化与赋值结构体变量可以在声明时直接初始化也可以先声明再整体赋值structStus{zhangsan,20,nan,132222213243};s1s;// 结构体变量之间可以直接整体赋值注意结构体变量之间可以直接用赋值这是数组做不到的。4. 成员访问点运算与箭头运算访问结构体成员有两种方式点运算.通过结构体变量访问成员如s.name。箭头运算-通过结构体指针访问成员如p-name。两者在指针场景下等价p-name等价于(*p).name。下面的代码演示了两种方式的等价性printf(%s %d %s %s\n,s.name,s.age,s.sex,s.tele);printf(%s %d %s %s\n,(*p).name,(*p).age,(*p).sex,(*p).tele);printf(%s %d %s %s\n,p-name,p-age,p-sex,p-tele);5. 结构体指针传参把结构体指针传给函数可以避免整个结构体的拷贝提高效率。函数内既可以用(*a).成员也可以用a-成员访问voidprint(structStu*a){printf(%s %d %s %s\n,(*a).name,(*a).age,(*a).sex,(*a).tele);printf(%s %d %s %s\n,a-name,a-age,a-sex,a-tele);}调用时传入结构体变量的地址即可print(s);。6. 完整示例代码把以上知识点整合成一个可运行的程序#includestdio.h// struct 结构体关键字// struct Stu 结构体类型名定义// s1 声明结构体变量非类型名structStu{charname[20];// 内部成员结构体intage;charsex[10];chartele[12];}s1,*p;voidprint(structStu*a)// 结构体变量调用和指针类似{printf(%s %d %s %s\n,(*a).name,(*a).age,(*a).sex,(*a).tele);printf(%s %d %s %s\n,a-name,a-age,a-sex,a-tele);}intmain(){ps1;structStus{zhangsan,20,nan,132222213243};s1s;// 结构体变量 s结构体变量.成员点运算printf(%s %d %s %s\n,s.name,s.age,s.sex,s.tele);printf(%s %d %s %s\n,s1.name,s1.age,s1.sex,s1.tele);printf(%s %d %s %s\n,(*p).name,(*p).age,(*p).sex,(*p).tele);printf(%s %d %s %s\n,p-name,p-age,p-sex,p-tele);print(s);// printf(%s %d %s %s\n, s1-name, s1-age, s1-sex, s1-tele); // 语法错误// int *p *p 数值变量p 地址return0;}7. 常见避坑指南不要对结构体变量使用-s-name是语法错误-只能用于指针。不要对指针使用.p.name也是错误的指针必须用-或先解引用(*p).name。结构体可以整体赋值s1 s;合法但数组不能这样整体赋值。传参优先用指针结构体较大时值传递会拷贝整个结构体用指针更高效。8. 总结结构体是 C 语言组织复杂数据的核心工具。掌握struct定义、变量声明、点运算与箭头运算的区别以及指针传参的写法就能写出结构清晰、可维护的 C 程序。建议你亲手运行上面的完整示例并尝试修改成员值、增加新成员来加深理解。