C语言——结构体详解

ops/2024/9/23 9:21:06/

        今天我们就一起来了解一下C语言中结构体有关的知识吧!

        结构是什么?

        结构是一些值的集合,这些值被称为成员变量,结构的每个成员可以是不同类型的变量。        

        我们之前也学习过数组,这里我们来区分一下结构体和数组的概念

        数组是一组相同类型元素的集合。

        结构体是一组不同类型元素的集合。

        我们可以了解到,结构体和数组都是元素的集合,区别是,结构体是不同类型的元素的集合。这里我们发现,结构体面向的对象是复杂的。

        结构体的声明

struct stu
{char name[20];int stu_num[20];
}s1;

        在这个代码中,我们声明了结构体stu,stu是标签名,可以理解为结构体的名称,这个名称并不是固定不变的,可以随我们心意和具体内容来设置,比如这串代码中,我们想设置一个学生的学号和姓名,我们就可以将结构体命名为stu(student)。

        当然结构体括号中的就是结构体的成员列表了,我们想表示姓名和学号,我们就定义两个数组来存放我们将要表示的内容,姓名需要定义char类型的,我们设置为name,学号这里我们定义为stu_num,因为学号是数字,所以我们定义类型为int。

        结构体成员的类型

        这里我们需要了解到结构体成员的类型:可以是标量,数组,指针,甚至可以是其他的结构体(后面举例说明)。

        结构体变量的定义和初始化

        

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
//结构体变量的定义
struct stu
{char name[20];int stu_num;char sex[10];float score;
};
int main()
{//结构体变量的初始化struct stu s1 = { "zhangsan",0001,"nan",59.5f };struct stu s2 = { "wangwu",0003,"nv",60.2f };printf("%s %d %s %f", s1.name, s1.stu_num, s1.sex, s1.score);return 0;
}

        在这个代码中,我们定义了结构体stu,结构体面向的对象是学生,结构体的成员列表中包含了结构体对象stu的姓名,学号,性别,分数。这是我们对结构体stu的定义,告诉别人我们定义的结构体stu中都有什么成员。

        我们之前说结构体面向的对象是复杂的,这里就是他复杂的地方,面向一个学生对象可以有四个或者更多的结构体成员,而数组的话就只有一组相同类型的元素。

        在后面的主函数中,我们定义结构体对象的结构体变量,并且将它初始化,这里初始化就是对我们的结构体变量的各个成员进行填充,例如在代码中我们给结构体变量s1赋初值为:"zhangsan",0001,"nan",59.6f 。

        之后我们打印一下结构体变量s1的值,看看有没有初始化成功,结果显示无误:

        

        结构体成员的访问

        其实我们刚刚已经访问过结构体成员了,我们使用了(.)操作符,这是结构体成员访问的一种方式。

        代码解释

        

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
struct X
{int a;char c;
};
struct Y
{double d;struct X x;float f;
};void print1(struct Y yn)
{printf("%lf %d %c %f\n", yn.d, yn.x.a, yn.x.c, yn.f);
}
void print2(struct Y* ym)
{printf("%lf %d %c %f\n", (*ym).d, (*ym).x.a, (*ym).x.c, (*ym).f);printf("%lf %d %c %f\n", ym->d, ym->x.a, ym->x.c, ym->f);
}
int main()
{struct Y y = { 5.2,{13,'b'},1.314f};//传值调用print1(y);//传址调用print2(&y);return 0;
}

        因为是给大家解释所以这里的结构体变量名称就尽量简单方便大家理解。

        解析

        首先我们定义结构体X,里面存放一个整型变量a和字符型变量c,再定义一个结构体Y,里面存放了一个双精度浮点型的d,结构体X和一个单精度浮点型的f。

        定义好我们的结构体之后我们对结构体变量y进行初始化,赋初值为: 5.2,{13,'b'},1.314f,这里有大家需要注意的点哦,我们发现在结构体Y的内部还有一个结构体X,那么这个时候我们就需要再来一个{}用来存放在结构体Y中结构体X的值了。

        传值调用

        我们通过函数调用的方式来实现结构体的传值调用,我们定义函数print1,传值调用我们主要使用点操作符来完成。但是我们在使用点操作符之前需要知道结构体变量是什么,此代码中,结构体变量y传参给print1函数为yn。

        printf("%lf %d %c %f\n", yn.d, yn.x.a, yn.x.c, yn.f);

        结构体变量.成员名

        传址调用

        我们还是使用函数调用的方式实现传址调用,定义函数print2,这里就需要注意了,我们既然是传址调用,那么我们就应该将地址作为参数进行传递,所以我们主函数中print2需要将y的地址传给print2函数中的* ym,地址需要一个指针来接收,我们这里一定不能忘记ym前的*号啊。

        传址调用有两种方式,但是不是很推荐第一种,因为操作起来很麻烦。

        第一种方式:

            printf("%lf %d %c %f\n", (*ym).d, (*ym).x.a, (*ym).x.c, (*ym).f);

        我们这边取地址之后解引用将结构体指针变为结构体变量的方式其实和传值调用是一样的,但是步骤要繁琐很多,属于是多此一举。

        第二种方式:

        printf("%lf %d %c %f\n", ym->d, ym->x.a, ym->x.c, ym->f);

        这种方式是直接使用地址的方式来进行传址调用,嗯对,物尽其用,但是这里也要注意,当我们结构体中还有结构体的时候,我们结构体成员X的结构体变量x需要的还是点操作符,因为这里我们ym->x的时候x已经是结构体变量了,所以我们直接使用点操作符就可以访问结构体变量x中的成员。

        结构体指针->成员名

        今天就到这里喽,希望大家都可以了解结构体的知识,大家下次再见!如有不足之处请各位指正!!!评论区留言一定会回大家的嘞!


http://www.ppmy.cn/ops/3683.html

相关文章

数据结构:堆

这张网络上的图片很形象的展示了一棵具有多个分支的独特树木&#xff0c;其分支模式类似于&#xff08;甚至于是完美&#xff09;二叉树的结构。我们可以将这棵树的形态作为引入二叉树概念的一个隐喻。在二叉树中&#xff0c;每个节点最多有两个子节点&#xff0c;这与树木的分…

【python】flask操作数据库工具SQLAlchemy,详细用法和应用实战

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

前端开发攻略---在输入框中输入中文但是还没选中的时候,搜索事件依然存在;中文输入法导致的高频事件。

1、演示 解决前 解决后 2、输入框事件介绍 compositionstart事件在用户开始使用输入法输入时触发。这意味着用户正在进行组合输入&#xff0c;比如在中文输入法中&#xff0c;用户可能正在输入一个多个字符的词语。在这个阶段&#xff0c;输入框的内容可能还没有完全确定&#…

Elasticsearch(2)

目录 121.ES查询中match和term的区别? 122.Es查询中should和must的区别? 123.ES查询中match,match_phrase和match_phase_prefix有什么区别? 124.ES查询中什么是复合查询?有哪些复合查询方式?

深入刨析 mysql 底层索引结构B+树

文章目录 前言一、什么是索引&#xff1f;二、不同索引结构对比2.1 二叉树2.2 平衡二叉树2.3 B-树2.4 B树 三、mysql 的索引3.1 聚簇索引3.2 非聚簇索引 前言 很多人看过mysql索引的介绍&#xff1a;hash表、B-树、B树、聚簇索引、主键索引、唯一索引、辅助索引、二级索引、联…

【Web】陇原战“疫“2021网络安全大赛 题解

目录 CheckIN eaaasyphp EasyJaba CheckIN 拿到附件&#xff0c;贴出关键代码 func getController(c *gin.Context) {cmd : exec.Command("/bin/wget", c.QueryArray("argv")[1:]...)err : cmd.Run()if err ! nil {fmt.Println("error: ", …

桥接模式【结构型模式C++】

1.概述 桥接模式是一种结构型设计模式&#xff0c;是用于把抽象化与实现化解耦&#xff0c;使得二者可以独立变化。这种类型的设计模式属于结构型模式&#xff0c;它通过提供抽象化和实现化之间的桥接结构&#xff0c;来实现二者的解耦。 这种模式涉及到一个作为桥接的接口&am…

语言模型的发展

文章目录 语言模型的发展历程大语言模型的能力特点大语言模型关键技术概览大语言模型对科技发展的影响 语言模型的发展历程 一般来说&#xff0c;语言模型旨在对于人类语言的内在规律进行建模&#xff0c;从而准确预测词序列中未来&#xff08;或缺失&#xff09;词或词元&…