C语言第十八课:初阶结构体

news2024/10/7 12:22:52

目录

前言:

一、结构体类型的声明:

        1.结构的基础知识:

        2.结构的声明:

        3.结构成员允许的类型:

        4.结构体变量的定义:

        5.结构体变量的初始化:

二、结构体成员的访问:

        1.结构体变量访问成员:

        2.结构体指针访问指向变量的成员:

三、结构体传参:

四、总结:


前言:

        上周因为考试复习和放假等等原因导致你们勤奋的銮同学停更了近一周,为了弥补上周的停更,这两天我也开启了狂暴日更模式,辛苦各位路过的小伙伴们给我点点关注点点赞,让我有继续狂暴下去的动力,鄙人在此谢过各位大佬了!

        上文中我们学习了初阶指针的相关知识,已经对指针有了一定程度的了解和理解,对于指针的应用也是有了一定的心得,关于更深层次的内容我将会在初阶C语言全部介绍完毕后,开启进阶模块为各位小伙伴们进行讲解。而本文我将带领小伙伴们了解下一章节关于结构体的内容。

一、结构体类型的声明:

        1.结构的基础知识:

        我们常常将结构称为结构体,结构是一系列值的集合,这些值我们称之为成员变量。结构的每个成员可以是不同类型的变量。这里我们应当进行区分:

数组:一组相同类型的集合

结构:一系列允许类型不同成员的集合

        结构体存在的意义是,在我们的日常生活中存在着许许多多的复杂对象,而这些复杂对象具有许许多多的属性难以通过某种单一类型的值进行描述,例如:

学生”的属性:姓名年龄性别成绩等等

著作”的属性:书名书号作者定价等等

        于是我们就通过使用结构体这样包含一系列可以为不同类型的值的集合描述我们想要描述的复杂对象

        2.结构的声明:

        与函数使用相同,结构在使用前也需要声明,它的声明格式为:

struct tag
//tag为程序员可以根据需求自定义的标签名
{
	member_list;
	//成员列表,含有一到多个

}variable_list;
//variable_list为变量列表,用于在声明结构类型的同时定义变量(可以没有)

        例如我们在描述“学生”这个复杂变量时可以这样去声明:

struct student
//student为我们根据描述对象“学生”自定义的标签名
{
    //结构成员可以是不同类型的变量:
	char name[20];
	//成员:姓名
	int age;
	//成员:年龄
	char sex[5];
	//成员:性别
	float score;
	//成员:成绩
};

        3.结构成员允许的类型:

        结构的成员可以是标量(有大小无方向)、数组指针,甚至是其它结构体(结构体支持嵌套)。

        4.结构体变量的定义:

        结构体的定义有两种方式,一种是在声明类型的同时定义结构体变量,另一种是在主函数内定义结构体变量

#define _CRT_SECURE_NO_WARNINGS 1

#include<stdio.h>

struct student
{
	char name[20];
	int age;
	char sex[5];
	float score;

}s1,s2;
//定义结构体变量s1、s2
//此处定义的结构体变量是全局的

struct student s3, s4;
//定义结构体变量s3、s4
//此处定义的结构体变量等同于声明时定义,也是全局的

int main()
{
	struct student s5, s6;
	//定义结构体变量s5、s6
	//此处定义的结构体变量是局部的

	return 0;
}

        两种定义方式均可,但也有所不同。在声明结构体类型时所定义的结构体变量是全局的,而在主函数内定义结构体变量则是局部的。

        5.结构体变量的初始化:

        结构体变量在进行初始化时同样有两种方式,一种是在声明时定义并进行初始化,另一种是在主函数内定义并进行初始化

#define _CRT_SECURE_NO_WARNINGS 1

#include<stdio.h>

struct student
{
	char name[20];
	int age;
	char sex[5];
	float score;

}s1 = { "Zhang",21,"Man",98.4 };
//初始化结构体变量s1,此处的结构体变量是全局的

struct student s2 = { "Wang",20,"Woman",99.5 };
//初始化结构体变量s2,此处初始化的结构体变量等同于声明时初始化,也是全局的

int main()
{
	struct student s3 = { "Jiao",21,"Man",67.2 };
	//初始化结构体变量s3,此处的结构体变量是局部的

	printf("%s %d %s %.1lf\n", s1.name, s1.age, s1.sex, s1.score);
	printf("%s %d %s %.1lf\n", s2.name, s2.age, s2.sex, s2.score);
	printf("%s %d %s %.1lf\n", s3.name, s3.age, s3.sex, s3.score);

	return 0;
}

        并且同样的,在声明结构体类型时所定义并初始化的结构体变量是全局的,而在主函数内定义并初始化结构体变量则是局部的:

        值得一提的是,结构体在进行初始化时允许进行嵌套初始化

#define _CRT_SECURE_NO_WARNINGS 1

#include<stdio.h>

struct student
{
	char name[20];
	int age;
	char sex[5];
	float score;

};

struct id
{
	struct student s1;
	//结构体允许嵌套初始化
	char id[20];
};

int main()
{
	struct id ID1 = { {"Zhang",21,"Man",98.4 },"2028224096" };
	printf("%s %d %s %.1lf %s\n", ID1.s1.name, ID1.s1.age, ID1.s1.sex, ID1.s1.score, ID1.id);

	return 0;
}

        代码运行起来依然可以得到我们想要的结果

二、结构体成员的访问:

        1.结构体变量访问成员:

        结构体变量访问成员是指,通过点操作符 ' . ' 对结构体变量成员进行访问。点操作符接受两个操作数,一个是结构体变量名,一个是结构体成员名

#define _CRT_SECURE_NO_WARNINGS 1

#include<stdio.h>

struct AGE
{
	int age;
};

void Printf(struct AGE str)
{
	printf("该同学的年龄为:%d\n", str.age);
}

int main()
{
	struct AGE A1 = { 21 };
	//定义并初始化结构体变量A1

	printf("该同学的年龄为:%d\n", A1.age);
	//通过点操作符访问结构体变量A1的结构体成员age
	//点操作符接受两个操作数,一个是结构体变量名A1,另一个是结构体成员名age

	Printf(A1);

	return 0;
}

        如此就可以实现结构体变量对成员的访问了:

        2.结构体指针访问指向变量的成员:

        而有些时候我们得到的不是一个结构体变量,而是指向一个结构体变量的指针,那么在这种情况下,我们又该如何去访问结构体成员呢?答案是,使用结构体指针访问指向变量的成员

#define _CRT_SECURE_NO_WARNINGS 1

#include<stdio.h>

struct AGE
{
	int age;
};

void Printf(struct AGE* str)
//接收结构体地址
{
	printf("该同学的年龄为:%d\n", (*str).age);
	//使用结构体指针访问指向对象的成员

	printf("该同学的年龄为:%d\n", str->age);
	//或使用'->'操作符,也能实现使用结构体指针访问指向对象的成员
}

int main()
{
	struct AGE A1 = { 21 };
	//定义并初始化结构体变量A1

	Printf(&A1);
	//给结构体地址传参

	return 0;
}

        通过使用结构体指针,我们成功的访问了指向变量的成员

三、结构体传参:

        类似于函数,在函数中访问结构体成员时,也存在着传值调用与传址调用的问题。为了研究这个问题,我们直接上代码进行研究:

#define _CRT_SECURE_NO_WARNINGS 1

#include<stdio.h>

struct TEST
{
	int test;
};

//结构体传参
void Printf1(struct TEST test1)
{
	printf("打印测试用例Printf1:%d\n", test1.test);
}

//结构体地址传参
void Printf2(struct TEST* test1)
{
	printf("打印测试用例Printf2:%d\n", test1->test);
}

int main()
{
	struct TEST test1 = {666};

	Printf1(test1);
	//传值调用:传结构体
	Printf2(&test1);
	//传址调用:传结构体地址

	return 0;
}

        那么上面的两种调用方式哪一种更好呢?我们认为应当首选 Printf2 函数。原因是函数在传参时参数是需要压栈的,即将整个结构体变量的所有成员数据全部拷贝至函数执行时所创建的临时空间。那么假设在传递结构体对象的时候,结构体过大,参数压栈的系统开销有可能会很大,这种情况下将会导致我们计算机系统的性能的下降

        结论:我们在进行结构体传参时应当传递结构体的地址

四、总结:

        那么到这里,今天我们关于初阶结构体的学习就结束啦。关于结构体的知识其实还有很多,而我们今天学习的目标仅仅只是让各位小伙伴们能够学会使用结构体,关于结构体更深层次的知识点,我们将在后续的进阶模块全部为各位小伙伴们做更加详细的全面介绍。

        通过今天的学习,想必各位小伙伴们已经学会了结构体的使用,大家如果仍然存有疑问,或者对于结构体的使用有自己的一些想法,可以在课下多多尝试,用实验来进行求证。如果实在无法解决,也欢迎各位先伙伴们私信我,我会竭尽我个人所能,为各位小伙伴们答疑解惑。懒惰不会让你一下子跌倒,但会在不知不觉中减少你的收获;勤奋也不会让你一夜成功,但会在不知不觉中积累你的成果!

        新人初来乍到,辛苦各位小伙伴们动动小手,三连走一走 ~ ~ ~  最后,本文仍有许多不足之处,欢迎各位看官老爷随时私信批评指正!

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

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

相关文章

[附源码]计算机毕业设计实验室管理系统Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

4 第一个程序

第一个程序 1 源程序 源程序中包括两种指令&#xff1a;伪指令和汇编指令 汇编指令是有对应机器码的指令&#xff0c;可以用CPU直接执行 伪指令没有对应的机器码&#xff0c;只有编译器执行不用CPU执行 1.1 segment ends segment和ends的功能是定义一个段。使用格式如下 …

[附源码]计算机毕业设计三星小区车辆登记系统Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

多线程中的公平锁、非公平锁、可重入锁、死锁【详细总结】

目录公平锁非公平锁公平锁和非公平锁的用法可重入锁synchronized可重入锁示例ReentrantLock的示例代码死锁死锁产生的原因常用解决死锁的方法判断程序是否发生死锁死锁的案例&#xff08;面试会问&#xff09;公平锁 多个线程按照申请锁的顺序去获得锁&#xff0c;线程会直接进…

第十六章 Dijkstra算法的讲解以及证明(与众不同的通俗证明)

第十六章 Dijsktra算法的讲解以及粗略证明一、Dijkstra的用途二、Dijkstra的思想及证明&#xff08;1&#xff09;相关结论及证明&#xff1a;结论1&#xff1a;必须借助中间点时某个点到终点的最短路程&#xff1d;该点到中间点的最短距离&#xff0b;中间点到终点的最短距离结…

数据分析思维(一)|信度与效度思维

信度与效度思维 1、概念 信度与效度思维通常用于在数据分析中进行更有价值的指标选择。 信度&#xff1a;指标的可靠程度。包括一致性及稳定性。&#xff08;口径是否一致&#xff0c;是否具有波动性&#xff09; 效度&#xff1a;指标的有效性。一个数据或指标的生成&…

JavaFX项目打包成可安装exe文件

开发环境&#xff1a;Windows 10 2H JDK&#xff1a;jdk1.8.0_112 IDEA&#xff1a;2020.3 1. 项目中导入插件依赖 <plugin><groupId>io.github.fvarrui</groupId><artifactId>javapackager</artifactId><version>1.6.6</version>&…

[附源码]计算机毕业设计JAVA婴幼儿玩具共享租售平台

[附源码]计算机毕业设计JAVA婴幼儿玩具共享租售平台 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM …

Java学习之多态一

目录 一、入门案例 Food类 Animal类 Master类 运行测试 分析 运行结果 问题总结 二、方法的多态 三、对象的多态&#xff08;重难点/核心&#xff09; 四个非常重要的知识点&#xff08;背诵&#xff09; 举例说明 父类-Animal类 子类-Dog类 子类-Cat类 运行-Po…

如何将数据库从 CloudKit 迁移到 Firebase

为什么要迁移 如果该服务仅支持 Apple 设备,则使用 CloudKit 和 CoreData 可能是最佳选择。但是,如果您还需要支持 Web 和 Android,情况就不同了。 当同时支持Web和Android时,可以使用CloudKit JS访问iCloud DB。但是实施起来比较困难,需要有苹果账号。 如果未来有同时支…

【滤波跟踪】基于北方苍鹰和粒子群算法优化粒子滤波器实现目标滤波跟踪附matlab代码

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;修心和技术同步精进&#xff0c;matlab项目合作可私信。 &#x1f34e;个人主页&#xff1a;Matlab科研工作室 &#x1f34a;个人信条&#xff1a;格物致知。 更多Matlab仿真内容点击&#x1f447; 智能优化算法 …

[nacos]nacos2.x+nginx集群搭建以及过程中遇到的坑

参考文档 nacos官方集群部署说明centos7安装并配置jdknacos2.x集群实现centos7安装mysql8使用nginx反代nacos报错 badrequest 400 环境准备 vmware虚拟机上跑的centos7 (原本内存2g 坑点之一!2g内存无法启动三台nacos集群,官方说明需要4g)centos7安装并配置jdk8 安装教程参考 …

Mongoose【node.js的优雅mongodb对象建模】

Mongoose基础运行流程&#xff1a; 文章目录Mongoose基础运行流程&#xff1a;官方 Docs 地址1. 安装&#xff1a;2. 使用&#xff1a;2.1 目录结构&#xff1a;2.2 初始化连接实例 [ 创建 DBHelper.js ]2.2.1 链接地址书写格式[ mongoose.connect&#xff08;参数格式 &#x…

java计算机毕业设计ssm网络相册设计sepo8(附源码、数据库)

java计算机毕业设计ssm网络相册设计sepo8&#xff08;附源码、数据库&#xff09; 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。…

机器学习笔记之受限玻尔兹曼机(四)推断任务——边缘概率

机器学习笔记之受限玻尔兹曼机——推断任务[边缘概率]引言回顾&#xff1a;场景构建推断任务——边缘概率求解边缘概率与Softplus函数引言 上一节介绍了受限玻尔兹曼机中随机变量节点的后验概率&#xff0c;本节将介绍随机变量结点的边缘概率。 回顾&#xff1a;场景构建 已…

木聚糖-氨基|Xylan-NH2|木聚糖-聚乙二醇-氨基|氨基-PEG-木聚糖

木聚糖-氨基|Xylan-NH2|木聚糖-聚乙二醇-氨基|氨基-PEG-木聚糖 Xylan-NH2 木聚糖-氨基 中文名称&#xff1a;木聚糖-氨基 英文名称&#xff1a;Xylan-NH2 别称&#xff1a;氨基修饰木聚糖&#xff0c;氨基-木聚糖 PEG分子量可选&#xff1a;350、550、750、1k、2k、34k、5…

统计学-双变量相关分析-相关系数、相关比、克莱姆相关系数

双变量相关分析根据变量的数据类型不同而不同。当数值数据和数值数据计算相关性时&#xff0c;指标为相关系数&#xff1b;数值数据和类别数据计算相关性时&#xff0c;指标为相关比&#xff1b;类别数据和类别数据计算相关性时&#xff0c;指标为克里姆相关系数。 1 计算公式…

基于现代深度学习的目标检测方法综述

论文地址&#xff1a;A Survey of Modern Deep Learning based Object Detection Models 论文结构&#xff1a; 一、论文亮点&#xff08;与其他综述不同&#xff09;&#xff1a; 1、深度分析了两类检测方法&#xff1a;单步和两步检测&#xff0c;并从历史的角度分析&…

【covid 时间序列】基于matlab GUI冠状病毒病例、死亡、疫苗接种仿真【含Matlab源码 2262期】

一、⛄SEIR模型简介 1 SEIR模型简介 如果所研究的传染病有一定的潜伏期&#xff0c;与病人接触过的健康人并不马上患病&#xff0c;而是成为病原体的携带者&#xff0c;归入 E 类。此时有&#xff1a; 仍有守恒关系 S(t) E(t) I(t) R(t) 常数&#xff0c;病死者可归入 R…

Vue3 快速入门及巩固基础

1. Vue 框架介绍 2. Vue3 安装方式 3. Vue3 模板语法 4. 组件的 data 属性 5. 计算属性和方法 6. 侦听器的使用 7. class 类名绑定对象 8. class 类名绑定数组 9. style 样式绑定对象 10. style 样式绑定数组 11. 条件渲染 v-if 和 v-show 12. 列表渲染 v-for 13. …