c语言结构体学习

news2024/9/24 5:32:34

文章目录

  • 前言
  • 一、结构体的声明
    • 1,什么叫结构体?
    • 2,结构体的类型
    • 3,结构体变量的创建和初始化
    • 4,结构体的类型
    • 5,结构体的初始化
  • 二、结构体的访问
    • 1,结构体成员的点操作符访问
    • 2,结构体体成员的指针访问
  • 三、结构体传参


前言

昨天就是新的一年,小编看到了一句话送给各位读者:在过去的一年里,也许你踏足山巅,拥有团花锦簇的风光,也许你进入了低谷,经历了一个人的兵荒马乱,但是没关系的,去年千般未如愿,今年万事定称心。把过去的事儿,过去的人,一块尘封在记忆中不再烦恼,不再怀念。岁月本无语,未来犹可期,我始终如少年,你始终如初见。新的一年,我们看到了盛世的烟火,看到了繁华的街景,在c语言中写出烟花的代码可不是一个简单的小事情,他需要不断的积累,接下来我们学习结构体,在后面小编会给大家讲一些小的c游戏,烟花就需要用到结构体哦!


提示:以下是本篇文章正文内容,下面案例可供参考

一、结构体的声明

1,什么叫结构体?

结构就是一种集合
1,在之前我们学过很多数据类型,但是这些类型是内置类型,能描述的对象是非常有限的
2,但是生活中存在许多复杂对象,复杂对象就是不能用单一的数据去描述的,这时候为了方便描述复杂对象,于是c语言就有了结构体的概念
3,相比于结构体,数组是一组相同类型元素的集合,而结构是一些值的集合,这些值被称为成员变量,结构的每个成员可以是不同的类型

分析

就比如:我们划分一个人的特征
首先是性别,性别为男/女 ,我们存储这个性别用的类型为字符类型
再次是年龄,年龄肯定是正整数,我们定义一个有符号类型的整数来给年龄
然后是身高,身高是一个有小数点的数,所以我们这里可以用浮点型来定义身高
还有很多,在这里我们把人的特征集合在一起这个就是结构,然后这些特征被称为成员变量,每个成员
的变量类型可以相同可以不同

2,结构体的类型

语法形式

struct tag         
{
   member-list ;      
}  variable-list;  

例如:

//人的结构体类型声明
struct people
{
	char name[20]; //名字
	int age;       //年龄
	int height;    //身高
	char   sex[5];   //性别
}p1,p2;
int main()
{

	return 0;
}
分析

在这里tag就是结构体的标签,也就是要描述的东西,也就是复杂对象像上面的例子中的人;member-list是成员列表,在这里面声明成员类型,也就是定义变量,如上方例子中的年龄,性别,身高等;variable-list变量列表,就是我们用上面这个类型来创建变量,这里肯定会有疑惑的,比如int x = 0;这后面是不是有一个分号,然后我们不初始化就是int x;所以简单的来说:也就是说前面的内容都是结构体的类型,然后我们o就是结构体类型的变量。在上面代码中我们创建了两个结构体变量p1和p2.在这里p1和p2是全局变量。而我们在定义变量的时候要尽量用局部变量所以我们需要继续往后学习结构体的变量的创建

3,结构体变量的创建和初始化

在上面我们是在main函数外面声明的全局变量,接下来我们学习结构体的变量创建

struct people
{
	char name[20]; //名字
	int age;       //年龄
	int height;    //身高
	char sex[5];   //性别
};
int main()
{
	struct people p1 = { 0 };//结构体的局部变量
	return 0;
}
}
分析
在这里我们要区分一下结构体的类型是什么,结构体变量是什么,然后在上面你想给变量进行初始化就给他按照上面顺序类型给他赋值,用逗号隔开,不想初始化值,就局部初始全为0;注意这里和数组差不多一样的里面的成员很多,用大括号括起来。

在这里插入图片描述

4,结构体的类型

结构体的成员可以是标量,数组,指针,甚至可以是其他结构体

struct people
{
	char name[20]; //名字
	int age;       //年龄
	int height;    //身高
	char sex[5];   //性别
};
struct team
{
	struct people p;
	int num;
	int class;
};
int main()
{
	struct people p1 = { 0 };//结构体的局部变量
	return 0;
}
分析

在这里我们又创建了一个小组成员的结构体变量,在结构体变量里面我们定义了结构体people类型的变{}量p1,数量,和组别。这里是结构体内使用其他结构体。

5,结构体的初始化

struct people
{
	char name[20]; //名字
	int age;       //年龄
	int height;    //身高
	char sex[5];   //性别
};
struct team
{
	struct people p;
	int num;
	char class[5];
};
int main()
{
	//struct people p1 = { 0 };//结构体的局部变量
	struct people p1 = { "张三",20,175,"男" };
	struct team t = { {"张三",20,175,"男"} ,1,"经理" };
	return 0;
}

在这里插入图片描述

分析
然后在上面你想给变量进行初始化就给他按照上面顺序一一对应类别给他赋值,用逗号隔开,不想初始化值,就局部初始全为0;注意这里和数组差不多一样的里面的成员很多,用大括号括起来。然后结构体嵌套就在里面在加一个大括号描述另一个结构体内的成员就可以。如上方代码。打开监视窗口我们也可以发现它里面的存储情况和我们想的是一样的。如果不是一一对应的话他所赋值给的值不能给到相应的元素。然后出现下面这种情况。 ![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/042756740f48458c9a9d9b3a8ff7a760.png)

二、结构体的访问

1,结构体成员的点操作符访问

结构变量的成员是通过点操作符(.)访问的。点操作符接受两个操作数,结构体变量.结构体成员

     <table><tr><td bgcolor=turquoise>分析  </td></tr></table>

在上面我们只是通过监视窗口来查看结构体内的成员,我们可以将他打印出来么接下来就要用到结构体的访问,也就是我们之前学习的操作符内的结构体操作符,结构体操作符详见小编所写的详解c语言操作符(下篇)

struct people
{
	char name[20]; //名字
	int age;       //年龄
	int height;    //身高
	char sex[5];   //性别
};
struct team
{
	struct people p;
	int num;
	char class[5];
};
int main()
{
	//struct people p1 = { 0 };//结构体的局部变量
	struct people p1 = { "张三",20,175,"男" };
	struct team t = { {"张三",20,175,"男"} ,1,"经理" };
	printf("%s %d %d %s\n",p1.name,p1.age,p1.height,p1.sex);
	printf("%s %d %d %s %d %s", t.p.name, t.p.age, t.p.height, t.p.sex,t.num,t.class);

	return 0;
}

在这里插入图片描述

分析

在这里,成员是内置类型不是指针,所以我们用变量名点成员来访问成员元素。

2,结构体体成员的指针访问

struct people
{
	char name[20]; //名字
	int age;       //年龄
	int height;    //身高
	char sex[5];   //性别
};
struct team
{
	struct people p;
	int num;
	char class[5];
};
void print(struct people* p)
{
	printf("%s %d %d %s\n", p->name, p->age, p->height, p->sex);
}
int main()
{
	//struct people p1 = { 0 };//结构体的局部变量
	struct people p1 = { "张三",20,175,"男" };
	struct team t = { {"张三",20,175,"男"} ,1,"经理" };
	//printf("%s %d %d %s\n",p1.name,p1.age,p1.height,p1.sex);
	//printf("%s %d %d %s %d %s", t.p.name, t.p.age, t.p.height, t.p.sex,t.num,t.class);

	print(&p1);
	return 0;
}

在这里插入图片描述

分析
在这里我们把之前的打印注释掉,然后我们创建一个print函数来打印结构体变量p1,在这里我们对他进行取地址,然后接受的就是结构体指针变量,在print函数里面打印结构体变量p1的成员,这时候的变量p是指针变量,我们就不能用点操作符来访问结构体成员了我们得用箭头操作符来访问找到指针结构体成员。如上面代码所示,我们运行后还是正确的结果。

三、结构体传参

结构体传参其实我们在上面结构体的访问中就已经详细的说了,但是刚才是举例说明结构体的两种访问形式,显而易见,结构体传参也有两种传参形式,一种是直接将结构体变量本身传参,另一种则是传结构体的地址。

struct people
{
	char name[20]; //名字
	int age;       //年龄
	int height;    //身高
	char sex[5];   //性别
};
struct team
{
	struct people p;
	int num;
	char class[5];
};
void print1(struct people p)
{
	printf("%s %d %d %s\n", p.name, p.age, p.height, p.sex);  //结构体变量.成员变量
}
void print(struct people* p)
{
	printf("%s %d %d %s\n", p->name, p->age, p->height, p->sex);  //结构体指针 -> 成员变量
}
int main()
{
	//struct people p1 = { 0 };//结构体的局部变量
	struct people p1 = { "张三",20,175,"男" };
	struct team t = { {"张三",20,175,"男"} ,1,"经理" };
	printf("%s %d %d %s\n",p1.name,p1.age,p1.height,p1.sex);  
	printf("%s %d %d %s %d %s\n", t.p.name, t.p.age, t.p.height, t.p.sex,t.num,t.class);

	print1(p1);
	print(&p1);
	return 0;
}
分析

在这里print1中传参传递的就是结构体变量本身,print则是转递的是结构体的指针,将结构体变量的地址取出来传给print函数。在这里我们想让print1和print都打印p1的数据,而我们两个传参方式都做到了,达到了同样的效果,在这里我们看到p1如下图:在这里p1传参给p,也就是实参传参给形参,在之前函数的时候小编就说了,当实参传给形参时,形参就是实参的一份临时拷贝,所以我们在打印p的时候就是在打印p1的数据,但是,结构体传参把对象进行传参,是不是先拷贝在给他,如果结构体内成员多,这时候浪费的时间就多,在者进行对象传参,如果结构体成员多,那么我们需要开辟的空间也就越多,造成了空间浪费。
在这里插入图片描述

而在这里我们把p1的地址传过去,而指针大小无非就是四个字节或者八个字节,相对于把对象传参不用花费太多时间占用太大内存,而我们形参接受指针地址,后面也可以直接通过地址找到p1中的对象。
在这里插入图片描述

结论
函数传参的时候,参数需要压栈,如果传递一个结构体对象的时候结构体过大,参数压栈的系统开销比较大,所以会导致性能的下降。**因此,在结构体传参的时候,我们建议用指针传参的方式进行传参。**

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

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

相关文章

【解决】Unity 设置跨设备分辨率表现

开发平台&#xff1a;Unity 2018版本以上 开发语言&#xff1a;CSharp 编程平台&#xff1a;Visual Studio 2022   问题描述 使用 UnityEngine.dll 中关于设置分辨率的方法时&#xff0c;无法满足应用以设定分辨率进行屏幕显示问题。因而造成画面不同程度的拉伸情况。而这种情…

【Java】接口和抽象类有什么共同点和区别?

个人简介&#xff1a;Java领域新星创作者&#xff1b;阿里云技术博主、星级博主、专家博主&#xff1b;正在Java学习的路上摸爬滚打&#xff0c;记录学习的过程~ 个人主页&#xff1a;.29.的博客 学习社区&#xff1a;进去逛一逛~ 【Java】接口和抽象类有什么共同点和区别&…

工作流入门这篇就够了!

总概 定义&#xff1a;工作流是在计算机支持下业务流程的自动或半自动化&#xff0c;其通过对流程进行描述以及按一定规则执行以完成相应工作。 应用&#xff1a;随着计算机技术的发展以及工业生产、办公自动化等领域的需求不断提升&#xff0c;面向事务审批、材料提交、业务…

力扣hot100 对称二叉树 递归 队列

&#x1f468;‍&#x1f3eb; 题目地址 &#x1f468;‍&#x1f3eb; 参考思路 递归的难点在于&#xff1a;找到可以递归的点 为什么很多人觉得递归一看就会&#xff0c;一写就废。 或者说是自己写无法写出来&#xff0c;关键就是你对递归理解的深不深。 对于此题&#xf…

day04 两两交换链表中的节点 删除链表的倒数第N个节点 链表相交 环形链表Ⅱ

题目1&#xff1a;24 两两交换链表中的节点 题目链接&#xff1a;24 两两交换链表中的节点 题意 两两交换链表中相邻的节点&#xff0c;返回交换后链表的头节点 虚拟头节点 注意终止条件&#xff0c;考虑节点的奇偶数&#xff0c;根据奇偶数确定终止条件 注意定义中间变量…

Amos各版本安装指南

Amos下载链接 https://pan.baidu.com/s/1uyblN8Q-knNKkqQVlNnXTw?pwd0531 1.鼠标右击【Amos28】压缩包&#xff08;win11及以上系统需先点击“显示更多选项”&#xff09;选择【解压到 Amos28】。 2.打开解压后的文件夹&#xff0c;鼠标右击【Amos28】选择【以管理员身份运行…

干洗店洗鞋店小程序核心功能有哪些?

在繁忙的生活中&#xff0c;我们的鞋子常常承载着风尘仆仆的故事。而洗鞋小程序&#xff0c;就是那个让您的鞋子焕然一新的魔法师。通过这个小程序&#xff0c;您可以在线预约、支付&#xff0c;查询洗鞋订单&#xff0c;并与洗鞋店铺进行互动&#xff0c;轻松享受专业的洗鞋服…

计算机毕业设计 基于SpringBoot的工作量统计系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

计算机毕业设计------经贸车协小程序

项目介绍 本项目分为三种用户类型&#xff0c;分别是租赁者&#xff0c;车主&#xff0c;管理员用户&#xff1b; 管理员用户包含以下功能&#xff1a; 管理员登录,个人中心,租赁者管理,车主管理,赛事活动管理,车类别管理,租车管理,租车订单管理,车辆出售管理,购买订单管理,…

数据结构第2章 栈和队列

名人说&#xff1a;莫听穿林打叶声&#xff0c;何妨吟啸且徐行。—— 苏轼《定风波莫听穿林打叶声》 本篇笔记整理&#xff1a;Code_流苏(CSDN)&#xff08;一个喜欢古诗词和编程的Coder&#x1f60a;&#xff09; 目录 0、思维导图栈和队列1、栈1&#xff09;特点2&#xff0…

计算机网络【Cookie和session机制】

会话&#xff08;Session&#xff09;跟踪是Web程序中常用的技术&#xff0c;用来跟踪用户的整个会话。常用的会话跟踪技术是Cookie与Session。Cookie通过在客户端记录信息确定用户身份&#xff0c;Session通过在服务器端记录信息确定用户身份。 本章将系统地讲述Cookie与Sess…

Springboot集成RabbitMq二

接上一篇&#xff1a;Springboot集成RabbitMq一-CSDN博客 1、搭建项目-消费者 与之前一样 2、创建配置类 package com.wym.rabbitmqconsumer.utils;import org.springframework.amqp.core.Binding; import org.springframework.amqp.core.BindingBuilder; import org.spring…

RabbitMQ集群的简单说明

1.普通集群(副本集群) 当集群中某一时刻master主节点宕机&#xff0c;可以对master中Queue中的消息进行备份。而就算master宕机了&#xff0c;从节点不会对外提供服务&#xff0c;等到master节点恢复后&#xff0c;系统才会恢复正常。 主从架构的缺点是队列中的消息只是位于主节…

流量预测资源总结(不断更新)

目录 整理流量预测数据集&#xff08;1&#xff09;Telecom Italia 意大利电信 2015&#xff08;2&#xff09;City Cellular Traffic Map (C2TM) 2015&#xff08;3&#xff09;、LTE Network Traffic Data_kaggle&#xff08;4&#xff09;、Cellular Traffic Analysis Data …

ROS学习笔记(8)进一步深入了解ROS第二步

0.前提 在上一讲中我提到过该系列是基于宾夕法尼亚大学工程学院的ROS公开课&#xff0c;系列文章将来源于公开课中的课后习题。该系列可以很好的帮助大家更加深入的了解ROS的一些概念。&#xff08;有效面对HR的提问。&#xff09; 1. (C)What is a nodehandle object? Can we…

解读 $mash 通证 “Fair Launch” 规则,将公平发挥极致

Solmash 是 Solana 生态中由社区主导的铭文资产 LaunchPad 平台&#xff0c;该平台旨在为 Solana 原生铭文项目&#xff0c;以及通过其合作伙伴 SoBit 跨链桥桥接到 Solana 的 Bitcoin 生态铭文项目提供更广泛的启动机会。有了 Solmash&#xff0c;将会有更多的 Solana 生态的铭…

OpenCV中实现图像旋转的方法

OpenCV中实现图像旋转的方法 函数&#xff1a;cv2.flip() 功能&#xff1a;水平或者垂直翻转 格式&#xff1a;dst cv2.flip(src,flipCode[,dst]) 参数说明&#xff1a; src&#xff1a;输入图像 dst&#xff1a;和原图像具有相同大小、类型的目标图像。 flipCode&#…

Docker中的核心概念

1.镜像 Image 一个镜像就代表一个软件。mysql镜像、redis镜像、mq镜像 2.容器 Container 一个镜像运行一次就会生成一个容器&#xff0c;容器就是一个运行的软件服务。 3.远程仓库 Repository 远程仓库用来存储所有软件的镜像&#xff0c;Docker Hub 4.本地仓库 用来存储…

对偶问题的基本性质

写于&#xff1a;2024年1月3日晚 修改于&#xff1a; 原规划与对偶规划 原规划对偶规划 max ⁡ z C T X s.t. { A X ≤ b , 其中 X ( m ∗ 1 ) X ≥ 0 \begin{aligned} & \max \mathrm{z}\mathbf{C}^T \mathbf{X} \\ & \text { s.t. }\left\{\begin{array}{l}\mat…

教育机构培训系统小程序功能清单

制作一款适合自己的教育机构培训系统小程序&#xff0c;可以为学员提供更便捷的学习体验&#xff0c;同时提高机构的教学效率。今天将详细介绍如何使用乔拓云平台制作教育机构培训系统小程序。 在浏览器搜索乔拓云&#xff0c;登录到后台&#xff0c;选择教育系统并点击进入。在…