news 2026/6/9 16:11:28

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/9 16:11:26

专业的康有利到家理疗小程序哪家好

专业的康有利到家理疗小程序哪家好在当今数字化时代&#xff0c;到家理疗服务借助小程序得到了更广泛的推广与应用。康有利到家理疗小程序为用户提供了便捷的理疗服务预约途径&#xff0c;那么专业的康有利到家理疗小程序哪家好呢&#xff1f;市场现状分析目前市场上的康有利到…

作者头像 李华
网站建设 2026/6/8 10:04:02

大模型RAG技术深度剖析:提升AI回答质量的黑科技

本文详细解读了RAG&#xff08;检索增强生成&#xff09;技术&#xff0c;分析了其解决LLMs幻觉、知识过时等问题的意义&#xff0c;介绍了RAG系统的三大发展范式&#xff08;朴素、高级、模块化&#xff09;&#xff0c;探讨了检索、生成、增强环节的关键技术和评估方法&#…

作者头像 李华
网站建设 2026/6/8 10:04:00

STM32学习——编码器接口测速

1.编码器接口测速1.基本要点1.void TIM_EncoderInterfaceConfig(TIM_TypeDef* TIMx, uint16_t TIM_EncoderMode,uint16_t TIM_IC1Polarity, uint16_t TIM_IC2Polarity);//配置定时器编码器接口模式的核心函数&#xff0c;用于将定时器配置为编码器模式&#xff0c;实现对正交编…

作者头像 李华
网站建设 2026/6/9 10:07:20

学Simulink——基础MPPT控制场景实例:基于Simulink的电导增量法(INC)光伏MPPT仿真

目录 手把手教你学Simulink 一、引言:为什么“扰动观察法在快速变化光照下会‘跑偏’”?——因为P&O仅比较前后功率大小,无法区分MPP左侧还是右侧;当光照突变时,( dP ) 符号可能误判,导致反向远离MPP! 二、电导增量法(INC)原理 1. 光伏功率对电压求导 2. 判断…

作者头像 李华
网站建设 2026/6/8 7:01:38

评论笔记 - Cordova 与 OpenHarmony 混合开发实战

欢迎大家加入开源鸿蒙跨平台开发者社区&#xff0c;一起共建开源鸿蒙跨平台生态。 &#x1f4cc; 模块概述 评论笔记模块是MovieTracker应用中用于记录和管理影片评论的功能。用户可以为影片添加详细的评论笔记&#xff0c;记录观影感受、剧情分析、演员表现等。评论笔记支持编…

作者头像 李华
网站建设 2026/6/6 2:46:58

备份恢复模块 - Cordova与OpenHarmony混合开发实战

欢迎大家加入开源鸿蒙跨平台开发者社区&#xff0c;一起共建开源鸿蒙跨平台生态。 &#x1f4cc; 概述 备份恢复模块用于数据的备份和恢复。这个模块支持自动备份和手动备份&#xff0c;用户可以定期备份应用数据以防止数据丢失。通过Cordova框架&#xff0c;我们能够在Web层实…

作者头像 李华