[C语言初阶]结构体初阶

在这里插入图片描述

目录

  • 一、结构体的声明
  • 二、结构体的定义和初始化
  • 三、结构体成员访问
  • 四、结构体传参
  • 五、函数调用的参数压栈(了解)

在C语言中,我们知道数组是一组相同类型元素的集合,而结构体则更为灵活,它允许我们将不同类型的数据组合在一起,形成一个新的复合数据类型。本文将带你全面了解结构体的基础知识,从声明定义到成员访问,再到最后的结构体传参。


一、结构体的声明

结构体的声明使用struct关键字,其基本语法如下:

struct 结构体标签 {类型 成员1;类型 成员2;// 更多成员...
};

与数组不同,结构体的成员可以是不同类型的变量。例如,我们可以创建一个学生结构体:

struct Stu {char name[20];  // 姓名int age;        // 年龄float score;    // 成绩
};

声明结构体后,我们可以创建该类型的变量:

struct Stu s;  // 创建一个Stu类型的结构体变量s

当然我们也可以在声明结构体的同时创建变量(此时创建的是全局变量(因为在{}外定义)):

struct Stu {char name[20];int age;float score;
} s1, s2;  // 全局变量s1和s2

而上面的在main函数内部创建的则是局部变量。

二、结构体的定义和初始化

结构体的初始化与数组类似,使用花括号{}进行初始化:

struct Stu s = {"张三", 18, 90.5};

当结构体嵌套时(即成员中包含另一个结构体),可以使用嵌套的花括号来对结构体进行初始化:

struct Date {int year;int month;int day;
};struct Student {char name[20];struct Date birthday;  // 嵌套结构体
};struct Student stu = {"李四", {2000, 5, 20}};

三、结构体成员访问

访问结构体成员有两种方式:

  1. 使用.操作符直接访问:
struct Stu s;
strcpy(s.name, "王五");
s.age = 19;
s.score = 88.5;
  1. 当有结构体指针时,使用->操作符:
struct Stu s;
struct Stu *ps = &s;
ps->age = 20;  // 等价于 (*ps).age = 20;

如在这里ps->age,表示的意思是ps先找到指向的结构体变量s,再找其成员变量age

四、结构体传参

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

  1. 传值调用:传递整个结构体对象的副本
void printStudent(struct Stu s) {printf("姓名: %s, 年龄: %d, 成绩: %.1f\n", s.name, s.age, s.score);
}// 调用
printStudent(s);
  1. 传址调用:传递结构体的指针
void printStudent(struct Stu *ps) {printf("姓名: %s, 年龄: %d, 成绩: %.1f\n", ps->name, ps->age, ps->score);
}// 调用
printStudent(&s);

这两种方式我们推荐使用传址调用,原因如下:

  • 效率更高:传值调用需要临时拷贝整个结构体,会消耗更多内存和时间。而传址调用只需传递一个指针(32位系统4字节,64位系统8字节),大大提高了传参效率。
  • 功能更强大:通过指针可以直接修改原结构体的值,而传值调用只能操作副本。

五、函数调用的参数压栈(了解)

在函数调用过程中,参数会被"压栈"(push onto the stack)。栈是一种先进后出(LIFO)的数据结构:

  • 每次函数调用都会在内存的栈区开辟一段空间
  • 参数通常从右向左依次压栈
  • 例如Add(a, b)调用时,先压入b,再压入a

了解函数栈帧的创建和销毁有助于深入理解函数调用机制,这相当于我们编程能力的"内功"。


结构体是C语言中非常重要的自定义数据类型,它允许我们将不同类型的数据组合成一个整体。通过本文,我们介绍了:

  1. 如何声明和定义结构体
  2. 结构体的初始化和成员访问方法
  3. 结构体传参的两种方式(优先使用传址调用)
  4. 函数调用时的参数压栈机制(了解)

掌握结构体的基础知识是学习更高级数据结构的前提,也是编写复杂程序的必备技能。在实际开发中,结构体经常与指针配合使用,能够极大地提高程序的灵活性和效率。在下一章,我们将介绍一些实用的调试技巧,敬请期待!

作者其他文章链接:
初识C语言—人生若只如初见(完结撒花!)
[C语言初阶]指针初阶
[C语言初阶]操作符
[C语言初阶]扫雷小游戏
Gitee详细使用教程

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/91180.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/91180.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LVS(Linux Virtual Server)集群技术详解

一.集群和分布式: 集群:同一个业务系统,部署在多台服务器上,集群中,每一台服务器实现的功能没有差别,数据和代码都是一样的 分布式:一个业务被拆成多个子业务,或者本身就是不同的业务&#…

leetcode_27 移除元素

1. 题意 给定一个数组,把不等于val的元素全部移动到数组的前面来。 不需要考虑值为val里的元素。 2. 题解 2.1 同向双指针 我们利用双指针,慢指针指向下一个插入的位置。而快指针不断向前找到首个不为val的值,找到后将快指针位置值赋给慢…

Linux-Ubuntu下的git安装与配置

一、安装git1.打开终端,运行以下命令(需要联网)sudo apt-get update sudo apt-get install git2.验证安装安装完成之后,通过运行以下命令验证git是否已经正确安装:git --version二、配置git2.1.配置用户名及邮箱地址在…

2D和3D激光slam的点云去运动畸变

在使用激光雷达设备采集点云的时候,我们都知道,激光雷达是边运动边采集的,每一个点云采集时的激光雷达的中心和姿态都是不一样的,如果不加以矫正,那么这一帧数据就会出现问题,比如采集一个平面的结构的时候…

Java 热门面试题 200 道(Markdown表格版)【简化版】

Java 热门面试题 200 道(Markdown表格版)【简化版】 Java与数据库核心面试题摘要 本文精选200道Java与数据库高频面试题,重点涵盖: Java集合: HashMap原理(数组+链表/红黑树)、ConcurrentHashMap分段锁优化、红黑树改进目的(解决哈希冲突性能问题) MySQL索引: 最左前…

OpenCV探索之旅:多尺度视觉与形状的灵魂--图像金字塔与轮廓分析

在我们学会用Canny算法勾勒处世界的轮廓之后,一个更深层次的问题摆在了面前:这些由像素组成的线条,如何才能被赋予“生命”,成为我们能够理解和分析的“形状”?如果一个物体在图像中时大时小,我们又该如何稳…

Redis作缓存时存在的问题及其解决方案

Redis最常用的一个场景就是作为缓存,本文主要探讨Redis作为缓存,在实践中可能会有哪些问题?比如一致性, 穿击, 穿透, 雪崩, 污染等。 为什么要理解Redis缓存问题 在高并发的业务场景下,数据库大多数情况都是用户并发访问最薄弱的…

day17 力扣654.最大二叉树 力扣617.合并二叉树 力扣700.二叉搜索树中的搜索 力扣98.验证二叉搜索树

最大二叉树给定一个不重复的整数数组 nums 。 最大二叉树 可以用下面的算法从 nums 递归地构建:创建一个根节点,其值为 nums 中的最大值。递归地在最大值 左边 的 子数组前缀上 构建左子树。递归地在最大值 右边 的 子数组后缀上 构建右子树。返回 nums 构建的 最大…

天地图前端实现geoJson与wkt格式互转

geoJson与wkt都是WebGIS开发中经常用到的格式,天地图行政区划边界接口返回的是wkt格式数据,需要转换一下。 安装插件:terraformer/wkt npm install terraformer/wkt 两个函数: .wktToGeoJSON(WKT) ⇒ object.geojsonToWKT(Geo…

(1-7-3)数据库的基本查询

目录 1. 数据库的基本查询 1.1 简单的记录查询 1.2 使用列别名 2. 数据分页查询 (1)查询前五行数据 (2)查询 11 ~ 15 行数据 3. 结果集排序 3.1 单关键字排序 (1)升序排列 (2&#…

宝塔配置pgsql可以远程访问及pdo_pgsql扩展的安装

本地navicat premium 17.0 可以远程访问pgsql v16.1宝塔的软件商店里,找到pgsql管理器;在pgsql管理器里找到客户端认证:第二步:配置修改,CtrlF 查找listen_addresses关键字;第三步:在navicat里配…

SQL进阶:自连接的用法

目录 一、可重排列、排列、组合 1、创建表 2、录入数据 3、获取可重排列的商品名称(有序) 4、获取排列的商品名称(有序) 5、获取组合的商品名称(无序) 6、获取3个元素的组合商品名称(无序…

Spark集群优化配置指南

Spark集群优化配置指南 📋 概述 本文档记录了5节点Spark集群的性能优化配置,主要解决Thrift Server内存不足(OOM)问题和CPU资源利用率低的问题。 文档内容 Spark架构原理: Driver与Executor的关系和工作机制Driver内存配置详解: 三个关键内存参数的作用和…

Layui —— select

前言:记录在修改bug时遇到的一些奇怪问题。遇到的奇怪问题1:项目中引入了 layui,而且也使用了 layui.use 按需导入了需要的组件,但是在页面每次刚初始化的时候去使用layui,控制台都会报 组件未定义的问题(正…

代码随想录day32dp1

文章目录509. 斐波那契数70. 爬楼梯746. 使用最小花费爬楼梯确定dp数组(dp table)以及下标的含义 确定递推公式 dp数组如何初始化 确定遍历顺序 举例推导dp数组509. 斐波那契数 题目链接 文章讲解 class Solution { public:int fib(int n) {// 1. 确定…

RedisJSON 技术揭秘`JSON.ARRTRIM`用窗口裁剪,让数组保持“刚刚好”

1、指令速查 JSON.ARRTRIM <key> <path> <start> <stop>key&#xff1a;Redis 键名path&#xff1a;JSONPath&#xff0c;默认 $ 根&#xff1b;可用 .[*]/.. 多路径匹配start / stop&#xff1a;要保留的 [start, stop] 闭区间索引 支持负值&#xff…

fpga调试经验

fpga调试经验 调测场景&#xff1a; 外接adc传感器芯片&#xff0c;采集压力&#xff0c;温度等模拟量&#xff0c;fpga通过spi/i2c接口与adc传感器芯片通信 问题1&#xff1a;adc芯片在稳定环境中&#xff0c;输出数字量不稳定。 结论&#xff1a;adc输入电压由fpga板供应&…

cefSharp.WinForms.NETCore 138.xx (cef138/Chromium 138.0.7204.97) 升级测试体验

一、版本说明及变化 该版本支持cef138.0.x系列,cefsharp138.0.170 无重大更新;该版本暂不支持h264,请关注后续 关注栏目,关注我,学习cefsharp少走弯路 不迷路! CefSharp 设置缓存的注意事项参考 说明:栏目是订阅文章,无附件,如需要单独获取(看底部介绍说明) 该版本1…

chatgpt是怎么诞生的,详解GPT1到GPT4的演化之路及相关背景知识

人工智能革命正在发生&#xff0c;我们是何其幸运的一代&#xff0c;能亲眼见证人类/机器智能的大爆发。 仅仅作为这场革命的看客显然是有些遗憾的&#xff0c;如何进一步了解它&#xff1f; 本文将讨论chatgpt的诞生过程&#xff0c;串联起OpenAI发表的一系列重要论文&#…

[笔记] 动态 SQL 查询技术解析:构建灵活高效的企业级数据访问层

文章目录一. 应用场景二. 使用示例示例1示例2示例3三. 实现1. 动态表查询构建器&#xff0c;模仿MyBatis-Plus2. mapper3. mapper.xml功能概述参数说明四. 动态 SQL 的优化与风险防控在企业级应用开发中&#xff0c;数据查询场景往往呈现出复杂多变的特点 —— 从简单的单表筛选…