本文基于实战代码, 总结C语言结构体的核心用法,包括结构体设计、嵌套结构体、结构体数组、指针操作结构体等关键知识点。
一、结构体基础认知
1. 结构体的核心作用
本质是自定义的集合多种基本数据类型的复合型数据类型 C语言中的基本数据类型(int、float、char等)只能描述单一属性,而结构体(struct) 允许我们自定义复合数据类型,将多个不同类型的属性封装为一个整体,比如描述“员工”“银行卡”“书籍”等包含多维度信息的对象。
2. 结构体的定义语法
// 语法模板:typedef 简化类型名(可选但推荐)
typedef struct 结构体名 {
数据类型 成员名1;
数据类型 成员名2;
// 嵌套结构体(可选)
其他结构体类型 嵌套成员名;
} 简化后的类型名;
示例(书籍类型):
#define NAMESIZE 20 // 宏定义限制字符串长度,避免越界
typedef struct Book {
char bookname[NAMESIZE]; // 书名
char author[NAMESIZE]; // 作者
float price; // 价格
} Book; // 简化类型名,后续可直接用Book声明变量,无需写struct Book
简化类型名后,Book相当于一个数据类型(类似int char),定义时 数据类型+变量 例如:Book(数据类型) arr(变量)
二、结构体变量的赋值方式
结构体变量的赋值分为「定义时直接赋值」和「先声明后逐个赋值」两种,核心注意:字符串成员不能直接用=赋值,需用strcpy函数。
1. 定义时直接赋值
赋值顺序必须与结构体成员的定义顺序完全一致:
int main() {
// 定义Book类型变量并直接赋值
Book book = {"C语言程序设计","谭浩强",20.0};
return 0;
}
注意:如果要直接赋值,必须要在定义时候赋值,若先定义,再直接赋值,视为错误
2. 先声明后逐个赋值
先开辟变量内存,再通过「变量名.成员名」访问并赋值:
int main() {
Book book; // 声明变量,成员初始为随机值
// 字符串成员用strcpy赋值(避免book.bookname = "xxx"的错误写法)
strcpy(book.bookname, "C语言程序设计");
strcpy(book.author, "谭浩强");
book.price = 20.0; // 数值成员可直接赋值
return 0;
}
三、嵌套结构体:封装多层级属性
相当于在一个结构体里再嵌套一个结构体 当描述的对象包含“子属性集合”时(比如员工包含“地址”,银行卡包含“属主信息”),可使用嵌套结构体,将子属性封装为独立结构体后,作为主结构体的成员。
示例:员工信息(包含地址嵌套)
#include <string.h>
#include <stdio.h>
#define NAMESIZE 10 // 姓名长度
#define PLACESIZE 20 // 地址字段长度
// 子结构体:地址(省/市/区)
typedef struct Address {
char province[PLACESIZE];
char city[PLACESIZE];
char area[PLACESIZE];
} Address;
// 主结构体:员工(包含姓名、年龄、工资、地址)
typedef struct Employee {
char name[NAMESIZE];
size_t age;
float salary;
Address address; // 嵌套Address结构体作为成员
} Employee;
嵌套结构体的赋值与访问
int main() {
// 1. 定义员工数组并赋值(包含嵌套地址)
Employee emps[] = {
{ "zs",10,1000,{"陕西省","西安市","未央区" } },
{ "lisi",20,5000,{"陕西省","西安市","未央区" } },
{ "ww",20,5000,{"陕西省","西安市","未央区" } }
};
// 2. 访问嵌套成员:主结构体.嵌套结构体.子成员
int len = sizeof(emps) / sizeof(emps[0]); // 计算数组长度
for (int i = 0; i < len; i++) {
printf("第%d个人信息:姓名:%s 工资:%.2f 年龄:%u %s %s %s\\n",
i+1, emps[i].name, emps[i].salary, emps[i].age,
emps[i].address.province, // 访问嵌套的地址省份
emps[i].address.city, // 访问嵌套的地址城市
emps[i].address.area); // 访问嵌套的地址区域
}
return 0;
}
四、结构体数组 + 指针操作
1. 结构体数组:批量管理多个结构体对象
比如“10个员工”“10张银行卡”,可定义结构体数组,语法与普通数组一致:
// 员工数组:存储3个员工对象
Employee emps[] = {
{ "zs",10,1000,{"陕西省","西安市","未央区" } },
{ "lisi",20,5000,{"陕西省","西安市","未央区" } },
{ "ww",20,5000,{"陕西省","西安市","未央区" } }
};
2. 指针操作结构体:灵活访问/修改数组元素
结构体指针的核心语法:
- 指针指向结构体数组首地址:结构体类型 *p = 数组名;(等价于&数组名[0])
- 指针访问成员:p->成员名(优先推荐) 或 (*p).成员名(等价写法)
- 指针偏移:p++ 指向数组中下一个结构体元素
示例:指针修改员工信息
int main() {
Employee emps[] = {
{ "zs",10,1000,{"陕西省","西安市","未央区" } },
{ "lisi",20,5000,{"陕西省","西安市","未央区" } },
{ "ww",20,5000,{"陕西省","西安市","未央区" } }
};
// 1. 指针指向数组第三个元素(下标2)
Employee* p = &emps[2];
// 修改嵌套的地址区域为“雁塔区”
strcpy(p->address.area, "雁塔区"); // 推荐写法:p->嵌套结构体.子成员
// 等价写法:strcpy((*p).address.area, "雁塔区");
// 2. 指针修改第二个员工(下标1)的工资
(emps + 1)->salary = 6000; // emps+1 等价于 &emps[1]
return 0;
}
五、实战作业:银行卡嵌套结构体设计与实现
结合上述知识点,完成“银行卡管理”实战作业,核心要求:
完整实现代码(贴合作业要求)
#include <stdio.h>
#define namesize 50
#define namesize1 50
struct information
{
char name[namesize1];
long long IDcode;
long long phonenumber;
}information;
typedef struct Bankcard
{
char bankname[namesize];
long long accoount;
long long code;
int money;
struct information information;
}bankcard;
int main()
{
bankcard bc[10] = { { "工商银行",5464454,2121221,2100,{"张三",1545133,32323522} } ,{ "工商银行",6686868,5566661,2500,{"李四",4457575,55757523} } };
bankcard* p = &bc[1];
printf("第一个人信息:%s %lld %lld %d %s %lld %lld\\n", bc[0].bankname,bc[0].accoount, bc[0].code,bc[0].money,bc[0].information.name,bc[0].information.IDcode,bc[0].information.phonenumber);
printf("第二个人信息:%s %lld %lld %d %s %lld %lld", p->bankname , p->accoount, p->code, p->money, p->information.name, p->information.IDcode, p->information.phonenumber);
return 0;
}
六、拓展知识点(面试高频)
总结
结构体是C语言面向过程编程中“封装思想”的核心体现,嵌套结构体解决了复杂对象的层级描述问题,而结构体数组+指针则实现了批量对象的高效管理。本文通过“员工信息”“银行卡”两个实战案例,覆盖了结构体定义、赋值、嵌套、数组、指针等核心用法,是掌握C语言复合数据类型的关键基础。
网硕互联帮助中心





评论前必须登录!
注册