当前位置: 首页 > news >正文

【重新认识C语言----结构体篇】

目录

-----------------------------------------begin-------------------------------------

引言

1. 结构体的基本概念

1.1 为什么需要结构体?

1.2 结构体的定义

2. 结构体变量的声明与初始化

2.1 声明结构体变量

2.2 初始化结构体变量

3. 结构体成员的访问

3.1 使用点运算符(.)

3.2 结构体指针与箭头运算符(->)

4. 结构体的内存布局

4.1 内存对齐规则

4.2 手动控制内存对齐

5. 结构体的高级用法

5.1 结构体数组

5.2 嵌套结构体

5.3 结构体与函数

5.4 使用typedef简化结构体类型名

6. 结构体与联合体(Union)的区别

7. 综合示例:学生管理系统

8. 常见问题与注意事项

结语

路过的佬们点点关注哦~

你们的鼓励是我前进的动力~

-------------------------------------------end-------------------------------------


-----------------------------------------begin-------------------------------------

引言

在C语言编程中,结构体(Structure) 是一种非常重要的复合数据类型。它允许开发者将多个不同类型的变量组合成一个逻辑单元,从而更高效地管理复杂数据。无论是实现链表、树等数据结构,还是描述现实世界中的实体(如学生、商品等),结构体都扮演着核心角色。本文将详细讲解结构体的定义、使用及高级特性,帮助读者彻底掌握这一关键概念。


1. 结构体的基本概念

1.1 为什么需要结构体?

假设我们需要描述一个学生的信息,包括姓名(字符串)、学号(整数)、年龄(整数)和成绩(浮点数)。如果单独使用多个变量来存储这些信息,代码会变得冗长且难以维护。例如:

char name[20];
int id;
int age;
float score;

结构体可以将这些变量封装为一个整体,使数据管理更加清晰。

1.2 结构体的定义

结构体通过 struct 关键字定义,语法如下:

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

示例:定义一个学生结构体

struct Student {char name[20];int id;int age;float score;
};

2. 结构体变量的声明与初始化

2.1 声明结构体变量

结构体定义后,可以通过两种方式声明变量:

  1. 在定义结构体时直接声明变量

    struct Student {// 成员定义
    } stu1, stu2;  // 直接声明变量stu1和stu2

  2. 通过结构体类型名声明变量

    struct Student stu3;  // 声明一个Student类型的变量stu3

    2.2 初始化结构体变量

    结构体变量可以在声明时初始化,或通过赋值操作初始化。
    示例:

// 声明时初始化
struct Student stu1 = {"Alice", 1001, 18, 90.5};// 单独赋值初始化
struct Student stu2;
strcpy(stu2.name, "Bob");
stu2.id = 1002;
stu2.age = 19;
stu2.score = 85.0;

3. 结构体成员的访问

3.1 使用点运算符(.

通过 . 运算符可以直接访问结构体变量的成员:

printf("学生姓名:%s\n", stu1.name);
printf("学号:%d\n", stu1.id);

3.2 结构体指针与箭头运算符(->

如果通过指针访问结构体成员,需使用 -> 运算符:

struct Student *pStu = &stu1;
printf("年龄:%d\n", pStu->age);  // 等价于 (*pStu).age

4. 结构体的内存布局

4.1 内存对齐规则

为了提高内存访问效率,结构体的成员在内存中遵循对齐规则:

  • 对齐数(Alignment):成员的大小与编译器默认对齐数中的较小值。

  • 起始地址:每个成员的起始地址必须是对齐数的整数倍。

  • 总大小:结构体的总大小是对齐数最大值的整数倍。

示例:

struct Example {char c;     // 1字节,对齐数为1int i;      // 4字节,对齐数为4double d;   // 8字节,对齐数为8
};

内存布局分析:

  • char c 占1字节,起始地址0。

  • int i 对齐数为4,起始地址需是4的倍数,因此填充3字节(地址1~3),起始地址4。

  • double d 对齐数为8,起始地址8。
    总大小 = 1 + 3(填充) + 4 + 8 = 16字节。

4.2 手动控制内存对齐

通过 #pragma pack(n) 可以修改默认对齐数(n为1、2、4、8等):

#pragma pack(1)  // 设置为1字节对齐
struct PackedExample {char c;int i;double d;
};
#pragma pack()   // 恢复默认对齐

此时结构体总大小为 1 + 4 + 8 = 13字节。

5. 结构体的高级用法

5.1 结构体数组

结构体数组用于存储多个相同类型的结构体变量。
示例:

struct Student students[3] = {{"Alice", 1001, 18, 90.5},{"Bob", 1002, 19, 85.0},{"Charlie", 1003, 20, 92.0}
};

5.2 嵌套结构体

结构体可以嵌套其他结构体作为成员。
示例:

struct Date {int year;int month;int day;
};struct Employee {char name[20];struct Date birthday;
};

5.3 结构体与函数

结构体可以作为函数参数或返回值传递。
示例:

// 函数参数:按值传递
void printStudent(struct Student stu) {printf("姓名:%s\n", stu.name);
}// 函数参数:按指针传递(推荐,避免内存拷贝)
void updateScore(struct Student *pStu, float newScore) {pStu->score = newScore;
}// 函数返回结构体
struct Student createStudent() {struct Student stu = {"David", 1004, 21, 88.5};return stu;
}

5.4 使用typedef简化结构体类型名

通过 typedef 可以为结构体定义别名,简化代码:

typedef struct Student {// 成员定义
} Student;  // 别名// 声明变量
Student stu4;

6. 结构体与联合体(Union)的区别

结构体与联合体(union)的区别在于内存分配方式:

  • 结构体:每个成员拥有独立的内存空间,总大小为所有成员大小之和(考虑对齐)。

  • 联合体:所有成员共享同一块内存空间,总大小等于最大成员的大小。

7. 综合示例:学生管理系统

#include <stdio.h>
#include <string.h>typedef struct Student {char name[20];int id;float score;
} Student;void printStudent(const Student *stu) {printf("姓名:%s\t学号:%d\t成绩:%.1f\n", stu->name, stu->id, stu->score);
}int main() {Student students[3];// 输入学生信息for (int i = 0; i < 3; i++) {printf("输入第%d个学生的姓名、学号和成绩:", i+1);scanf("%s %d %f", students[i].name, &students[i].id, &students[i].score);}// 输出学生信息printf("\n学生列表:\n");for (int i = 0; i < 3; i++) {printStudent(&students[i]);}return 0;
}

8. 常见问题与注意事项

  • 结构体赋值

    结构体变量可以直接赋值给同类型的变量(按值拷贝):

Student stu1 = {"Alice", 1001, 90.5};
Student stu2 = stu1;  // 合法,内存拷贝
  • 结构体大小计算

    使用 sizeof 运算符获取结构体大小,但需注意内存对齐的影响。

  • 结构体与动态内存分配

    结构体指针可以结合 malloc 实现动态内存分配:

Student *pStu = (Student*)malloc(sizeof(Student));
free(pStu);

结语

结构体是C语言中组织复杂数据的核心工具,其灵活性和高效性使其在系统编程、嵌入式开发等领域广泛应用。通过本文的学习,读者应能够熟练定义、操作结构体,并理解其底层内存布局。建议结合实际项目练习,进一步巩固这一重要概念。

路过的佬们点点关注哦~
你们的鼓励是我前进的动力~

-------------------------------------------end-------------------------------------

相关文章:

【重新认识C语言----结构体篇】

目录 -----------------------------------------begin------------------------------------- 引言 1. 结构体的基本概念 1.1 为什么需要结构体&#xff1f; 1.2 结构体的定义 2. 结构体变量的声明与初始化 2.1 声明结构体变量 2.2 初始化结构体变量 3. 结构体成员的访…...

#渗透测试#批量漏洞挖掘#Splunk Enterprise for Windows 任意文件读取漏洞( CVE-2024-36991)

免责声明 本教程仅为合法的教学目的而准备&#xff0c;严禁用于任何形式的违法犯罪活动及其他商业行为&#xff0c;在使用本教程前&#xff0c;您应确保该行为符合当地的法律法规&#xff0c;继续阅读即表示您需自行承担所有操作的后果&#xff0c;如有异议&#xff0c;请立即停…...

苹果公司宣布正式开源 Xcode 引擎 Swift Build145

2025 年 2 月 1 日&#xff0c;苹果公司宣布正式开源 Xcode 引擎 Swift Build145。 Swift 是苹果公司于 2014 年推出的一种开源编程语言&#xff0c;用于开发 iOS、iPadOS、macOS、watchOS 和 tvOS 等平台的应用程序。 发展历程 诞生&#xff1a;2014 年&#xff0c;苹果在全球…...

7.list

本篇博客梳理C的STL中的list容器 一、list的基本结构与使用 1&#xff0e;list的介绍 list的底层是带头循环双向链表 带头&#xff1a;含哨兵位 循环&#xff1a;尾节点的next指针指向哨兵位 双向&#xff1a;每个节点具有两个指针域&#xff0c;一个指针指向前一个结点 2…...

Qt+海康虚拟相机的调试

做机器视觉项目的时候&#xff0c;在没有相机或需要把现场采集的图片在本地跑一下做测试时&#xff0c;可以使用海康的虚拟相机调试。以下是设置步骤&#xff1a; 1.安装好海康MVS软件&#xff0c;在菜单栏->工具选择虚拟相机工具&#xff0c;如下图&#xff1a; 2.打开虚拟…...

数据库基础练习4(有关索引,视图完整解答)

建立需要的表 学生表 mysql> create table studnet(sno int primary key auto_increment,sname varchar(30) not null unique,ssex varchar(2) check (ssex男 or ssex女) not null ,sage int not null,sdept varchar(10) default 计算机 not null); Query OK, 0 rows affe…...

实操给触摸一体机接入大模型语音交互

本文以CSK6 大模型开发板串口触摸屏为例&#xff0c;实操讲解触摸一体机怎样快速增加大模型语音交互功能&#xff0c;使用户能够通过语音在一体机上查询信息、获取智能回答及实现更多互动功能等。 在本文方案中通过CSK6大模型语音开发板采集用户语音&#xff0c;将语音数据传输…...

Excel中对单列数据进行去重筛选

在Excel中对单列数据进行去重筛选&#xff0c;可以按照以下步骤操作&#xff1a; 方法一&#xff1a;使用“删除重复项”功能 选择数据列&#xff1a;点击要处理的列头&#xff08;如A列&#xff09;。打开“删除重复项”&#xff1a; Excel 2007及以后版本&#xff1a;点击“…...

K8s —基础指南(K8s - Basic Guide)

K8s —基础指南 K8s 是云上部署容器化应用的事实标准。它作为容器的强大编排器&#xff0c;管理容器重启、负载均衡等任务。 理解 Kubernetes 架构 Kubernetes 的关键功能之一是为访问 Pod 提供稳定的端点&#xff0c;尽管 Pod 本身是短暂的。Kubernetes 服务有效地弥补了这…...

ABAP开发中的前导零和末尾零

前导零和末尾零是指分别出现在数字序列中第一个非零数字之前和最后一个非零数字之后的任何零数字。 关于前导 0 在 SAP 系统中&#xff0c;大多数字母数字字段在数据库中存储时都带前导零&#xff0c;完全占用字段的定义长度。但是&#xff0c;当字段显示给最终用户时&#x…...

Baklib赋能数字内容体验个性化推荐提升用户体验的未来之路

内容概要 随着数字化时代的不断发展&#xff0c;用户对内容消费的需求日益多样化&#xff0c;个性化推荐成为提升用户体验的重要手段。Baklib以其先进的技术手段&#xff0c;在数字内容领域内积极推动个性化推荐的实施&#xff0c;从而满足用户在信息获取和内容消费中的独特需…...

关于Redis的持久化

目录 RDB 1.手动触发 2.自动触发 AOF aof的重写机制 Redis虽然是一个内存数据库&#xff0c;但是也是可以将数据存储到硬盘中的&#xff0c;也就是持久化。硬盘的数据是在Redis重启的时候&#xff0c;用来恢复内存中的数据的&#xff0c;即对数据做了一个备份。Redis实现持…...

【C语言标准库函数】指数与对数函数:exp(), log(), log10()

目录 一、头文件 二、函数简介 2.1. exp(double x) 2.2. log(double x) 2.3. log10(double x) 三、函数实现&#xff08;概念性&#xff09; 3.1. exp(double x) 的模拟实现 3.2. log(double x) 和 log10(double x) 的模拟实现 四、注意事项 4.1. exp(double x) 的注…...

2024美团春招硬件开发笔试真题及答案解析

目录 一、选择题 1、在 Linux,有一个名为 file 的文件,内容如下所示: 2、在 Linux 中,关于虚拟内存相关的说法正确的是() 3、AT89S52单片机中,在外部中断响应的期间,中断请求标志位查询占用了()。 4、下列关于8051单片机的结构与功能,说法不正确的是()? 5、…...

Python内置函数map(), list(), len(), iter(), hex(), hash()的详细解析,包括功能、语法、示例及注意事项

1. map(function, iterable, ...) 功能&#xff1a;对可迭代对象中的每个元素应用指定函数&#xff0c;返回一个迭代器。 参数&#xff1a; function&#xff1a;要执行的函数&#xff08;可以是lambda表达式&#xff09;。 iterable&#xff1a;一个或多个可迭代对象&#x…...

[LVGL] 在VC_MFC中移植LVGL

前言&#xff1a; 0. 在MFC中开发LVGL的优点是可以用多个Window界面做辅助扩展【类似GUIguider】 1.本文基于VC2022-MFC单文档框架移植lvgl8 2. gitee上下载lvgl8.3 源码&#xff0c;并将其文件夹改名为lvgl lvgl: LVGL 是一个开源图形库&#xff0c;提供您创建具有易于使用…...

MySQL视图索引操作

创建学生表&#xff1b; mysql> create table Student(-> Sno int primary key auto_increment,-> Sname varchar(30) not null unique,-> Ssex char(2) check (Ssex男 or Ssex女) not null,-> Sage int not null,-> Sdept varchar(10) default 计算机 not …...

一次奇怪的空指针问题分析:事务、死锁与隐式回滚

最近我们在排查一个诡异的 空指针异常&#xff0c;整个分析过程可以说是跌宕起伏&#xff0c;最终的结论也颇具隐蔽性。今天就把这个问题分享出来&#xff0c;希望对大家有所帮助。 问题现象 在系统中&#xff0c;我们有 单据 B&#xff0c;它通过一个 关联 ID 字段与 上级单…...

解决aspose将Excel转成PDF中文变成方框的乱码问题

原文网址&#xff1a;解决aspose将Excel转成PDF中文变成方框的乱码问题_IT利刃出鞘的博客-CSDN博客 简介 本文介绍如何解决aspose将Excel转成PDF中文变成方框的乱码问题。 问题描述 用aspose将word、excel等转成PDF后&#xff0c;英文展示正常&#xff0c;但中文全部变成了…...

.net8.0使用EF连接sqlite数据库及使用Gridify实现查询的简易实现

EF Core EF Core 是一个流行的对象关系映射&#xff08;ORM&#xff09;框架&#xff0c;它简化了与数据库的交互&#xff0c;提供了一个高效、灵活且易于使用的数据访问层。 Entity Framework (EF) Core 是轻量化、可扩展、开源和跨平台版的常用 Entity Framework 数据访问技…...

YOLOv8模型剪枝实战:如何利用BN层特性实现高效通道裁剪(附完整代码)

YOLOv8模型剪枝实战&#xff1a;从BN层特性到工程化部署的完整指南 在计算机视觉领域&#xff0c;YOLOv8凭借其卓越的实时检测性能已成为工业界的热门选择。但当我们将模型部署到资源受限的边缘设备时&#xff0c;模型大小和计算效率往往成为瓶颈。本文将深入探讨如何利用BN层γ…...

深入解析GD32/STM32 PWM中断:中央对齐模式的应用与实现

1. PWM中断与中央对齐模式的核心概念 第一次接触PWM中断时&#xff0c;我盯着示波器上跳动的波形发愣——明明配置了中断&#xff0c;为什么触发时机总是不对&#xff1f;后来才发现是计数模式没选对。中央对齐模式&#xff08;Center-Aligned Mode&#xff09;在电机控制、LED…...

为什么SwinIR在图像修复中吊打CNN?深入解析Swin-Transformer的三大优势

SwinIR如何重新定义图像修复&#xff1f;Transformer架构的三大技术革命 当你在手机相册里翻出一张十年前的老照片&#xff0c;却发现它模糊得连人脸都难以辨认时&#xff0c;传统CNN模型或许能帮你恢复部分细节&#xff0c;但边缘依然会显得生硬失真。这正是SwinIR要解决的核心…...

Photoshop AI绘画终极指南:用中文轻松驾驭Stable Diffusion插件

Photoshop AI绘画终极指南&#xff1a;用中文轻松驾驭Stable Diffusion插件 【免费下载链接】Auto-Photoshop-StableDiffusion-Plugin A user-friendly plug-in that makes it easy to generate stable diffusion images inside Photoshop using either Automatic or ComfyUI a…...

告别数据丢失!用ArcMap的‘图层组’功能,一次性搞定Shapefile转KML和标注

告别数据丢失&#xff01;用ArcMap的‘图层组’功能高效实现Shapefile转KML与标注一体化 在GIS数据处理中&#xff0c;Shapefile转KML是常见需求&#xff0c;但保留标注信息往往让用户头疼。传统方法需要分别处理数据和标注&#xff0c;步骤繁琐且容易出错。本文将介绍如何利用…...

计算机网络知识应用:保障分布式StructBERT微服务集群通信

计算机网络知识应用&#xff1a;保障分布式StructBERT微服务集群通信 最近在搞一个基于StructBERT模型的智能问答系统&#xff0c;随着用户量上来&#xff0c;单台服务器明显扛不住了&#xff0c;响应慢不说&#xff0c;还动不动就挂掉。没办法&#xff0c;只能上微服务集群&a…...

Java线程池中如何用TransmittableThreadLocal避免变量丢失?附完整Demo

Java线程池中TransmittableThreadLocal的实战应用与避坑指南 在Java高并发编程中&#xff0c;线程池是提升性能的利器&#xff0c;但线程复用机制却给上下文传递带来了挑战。当我们在父线程设置变量&#xff0c;子线程却无法获取时&#xff0c;这种"断链"现象常让开发…...

UG/NX Block UI Styler字符串控件避坑指南:常见问题与解决方案

UG/NX Block UI Styler字符串控件避坑指南&#xff1a;常见问题与解决方案 在UG/NX二次开发中&#xff0c;Block UI Styler作为可视化对话框设计工具&#xff0c;其字符串控件&#xff08;String Control&#xff09;是使用频率最高的交互元素之一。无论是参数输入、状态显示还…...

基于OFA的智能写作助手:图文内容自动生成与问答

基于OFA的智能写作助手&#xff1a;图文内容自动生成与问答 1. 引言 你有没有遇到过这样的情况&#xff1a;手头有一堆产品图片&#xff0c;却不知道怎么写吸引人的商品描述&#xff1b;或者看到一张复杂的图表&#xff0c;想要快速提取关键信息却无从下手&#xff1b;又或者…...

Local AI MusicGen开箱即用:WebUI汉化+中文Prompt提示模板集成

Local AI MusicGen开箱即用&#xff1a;WebUI汉化中文Prompt提示模板集成 1. 引言 想不想拥有一个私人AI作曲家&#xff1f;不需要你懂五线谱&#xff0c;也不需要昂贵的编曲软件&#xff0c;只要输入几个词&#xff0c;比如“悲伤的小提琴”或者“赛博朋克电子乐”&#xff…...