云计算百科
云计算领域专业知识百科平台

C语言结构体(一看就会)

本文基于实战代码, 总结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;
}

五、实战作业:银行卡嵌套结构体设计与实现

结合上述知识点,完成“银行卡管理”实战作业,核心要求:

  • 设计嵌套结构体:银行卡包含「银行名、账号、密码、余额」+ 「属主信息(姓名、身份证、电话)」;
  • 定义10个元素的银行卡数组,给前2张卡赋值;
  • 分别用「数组下标」和「指针」输出数组元素。
  • 完整实现代码(贴合作业要求)

    #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;
    }

    六、拓展知识点(面试高频)

  • 结构体大小与内存对齐:结构体的实际占用内存并非成员大小简单相加,编译器会按“内存对齐规则”填充字节(比如char后补字节对齐到int),目的是提升内存访问效率;
  • 指针++的本质:结构体指针p++ 会偏移「整个结构体的大小」,而非1个字节;
  • const修饰结构体指针:const BankCard *p 表示指针指向的结构体内容不可修改,仅指针本身可偏移;
  • 结构体传参:后续学习结构体作为函数参数时,推荐传指针(避免拷贝整个结构体,提升效率)。
  • 总结

    结构体是C语言面向过程编程中“封装思想”的核心体现,嵌套结构体解决了复杂对象的层级描述问题,而结构体数组+指针则实现了批量对象的高效管理。本文通过“员工信息”“银行卡”两个实战案例,覆盖了结构体定义、赋值、嵌套、数组、指针等核心用法,是掌握C语言复合数据类型的关键基础。

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » C语言结构体(一看就会)
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!