结构体小知识

news2024/9/16 10:09:39

目录

  • 前言
  • 1.结构体数组
    • 1.1结构体数组理解
    • 1.2结构体数组知识运用
    • 1.3 -> 操作符
  • 2. 知识拓展

前言

本期blog是对上一期指针知识的知识补充,如果各位大佬感兴趣的话,可以结合起来一起看!
在这里插入图片描述

1.结构体数组

1.1结构体数组理解

结构体数组在本质上是数组,里面存放的是结构体的数据。

1.2结构体数组知识运用

现在我们举例来讲解。首先创建一个结构体的类型,之后用该结构体的类型创建一个数组,可以类比int类型的数组进行创建,并用大括号括起来。现在假设我们有一个结构体,里面有一个int类型的数组arr,arr里面有1000个元素,再有一个int类型的n。

struct S
{
	int arr[1000];
	int n;
};

在主函数部分创建一个名字为s的变量,并对它进行初始化。

struct S
{
	int arr[1000];
	int n;
};

int main()
{
	struct S s = { {1,2,3,4,5},100 };
	return 0;
}

现在我们要对s里面的数据进行修改,这里我不采用直接使用s.n = 200的方式进行修改。我添加一个函数(set_stu)对s进行修改。在函数的形参部分我采用一个结构体变量来接收,并在函数里面对数据进行修改。我们可以添加一个print_stu函数打印看看。

#include<stdio.h>
struct S
{
	int arr[1000];
	int n;
};

void set_stu(struct S t)
{
	t.n = 200;
	t.arr[0] = -1;
	t.arr[1] = -2;
}

void print_stu(struct S t)
{
	printf("n = %d\n", t.n);
	int i = 0;
	for (i = 0; i < 5; i++)
	{
		printf("%d ", t.arr[i]);
	}
}

int main()
{
	struct S s = { {1,2,3,4,5},100 };
	set_stu(s);
	print_stu(s);
	return 0;
}

运行结果:
在这里插入图片描述
但是运行结果显示里面的数据并没有发生改变。那是哪里出问题了呢?
在主函数中,我们用s进行传参,传给set_stu函数的t,这叫做值传递。s有自己的空间,此处的t也有自己的空间。这里我们将数据传给了t,再对t进行改变,并不会影响到s,所以在打印时s的值不变。
该问题可以通过传址解决。我们可以将结构体变量s的地址传过去,把set_stu函数的形参部分改为结构体指针(ps)进行接收,并把该函数里面的内容也进行修改。

#include<stdio.h>
struct S
{
	int arr[1000];
	int n;
};

void set_stu(struct S* ps)
{
	(*ps).n = 200;
	(*ps).arr[0] = -1;
	(*ps).arr[1] = -2; 
}

void print_stu(struct S t)
{
	printf("n = %d\n", t.n);
	int i = 0;
	for (i = 0; i < 5; i++)
	{
		printf("%d ", t.arr[i]);
	}
}

int main()
{
	struct S s = { {1,2,3,4,5},100 };
	set_stu(&s);
	print_stu(s);
	return 0;
}

运行结果:
在这里插入图片描述
该写法是对指针变量进行解引用,然后找到结构体变量进行修改。但是还有其他的方法。

1.3 -> 操作符

#include<stdio.h>
struct S
{
	int arr[1000];
	int n;
};

void set_stu(struct S* ps)
{
	ps->n = 200;
	ps->arr[0] = -1;
	ps->arr[1] = -2;
}

void print_stu(struct S t)
{
	printf("n = %d\n", t.n);
	int i = 0;
	for (i = 0; i < 5; i++)
	{
		printf("%d ", t.arr[i]);
	}
}

int main()
{
	struct S s = { {1,2,3,4,5},100 };
	set_stu(&s);
	print_stu(s);
	return 0;
}

运行结果:
在这里插入图片描述
该方法更加直观,这种写法用到了->(操作符)。
注意:
该操作符的左边一定要是结构体的指针变量,右边是成员名。
在这里插入图片描述

2. 知识拓展

思考:
在print_stu函数这里需要传递s的地址吗?在这里我们仅仅是为了打印。
分析:
之前进行运行的时候,我们发现该函数是能够完成该功能的,即不传址也可以。print_stu函数的t得到的是改变后s的数据,并照着去打印。但是我建议还是尽量传址。
尽量传址的原因:
在这个例子中,我创建了一个非常大的结构体,这里的结构体对象很大,4000个字节加上n。在主函数部分创建s的时候,是一块非常大的空间。如果采用值传递时,t的创建也需要一块非常大的空间,此时就会有空间上的浪费。除此之外,拷贝数据过去时,时间和空间上都造成了浪费,即时间和空间的双重开销。当然这是理论上的,如果编译器在这方面做了优化,这又是另外一回事。

现在我们将地址传过去,并把print_stu函数的形参部分改为指针(ps)。

#include<stdio.h>
struct S
{
	int arr[1000];
	int n;
};

void set_stu(struct S* ps)
{
	ps->n = 200;
	ps->arr[0] = -1;
	ps->arr[1] = -2;
}

void print_stu(struct S* ps)
{
	printf("n = %d\n", ps->n);
	int i = 0;
	for (i = 0; i < 5; i++)
	{
		printf("%d ", ps->arr[i]);
	}
}

int main()
{
	struct S s = { {1,2,3,4,5},100 };
	set_stu(&s);
	/*print_stu(s);*/
	print_stu(&s);

	return 0;
}

在这里插入图片描述
现在我们传地址的话,就传递了4个字节或8个字节,之前我们说过一个地址的大小为4个字节或8个字节。在压栈时,只会指针变量压了一个栈,此时我们并没有创建两个结构体。所以只是为了打印数据,值传递也行,能解决问题。但是还是建议尽量传递地址,采用传址的形式。

结论
结构体传参的时候,尽量传递地址。

好了,今天我们的结构体知识就讲到这里。如果文章内容有误,请大佬在评论区斧正!谢谢大家!

在这里插入图片描述

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

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

相关文章

关系的规范化与范式详解

在数据库设计中&#xff0c;关系的规范化是确保数据结构合理性、减少冗余和异常的关键步骤。如果你是一个数据库设计的初学者&#xff0c;这篇文章将为你深入浅出地讲解 关系规范化 和 范式 的核心概念&#xff0c;并通过简洁的示例帮助你加深理解。 关系的规范化&#xff1a;…

JavaScript进阶day1

目录 1.作用域 1.1 局部作用域 1.2 全局作用域 1.3 作用域链 1.4 JS垃圾回收机制 1.4.1 什么是垃圾回收机制&#xff1f; 1.4.2 内存的生命周期 1.4.3 算法说明 1.5 闭包 1.6 变量提升 2.函数进阶 2.1 函数提升 2.2 函数参数 2.2.1 动态参数 2.2.2 剩余参数 2.…

GB2312编码(加2020H、8080H原理)

区位码、内码、国标码 转换及原理 背景答题思考相关资料 背景 问题: 某汉字的国标码为5650H&#xff0c;那么它的机内码为&#xff08; B &#xff09;。A E6E0H B D6D0H C C6C0H D 8080H答题 思考 为什么要加上2020H和8080H&#xff1f;区位码、内码、国标码怎么转换非常简单…

【硬件知识】关于RAM的“那些事”

文章目录 一、DRAM&#xff08;动态随机存取存储器&#xff09;二、SRAM&#xff08;静态随机存取存储器&#xff09;三、DRAM和SRAM的差异与区别 一、DRAM&#xff08;动态随机存取存储器&#xff09; 工作原理&#xff1a;DRAM使用电容来存储数据。每一位数据通过一个电容和…

【深度学习讲解笔记】第1章-机器学习基础

1.机器学习是什么 机器学习&#xff08;Machine Learning&#xff0c;ML&#xff09;&#xff0c;顾名思义就是让机器学会做一件事情&#xff0c;比如语音识别&#xff0c;机器听一段声音&#xff0c;产生这段声音对应的文字。或是识别图片中有几个人&#xff0c;几辆车。这些…

2024年语音识别转文字工具的崛起

无论是繁忙的会议记录、远程教学的即时笔记&#xff0c;还是日常生活的语音备忘&#xff0c;只需轻轻一说&#xff0c;便能瞬间转化为清晰可编辑的文字&#xff0c;这种便捷与高效无疑为现代生活增添了无限可能。本文将带你深入探索语音识别转文字工具的奥秘。 1.365在线转文字…

【Python篇】matplotlib超详细教程-由入门到精通(上篇)

文章目录 第一部分&#xff1a;基础概念与简单绘图1.1 matplotlib 简介1.2 创建第一个折线图1.3 图表的基本组成元素 第二部分&#xff1a;图表样式与修饰2.1 修改图表样式2.2 添加图例2.3 调整坐标轴与刻度 第三部分&#xff1a;绘制不同类型的图表3.1 散点图 (Scatter Plot)3…

使用 Homebrew 在 macOS 上安装 Conda

Homebrew 是一个流行的 macOS 包管理器&#xff0c;可以帮助你安装和管理各种软件包。 以下是使用 Homebrew 安装 Conda 的步骤&#xff1a; 1. 安装 Homebrew 如果你还没有安装 Homebrew&#xff0c;可以通过以下命令安装&#xff1a; /bin/bash -c "$(curl -fsSL htt…

《机器学习》—— XGBoost(xgb.XGBClassifier) 分类器

文章目录 一、XGBoost 分类器的介绍二、XGBoost&#xff08;xgb.XGBClassifier&#xff09; 分类器与随机森林分类器&#xff08;RandomForestClassifier&#xff09;的区别三、XGBoost&#xff08;xgb.XGBClassifier&#xff09; 分类器代码使用示例 一、XGBoost 分类器的介绍…

微信小程序 自定义组件

1. 微信小程序 自定义组件 微信小程序支持组件化开发&#xff0c;这有助于我们复用代码&#xff0c;提高开发效率。下面我将给出一个简单的微信小程序组件化示例&#xff0c;包括一个自定义组件的创建和使用。 1.1. 创建自定义组件 首先&#xff0c;在项目的 components 目录…

建筑二次供水的基本概念

什么是二次供水&#xff1f; 二次供水是城市供水的主要组成部分&#xff0c;是指集中式供水在入户之前经再度储存、加压和消毒后&#xff0c;通过管道输送给用户的供水方式。 为什么要使用二次供水&#xff1f; 由于市政供水的服务水压通常只能达到较低的楼层&#xff0c;而…

部分库函数及其模拟

前言&#xff1a;当我们学习c/c库函数的时候&#xff0c;我们可以用网站 cplusplus.com - The C Resources Network 来进行查阅&#xff0c;学习。 目录 库函数&#xff1a; 1.字符串函数 1.1求字符串长度 strlen 1.2长度不受限制的字符串函数 1.2.1strcpy 1.2.2strca…

“阡陌云旅”黄河九省文化旅游平台

“阡陌云旅”黄河九省文化旅游平台 GitHub地址&#xff1a;https://github.com/guoJiaQi-123/Yellow-River-Cloud-Journey 项目背景 “阡陌云旅”黄河九省文化旅游平台 “阡陌云旅” 黄河九省文化旅游平台是一个专注于黄河流域九省文化旅游资源整合与推广的项目。 黄河是中…

Spring Framework系统框架

序号表示的是学习顺序 IoC&#xff08;控制反转&#xff09;/DI&#xff08;依赖注入&#xff09;: ioc&#xff1a;思想上是控制反转&#xff0c;spring提供了一个容器&#xff0c;称为IOC容器&#xff0c;用它来充当IOC思想中的外部。 我的理解就是spring把这些对象集中管理…

HomeAssistant添加HACS绑定米家与苹果HomeKit设备并实现远程管理

文章目录 前言1. 下载HACS源码2. 添加HACS商店3. 绑定米家设备 前言 之前介绍过如何实现在群晖NAS使用Docker部署HomeAssistant&#xff0c;通过内网穿透在户外控制家庭智能设备。本文将介绍如何在HA平台安装HACS插件商店&#xff0c;将米家&#xff0c;果家设备接入 Home Ass…

推荐清晖一套不错的讲解沟通的线上讲座

推荐清晖一套不错的讲解沟通的线上讲座&#xff0c;比较实际贴地&#xff0c;听完了推荐给大家&#xff1a; 《项目管理中的沟通策略&#xff0c;听出弦外之音&#xff0c;变身沟通达人》 地址&#xff1a;项目管理中的沟通策略&#xff0c;听出弦外之音&#xff0c;变身沟通达…

数据结构(1):ArrayList和顺序表

数据结构(Data Structure)是计算机存储、组织数据的方式&#xff0c;指相互之间存在一种或多种特定关系的数据元素的集合。 下面我们就开一个新坑&#xff0c;数据结构。数据结构&#xff0c;简单来说就是存放数据的方式&#xff0c;这些方式多种多样&#xff0c;我们来一点一…

Statcounter Global Stats 提供全球统计数据信息

Statcounter Global Stats 提供全球统计数据信息 1. Statcounter Global Stats2. Mobile & Tablet Android Version Market Share WorldwideReferences Statcounter Global Stats https://gs.statcounter.com/ Statcounter Global Stats are brought to you by Statcounte…

C++ 定时器

这是第一次独立设计一个模块&#xff0c;从接口定义&#xff0c;模块组合到多线程并发可能遇到的各种问题&#xff0c;虽然定时挺简单的&#xff0c;但是想设计精度高&#xff0c;并且能应对高并发似乎也不是很容易&#xff0c;当然&#xff0c;最后没有测试定时器的代码&#…

架构模式:MVC

引言 MVC&#xff0c;即 Model&#xff08;模型&#xff09;-View&#xff08;视图&#xff09;-Controller&#xff08;控制器&#xff09;&#xff0c;是广泛应用于交互式系统中的典型架构模式&#xff0c;尤其在 GUI 和 Web 应用中。 MVC 的概念源自 GOF&#xff08;Gang …