news 2026/6/10 17:07:10

c语言结构体操作示例

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
c语言结构体操作示例

structs.c 完整代码

#include<stdio.h>#include<string.h>// 结构体定义structStudent{charname[50];intid;floatgpa;};// 嵌套结构体定义structDate{intday;intmonth;intyear;};structEmployee{charname[50];intemployeeId;structDatehireDate;floatsalary;};// 函数声明voidprintStudent(structStudents);voidupdateGPA(structStudent*s,floatnewGPA);intmain(){// 结构体变量声明与初始化structStudents1={"张三",1001,3.8};// 结构体变量访问printf("=== 学生信息 ===\n");printf("姓名: %s\n",s1.name);printf("学号: %d\n",s1.id);printf("GPA: %.2f\n",s1.gpa);// 结构体指针structStudent*ptr=&s1;printf("\n=== 通过指针访问学生信息 ===\n");printf("姓名: %s\n",ptr->name);printf("学号: %d\n",ptr->id);printf("GPA: %.2f\n",ptr->gpa);// 结构体数组printf("\n=== 学生数组 ===\n");structStudentstudents[3]={{"李四",1002,3.5},{"王五",1003,3.9},{"赵六",1004,3.2}};for(inti=0;i<3;i++){printStudent(students[i]);}// 调用函数修改结构体成员printf("\n=== 修改GPA ===\n");updateGPA(&students[0],3.7);printStudent(students[0]);// 嵌套结构体示例printf("\n=== 员工信息(嵌套结构体)===\n");structEmployeeemp1;strcpy(emp1.name,"钱七");emp1.employeeId=2001;emp1.hireDate.day=15;emp1.hireDate.month=6;emp1.hireDate.year=2020;emp1.salary=5000.0;printf("员工姓名: %s\n",emp1.name);printf("员工ID: %d\n",emp1.employeeId);printf("入职日期: %d/%d/%d\n",emp1.hireDate.day,emp1.hireDate.month,emp1.hireDate.year);printf("薪资: %.2f\n",emp1.salary);return0;}// 函数定义:打印学生信息voidprintStudent(structStudents){printf("姓名: %s, 学号: %d, GPA: %.2f\n",s.name,s.id,s.gpa);}// 函数定义:更新GPA(使用指针修改原结构体)voidupdateGPA(structStudent*s,floatnewGPA){s->gpa=newGPA;}

1. 文件概述

structs.c 是一个展示 C 语言中结构体基本概念、定义和使用方法的示例文件。通过该文件,您可以学习 C 语言中结构体的定义、初始化、访问、结构体指针、结构体数组以及嵌套结构体等核心操作。

  • 文件名: structs.c
  • 类型: C语言源文件
  • 功能: 演示C语言中结构体的基本概念、定义和使用方法,包括基本结构体、嵌套结构体、结构体数组、结构体指针以及结构体作为函数参数等。
  • 依赖: 标准C库(stdio.h, string.h)

2. 核心结构

2.1 头文件包含

structs.c 首先包含了两个必要的头文件:

#include<stdio.h>// 引入标准输入输出库#include<string.h>// 引入字符串处理函数库(用于字符串复制操作)

2.2 结构体定义

2.2.1 基本结构体

Student 结构体用于表示学生信息,包含姓名、学号和GPA三个成员:

// 结构体定义structStudent{charname[50];// 学生姓名intid;// 学生学号floatgpa;// 学生GPA};
2.2.2 嵌套结构体

Date 结构体用于表示日期,包含日、月、年三个成员:

// 嵌套结构体定义structDate{intday;// 日期intmonth;// 月份intyear;// 年份};

Employee 结构体用于表示员工信息,包含姓名、员工ID、入职日期(Date结构体)和薪资四个成员:

structEmployee{charname[50];// 员工姓名intemployeeId;// 员工IDstructDatehireDate;// 入职日期(嵌套Date结构体)floatsalary;// 员工薪资};

2.3 函数声明

structs.c 声明了两个用于处理 Student 结构体的函数:

// 函数声明voidprintStudent(structStudents);// 打印学生信息(值传递)voidupdateGPA(structStudent*s,floatnewGPA);// 更新学生GPA(指针传递,修改原结构体)

2.4 主函数(程序入口)

程序的核心逻辑在main()函数中实现,该函数演示了各种结构体操作并输出结果:

intmain(){// 结构体变量声明与初始化structStudents1={"张三",1001,3.8};// 结构体变量访问printf("=== 学生信息 ===\n");printf("姓名: %s\n",s1.name);printf("学号: %d\n",s1.id);printf("GPA: %.2f\n",s1.gpa);// 结构体指针structStudent*ptr=&s1;printf("\n=== 通过指针访问学生信息 ===\n");printf("姓名: %s\n",ptr->name);printf("学号: %d\n",ptr->id);printf("GPA: %.2f\n",ptr->gpa);// 结构体数组printf("\n=== 学生数组 ===\n");structStudentstudents[3]={{"李四",1002,3.5},{"王五",1003,3.9},{"赵六",1004,3.2}};for(inti=0;i<3;i++){printStudent(students[i]);}// 调用函数修改结构体成员printf("\n=== 修改GPA ===\n");updateGPA(&students[0],3.7);printStudent(students[0]);// 嵌套结构体示例printf("\n=== 员工信息(嵌套结构体)===\n");structEmployeeemp1;strcpy(emp1.name,"钱七");emp1.employeeId=2001;emp1.hireDate.day=15;emp1.hireDate.month=6;emp1.hireDate.year=2020;emp1.salary=5000.0;printf("员工姓名: %s\n",emp1.name);printf("员工ID: %d\n",emp1.employeeId);printf("入职日期: %d/%d/%d\n",emp1.hireDate.day,emp1.hireDate.month,emp1.hireDate.year);printf("薪资: %.2f\n",emp1.salary);return0;}

3. 关键概念与实现

3.1 结构体的定义与声明

结构体是 C 语言中一种用户自定义的数据类型,用于将不同类型的数据组合在一起。其基本语法如下:

struct结构体名{数据类型 成员名1;数据类型 成员名2;// ...};

在 structs.c 中,我们定义了三个结构体:

  • struct Student:表示学生信息
  • struct Date:表示日期
  • struct Employee:表示员工信息(包含嵌套的 Date 结构体)

3.2 嵌套结构体

嵌套结构体是指在一个结构体内部包含另一个结构体类型的成员。在 structs.c 中,Employee结构体包含了一个Date结构体作为其成员:

structEmployee{charname[50];intemployeeId;structDatehireDate;// 嵌套 Date 结构体floatsalary;};

嵌套结构体允许我们更自然地组织相关数据,例如员工的入职日期可以作为员工信息的一部分。

3.3 结构体变量的初始化

结构体变量可以在声明时直接初始化,使用大括号{}来指定各个成员的值:

// 直接初始化结构体变量structStudents1={"张三",1001,3.8};

也可以先声明结构体变量,然后再逐个初始化其成员:

// 先声明结构体变量structEmployeeemp1;// 然后逐个初始化成员strcpy(emp1.name,"钱七");emp1.employeeId=2001;emp1.hireDate.day=15;emp1.hireDate.month=6;emp1.hireDate.year=2020;emp1.salary=5000.0;

3.4 结构体成员的访问

要访问结构体变量的成员,可以使用点运算符.

printf("姓名: %s\n",s1.name);printf("学号: %d\n",s1.id);printf("GPA: %.2f\n",s1.gpa);

对于嵌套结构体的成员访问,需要使用多个点运算符:

printf("入职日期: %d/%d/%d\n",emp1.hireDate.day,emp1.hireDate.month,emp1.hireDate.year);

3.5 结构体指针

结构体指针是指向结构体变量的指针,使用箭头运算符->来访问结构体成员:

// 结构体指针structStudent*ptr=&s1;printf("姓名: %s\n",ptr->name);printf("学号: %d\n",ptr->id);printf("GPA: %.2f\n",ptr->gpa);

结构体指针在函数参数传递中非常有用,可以避免结构体的复制开销,并允许函数修改原结构体的值。

3.6 结构体数组

结构体数组是元素为结构体类型的数组,可以使用嵌套的大括号来初始化:

// 结构体数组structStudentstudents[3]={{"李四",1002,3.5},{"王五",1003,3.9},{"赵六",1004,3.2}};

要访问结构体数组中的元素及其成员,可以结合数组下标和点运算符:

for(inti=0;i<3;i++){printStudent(students[i]);}

3.7 结构体作为函数参数

结构体可以作为函数参数传递,有两种传递方式:

3.7.1 值传递

值传递将结构体变量的副本传递给函数,函数内部的修改不会影响原结构体变量:

// 函数定义:打印学生信息(值传递)voidprintStudent(structStudents){printf("姓名: %s, 学号: %d, GPA: %.2f\n",s.name,s.id,s.gpa);}
3.7.2 指针传递

指针传递将结构体变量的地址传递给函数,函数内部可以通过指针修改原结构体变量:

// 函数定义:更新GPA(使用指针修改原结构体)voidupdateGPA(structStudent*s,floatnewGPA){s->gpa=newGPA;// 使用箭头运算符访问指针指向的结构体成员}

指针传递比值传递更高效,特别是当结构体较大时,可以避免大量数据的复制。

4. 代码流程

structs.c 的执行流程如下:

  1. 引入头文件stdio.hstring.h
  2. 定义 Student 结构体
  3. 定义 Date 结构体和嵌套的 Employee 结构体
  4. 声明 printStudent 和 updateGPA 函数
  5. 主函数入口:
    • 声明并初始化 Student 结构体变量 s1
    • 直接访问 s1 的成员并输出
    • 创建指向 s1 的指针并通过指针访问成员
    • 声明并初始化 Student 结构体数组
    • 调用 printStudent 函数打印数组中每个学生的信息
    • 调用 updateGPA 函数修改第一个学生的GPA
    • 声明并初始化 Employee 嵌套结构体变量
    • 访问并输出 Employee 及其内部 Date 结构体的成员
  6. 程序结束

5. 输出结果

编译并运行 structs.c 后,将得到以下输出:

=== 学生信息 === 姓名: 张三 学号: 1001 GPA: 3.80 === 通过指针访问学生信息 === 姓名: 张三 学号: 1001 GPA: 3.80 === 学生数组 === 姓名: 李四, 学号: 1002, GPA: 3.50 姓名: 王五, 学号: 1003, GPA: 3.90 姓名: 赵六, 学号: 1004, GPA: 3.20 === 修改GPA === 姓名: 李四, 学号: 1002, GPA: 3.70 === 员工信息(嵌套结构体)=== 员工姓名: 钱七 员工ID: 2001 入职日期: 15/6/2020 薪资: 5000.00

6. 补充代码示例

6.1 结构体的动态内存分配

使用malloc()函数为结构体动态分配内存:

#include<stdio.h>#include<stdlib.h>#include<string.h>structStudent{charname[50];intid;floatgpa;};intmain(){// 动态分配结构体内存structStudent*ptr=(structStudent*)malloc(sizeof(structStudent));if(ptr==NULL){printf("内存分配失败\n");return1;}// 初始化结构体成员strcpy(ptr->name,"孙八");ptr->id=1005;ptr->gpa=3.6;// 访问结构体成员printf("姓名: %s\n",ptr->name);printf("学号: %d\n",ptr->id);printf("GPA: %.2f\n",ptr->gpa);// 释放动态分配的内存free(ptr);return0;}

6.2 结构体的 typedef

使用typedef关键字为结构体类型创建别名,简化结构体的使用:

#include<stdio.h>#include<string.h>// 使用 typedef 为结构体创建别名typedefstruct{charname[50];intid;floatgpa;}Student;// Student 是结构体的别名// 使用 typedef 为嵌套结构体创建别名typedefstruct{intday;intmonth;intyear;}Date;typedefstruct{charname[50];intemployeeId;Date hireDate;// 使用别名 Datefloatsalary;}Employee;// Employee 是结构体的别名intmain(){// 直接使用别名创建结构体变量Student s1={"周九",1006,3.8};Employee emp1;strcpy(emp1.name,"吴十");emp1.employeeId=2002;emp1.hireDate.day=20;emp1.hireDate.month=8;emp1.hireDate.year=2021;emp1.salary=5500.0;printf("学生姓名: %s\n",s1.name);printf("员工姓名: %s\n",emp1.name);printf("入职日期: %d/%d/%d\n",emp1.hireDate.day,emp1.hireDate.month,emp1.hireDate.year);return0;}

6.3 结构体数组的动态内存分配

使用malloc()函数为结构体数组动态分配内存:

#include<stdio.h>#include<stdlib.h>#include<string.h>structStudent{charname[50];intid;floatgpa;};intmain(){intn=3;// 动态分配结构体数组内存structStudent*students=(structStudent*)malloc(n*sizeof(structStudent));if(students==NULL){printf("内存分配失败\n");return1;}// 初始化结构体数组strcpy(students[0].name,"郑十一");students[0].id=1007;students[0].gpa=3.9;strcpy(students[1].name,"王十二");students[1].id=1008;students[1].gpa=3.7;strcpy(students[2].name,"赵十三");students[2].id=1009;students[2].gpa=3.5;// 访问结构体数组for(inti=0;i<n;i++){printf("学生 %d: %s, %d, %.2f\n",i+1,students[i].name,students[i].id,students[i].gpa);}// 释放动态分配的内存free(students);return0;}

7. 编译和运行

7.1 使用 GCC 编译

在命令行中,可以使用以下命令编译 structs.c:

gcc structs.c -o structs -fexec-charset=gbk

7.2 运行程序

编译成功后,根据您的操作系统,使用以下命令运行程序:

  • Windows:

    .\structs.exe
  • Linux/macOS:

    ./structs

8. 注意事项

8.1 结构体成员的访问

  • 直接访问结构体变量的成员使用点运算符.
  • 访问结构体指针指向的成员使用箭头运算符->

8.2 字符串成员的初始化

对于结构体中的字符串成员,不能直接使用赋值运算符=来初始化或修改,需要使用strcpy()函数:

// 错误的方式emp1.name="钱七";// 字符串数组不能直接赋值// 正确的方式strcpy(emp1.name,"钱七");// 使用 strcpy 函数复制字符串

8.3 结构体的大小

结构体的大小可能大于其所有成员大小的总和,这是因为编译器为了提高访问效率会对结构体成员进行内存对齐。可以使用sizeof()运算符来获取结构体的实际大小。

8.4 内存管理

如果使用malloc()等函数动态分配了结构体内存,必须使用free()函数及时释放内存,避免内存泄漏。

9. 总结

structs.c 提供了 C 语言中结构体操作的基本示例,涵盖了结构体的定义、初始化、访问、嵌套、指针、数组以及作为函数参数等核心概念。通过学习这些示例,您可以掌握 C 语言中结构体处理的基础知识。

此外,我们还补充了结构体的动态内存分配、typedef 别名以及结构体数组的动态内存分配等高级操作的示例代码,帮助您进一步扩展对 C 语言结构体处理的理解。

在实际编程中,结构体是一种非常重要的数据类型,它允许我们将相关的数据组织在一起,提高代码的可读性和可维护性。特别是在处理复杂数据结构(如链表、树等)时,结构体是不可或缺的基础。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/10 10:54:47

基于SpringBoot+Vue的乡镇农村建设用地管理系统的设计与实现

前言 &#x1f31e;博主介绍&#xff1a;✌CSDN特邀作者、全栈领域优质创作者、10年IT从业经验、码云/掘金/知乎/B站/华为云/阿里云等平台优质作者、专注于Java、小程序/APP、python、大数据等技术领域和毕业项目实战&#xff0c;以及程序定制化开发、文档编写、答疑辅导等。✌…

作者头像 李华
网站建设 2026/6/9 23:48:38

解析:One-API 与 New-API 核心原理

One-API 与 New-API 都是用于统一管理和分发大模型API的工具&#xff0c;但其设计理念、核心架构和功能侧重点存在显著差异。下面将详细解析它们的工作原理&#xff0c;并进行对比。一、One-API 的工作原理One-API 的工作原理可以概括为&#xff1a;作为一个统一的API网关&…

作者头像 李华
网站建设 2026/6/10 10:51:46

【MongoDB实战】第10章 新手避坑指南:90%的人都会踩的错误

文章目录 《MongoDB实战入门》第10章 新手避坑指南:90%的人都会踩的错误 10.1 连接与配置类错误 10.1.1 连接字符串配置错误 错误场景与实战示例 正确配置与实战代码 标准连接字符串格式 正确实操代码(Python驱动) 10.1.2 服务启动失败 场景1:端口占用 排查与解决实战 场景…

作者头像 李华
网站建设 2026/6/10 10:58:34

【图数据库与知识图谱】第一部分:基石篇——图与图谱的基本认知

文章目录 第1章 图论基础:古老数学的现代逆袭 1.1 图论简史与核心思想:从“七桥问题”到“万物互联” 1.2 图的基本构成:3个要素搞定“关系建模” 1.3 图的类型:4种常见类型,覆盖不同场景 1.3.1 无向图:关系是“双向的” 1.3.2 有向图:关系是“单向的” 1.3.3 属性图:带…

作者头像 李华
网站建设 2026/6/10 10:51:19

基于三电平SVPWM改进技术的异步电机感应电机直接转矩控制性能研究参考文献参考研究及其优劣对比

基于三电平SVPWM改进的异步电机/感应电机直接转矩控制发波方式用三电平SVPWM&#xff0c;相比较于两电平SVPWM和滞环离线开关表发波方式&#xff0c;整体的控制性能有很大的改善。 提供对应的参考文献;直接转矩控制&#xff08;DTC&#xff09;这玩意儿在电机控制圈子里算是经典…

作者头像 李华
网站建设 2026/6/10 10:54:05

零基础学AI大模型:从环境搭建到实战应用的完整入门指南_大模型从入门到精通,从看这篇开始

本文为AI大模型零基础学习者提供全面入门指南&#xff0c;涵盖大模型基础概念、学习环境搭建、机器学习与深度学习基础知识、预训练模型使用与微调方法&#xff0c;以及实战项目实践。通过系统学习&#xff0c;小白可逐步掌握从环境配置到模型应用的全流程&#xff0c;为进入AI…

作者头像 李华