C语言进阶【6】---结构体【1】(结构体的本质你不想了解吗?)

news2024/9/27 17:41:33

本章概述

  • 结构体类型的声明
  • 结构体变量的创建和初始化
  • 结构体成员访问操作符
  • 彩蛋时刻!!!

结构体类型的声明

咱们在讲操作符那个章节中,对于结构体类型的声明进行了讲解,咱们先来回忆一下,为后面的讲解作准备。

  • 为什么要有结构体类型? 前面,咱们讲过,变量类型分为内置类型自定义类型char , float ,int 等这些为内置类型,也就是说这些内置的类型是C语言给你规定好的,直接用就OK了。数组,结构体,联合体和枚举这些就是自定义类型,需要我们自己来定义,定义后才能使用。当我们描述简单的变量时候,一般用内置类型(单一变量类型)就OK了,比如,定义一个整形变量,int i=0; 但是,当我们描述一个复杂的对像时,单一变量就不行了,比如,描述一个学生。描述一个学生需要描述名字,身高,体重和学号。这些描述中有字符类型,整形类型和浮点类型。而我们的单一变量类型就不满足了,需要定义结构体类型来进行描述。
  • 结构体的定义结构体是一些值的集合,这些值被称为成员变量,这些成员变量可以是不同类型的变量。进行结构体的结构展示:
struct  tag
{
	 member-list ; //成员列表
}varible-list; // 定义的结构体变量

可以在创建结构体的时候定义变量,这个时候的变量为全局变量。也可以先创建好结构体,在后面使用的时候,再创建对应的结构体变量,就是局部变量。进行代码展示:

struct stu
{
	int age;
	char name[20];
	double hight;
}s1,s2;  // s1 ,s2为全局变量 

s1 ,s2为全局变量 。。

struct stu
{
	int age;
	char name[20];
	double hight;
};
int main()
{
	struct stu s1; //s1为局部变量
	return 0;
}

s1为局部变量

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

  • 结构体的创建:我们已经在上面写过了结构体的创建格式。我们再来创建一个描述学生的结构体类型吧。
描述一个学生,名字,年龄,身高,学号和体重
struct stu
{
	 char name[20];
	 int age;
	 double hight;
	 char ID[40];
	 double weight;
};
  • 结构体的初始化:在这里我们要分为两种情况,一种是初始化一部分(不正经的写法)另一种就是全部初始化。我们直接创建局部变量。
    • 初始化一部分(不正经的写法):进行代码展示;
#define  _CRT_SECURE_NO_WARNINGS	1
#include <stdio.h>
struct stu
{
	char name[20];
	int age;
	double hight;
	char ID[40];
	double weight;
};
int main()
{
	struct stu s1 = {"zhangsan",18};
	return 0;
}

结果运行图:在这里插入图片描述
我们创建的结构体类型中,有很多的成员,但是我们只初始化了几个成员,而且也没有报错。这样初始化是OK的,对于其它没初始化的成员空间,就会自动初始化为0。调试图所示:在这里插入图片描述
但是,这是不正经的写法我们既然创建了一个结构体类型,肯定为描述对象,所创建的数据类型(成员变量)刚刚好,我们就是为了全面描述对象的,为什么还初始化不全面呢?对吧。所以,我们要全部初始化,才是正经的写法。

  • 初始化全部成员,进行代码展示。
#define  _CRT_SECURE_NO_WARNINGS	1
#include <stdio.h>
struct stu
{
	char name[20];
	int age;
	double hight;
	char ID[40];
	double weight;
};
int main()
{
	struct stu s1 = {"zhangsan",18,180.2,"32301022004",75.3};
	return 0;
}

我们还可以不按顺序进行初始化,进行代码展示:

#define  _CRT_SECURE_NO_WARNINGS	1
#include <stdio.h>
struct stu
{
	char name[20];
	int age;
	double hight;
	char ID[40];
	double weight;
};
int main()
{
	struct stu s1 = {"zhangsan",18,180.2,"32301022004",75.3};
	struct stu s2 = {.age=18,.ID="32301022004",.hight=180.3,.weight=75.3,.name="zhangsan"};
	return 0;
}
  • 结构体的特殊声明:一般结构体的声明,咱们都知道,它是有标签名的(tag)。但是,=结构体的声明可以不用写标签名,这种特殊声明就叫匿名结构体。进行代码展示:
// 匿名结构体
struct
{
	char name[20];
	int age;
	double hight;
	char ID[40];
	double weight;
}s1; //匿名结构体只能定义全局变量
  • 匿名结构体要注意的地方匿名结构体只能定义全局变量,不能定义局部变量。为什么呢?接下来进行代码讲解:
假如我们用上面的匿名结构体来定义变量:struct s1 。大家是不是看着很不对劲,这是匿名结构体
定义的变量s1 。但是,我们也可以看成 struct  s1==struct  tag(标签),其中s1就是个标签。
所以,计算机会把struct  s1当成正常命名的结构体。所以,为了能够定义匿名结构体变量,我们
只能定义全局变量。
  • 结构体使用注意事项同种类型的同一个结构体可以使用多次,不同种类型的同一个结构体只能使用一次。我们先来写个代码;
写个结构体的类型,我们创建个普通的变量和指针型的变量。我们取出这个普通变量
的地址,存放到结构体类型指针中。

我们先来展示正常的结构体创建的变量代码:

#define  _CRT_SECURE_NO_WARNINGS	1
#include <stdio.h>
struct str
{
	int i;
	char arr[20];
}s1;
struct str
{
	int i;
	char arr[20];
}*p;
int main()
{
	p = &s1;
	return 0;
}

结果运行图:在这里插入图片描述
结果运行是错误的,在这里我们分开使用了结构体类型,又分别创建了两个不同类型的变量。我们进行&s1,取出的是s1的地址,按理来说是可以赋值给p的。但是,编译器会把这一个结构体类型当成不同的结构体类型,所以就会报错。这就回到咱们开头讲的:同类型的变量可以使用多次,不同类型的变量只能使用一次。进行展示正确的代码:
代码展示【1】

#define  _CRT_SECURE_NO_WARNINGS	1
#include <stdio.h>
struct str
{
	int i;
	char arr[20];
}s1,*p;
int main()
{
	p = &s1;
	return 0;
}

结构运行图:在这里插入图片描述
代码展示【2】

#define  _CRT_SECURE_NO_WARNINGS	1
#include <stdio.h>
struct str
{
	int i;
	char arr[20];
}s1;
int main()
{
	struct str *p=NULL;
	p = &s1;
	return 0;
}

结果运行图:在这里插入图片描述
这两种的写法才是正确的,上面展示的两种代码就属于共用同一个类型的结构体。虽然创建的是两种不同类型的变量,但是你没有分开使用,编译器就会认为你使用的是同一个结构体类型,所以不会报错。总结:创建不同类型的变量时,同一个结构体不能分开使用,匿名结构体也是如此
不是同一个结构体也可以使用(虽然成员列表相同),如下:在这里插入图片描述

  • 重命名使用:上面,咱们讲了,同一个结构体定义不同类型变量时,只能使用一次。那么我们有没有什么办法可以用多次呢?——重命名。关于重命名,咱们讲过,#definetypedef。进行代码展示——以typedef举例:
#define  _CRT_SECURE_NO_WARNINGS	1
#include <stdio.h>
typedef struct str
{
	int i;
	char arr[20];
}node;
int main()
{
	node* p = NULL;
	node a;
	p = &a;
	return 0;
}

结果运行图:在这里插入图片描述
当我们重命名后就可以随便用了,匿名结构体也是如此。

  • 结构体的自引用:当我们在结构体里面包含一个同一个结构体是否可以呢?进行代码展示:
struct Node
{
  int data;
  struct Node next;
};

上面的代码,我们定义了一个数据结构里面的链表节点。所谓数据结构就是:数据在内存中的存储方式。我们知道数组就是一种存储数据的方式之一,其实数据在内存中的存储方式很多中。其中有一种不是连续存储的方式就是链表存储。每个链表都有一个节点,这个节点里面存有数据和下一个节点的信息,如图所示:在这里插入图片描述
大家感觉到上面的代码有什么问题吗?我们知道每个数据类型都有大小是吧,那么我来计算一下这个节点的大小。我们发现竟然无法计算。Int data我们清楚占有4个字节,但是 struct Node next占有多少个字节就不清楚了(因为它里面又会包含 struct Node next),就会形成 “套娃” 就会无穷大。我们表示节点示不用这种方式自引用,我们可以存放下一个节点的地址,指针大小咱们知道是固定的。所以节点大小就可以计算了,进行代码展示:

struct Node
{
  int data;
  struct Node* next;
};
  • 重命名的自引用注意事项我们重命名后,不能在结构体里面自引用这个重命名的结构体。进行代码展示:
typedef struct Node
{
	 int data;
	 Node* next;
}Node;

结果运行图:在这里插入图片描述
结果报错了。原因 :因为程序是一步一步在执行的,当执行到 Node* next;这句代码的时候,编译器在之前没见它就会报错(因为你在后面才重命名的,所以编译器看不到)。进行正确代码展示:

typedef struct Node
{
	int data;
	struct Node* next;
}Node

这样写就OK了。

结构体成员访问操作符

  • 成员访问操作符:有两种访问操作符' .'' ->'。其中‘ ->’只能用于指针形式的访问
    • ' .'的访问方式:进行代码展示:
#include <stdio.h>
struct stu
{
	int i;
	char name[30];
};
int main()
{
	struct stu s1 = {100,"zhangsan"};
	printf("%d %s",s1.i,s1.name);
	return 0;
}

结果运行图:在这里插入图片描述
我们还可以直接赋值,进行代码展示:

#include <stdio.h>
struct stu
{
	int i;
	char name[30];
}s1;
int main()
{
	s1.i = 100;
	//s1.name = "zhangsan";
	
	printf("%d %s",s1.i,s1.name);
	return 0;
}

结果运行图:在这里插入图片描述
我们不能进行点的直接访问数组,原因如下图所示:在这里插入图片描述

  • ' ->'访问方式:进行代码展示:
#include <stdio.h>
struct stu
{
	int i;
	char name[30];
};
int main()
{
	struct stu s1 = {100,"zhangsan"};
	struct stu* p = &s1;
	printf("%d %s", p->i,p->name);
	return 0;
}

结果运行图:在这里插入图片描述

彩蛋时刻!!!

https://www.bilibili.com/video/BV1MwtteWECz/?spm_id_from=pageDriver&vd_source=7d0d6d43e38f977d947fffdf92c1dfad
在这里插入图片描述
每章一句不要看见别人发光,就觉得自己暗淡感谢你能看到这里,点赞+关注+收藏+转发是对我最大的鼓励,咱们下期见!!!

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

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

相关文章

堆排序,TopK问题|向上调整建堆|向下调整建堆(C)

堆排序 void HeapSort(int* a, int n) {HP hp;HeapInit(&hp);for (int i 0; i < n; i){HeapPush(&hp, a[i]);}int i 0;while (!HeapEmpty(&hp)){a[i] HeapTop(&hp);HeapPop(&hp);}HeapDestroy(&hp); }先初始化一个堆将数组中的数据一个一个顺序…

【Python大语言模型系列】在阿里云ECS服务器上部署dify大模型应用开发平台(完整教程)

这是我的第360篇原创文章。 一、阿里云ECS简介 云服务器( Elastic Compute Service ,简称ECS )是一-种简单高效、处理能力可弹性伸缩的计算服务&#xff0c;帮助您快速构建更稳定、安全的应用,提升运维效率,降低IT成本&#xff0c;使您更专注于核心业务创新。 这个活动需要满…

Vatee万腾平台:企业智能化生态的领航者

在科技日新月异的今天&#xff0c;企业的智能化转型已成为不可逆转的趋势。Vatee万腾平台&#xff0c;凭借其前瞻性的技术视野和不懈的创新精神&#xff0c;正逐步构建起一个以智能化为核心的新型商业生态&#xff0c;成为推动企业智能化升级的核心力量。 Vatee万腾平台深谙技…

软件设计之Maven(1)

软件设计之Maven(1) 路线图推荐&#xff1a; 【Java学习路线-极速版】【Java架构师技术图谱】 尚硅谷新版Maven教程&#xff08;高效入门maven&#xff0c;上手又快又稳&#xff09; 资料可以去尚硅谷官网免费领取 学习内容&#xff1a; Maven简介安装与环境配置Maven工程GA…

【机器学习(九)】分类和回归任务-多层感知机(Multilayer Perceptron,MLP)算法-Sentosa_DSML社区版

文章目录 一、算法概念二、算法原理&#xff08;一&#xff09;感知机&#xff08;二&#xff09;多层感知机1、隐藏层2、激活函数sigma函数tanh函数ReLU函数 3、反向传播算法 三、算法优缺点&#xff08;一&#xff09;优点&#xff08;二&#xff09;缺点 四、MLP分类任务实现…

【html网页制作】国庆节日主题网页制作含js轮播(5页面附效果源码)

HTMLCSS节日国庆主题网页制作 &#x1f354;涉及知识&#x1f964;写在前面&#x1f367;一、网页主题&#x1f333;二、网页效果菜单切换效果PageA、整体页Page1、首页Page2、节日由来Page3、节日视频Page4、庆祝活动Page5、留言 &#x1f40b;三、网页架构与技术3.1 脑海构思…

# linux从入门到精通(二)

linux从入门到精通&#xff08;二&#xff09; 一、Linux系统的安装&#xff1a;新建VM虚拟机 1、Linux版本的选择 1&#xff09;版本选择&#xff1a;CentOS 6.5 【镜像一般都是xxx.iso文件】 2&#xff09;为什么不选择7.x版本&#xff1f; 6.x的各种系统操作模式是基础…

python绘制图像

柱状图 import os# 输入想要存储图像的路径 os.chdir(D:)import matplotlib.pyplot as plt import numpy as np # 改变绘图风格 import seaborn as snssns.set(color_codesTrue)cell [gen7, xgspon, 3081GB, vettel, totalplay, other] pvalue [21, 20, 18, 13, 7, 34]width…

​​XrayGLM原理与部署

接上一篇&#xff1a;VisualGLM-6B——原理与部署-CSDN博客 XrayGLM技术背景与原理 XrayGLM 是一种基于 VisualGLM-6B 微调开发的多模态医学影像诊断模型&#xff0c;专门用于处理医学影像&#xff08;如 X 光胸片&#xff09;的自动诊断和报告生成任务。该模型旨在为中文医学…

第8章_索引的创建与设计原则

1. 索引的声明与使用 1.1 索引的分类 MySQL的索引包括普通索引、唯一性索引、全文索引、单列索引、多列索引和空间索引等。 从 功能逻辑 上说&#xff0c;索引主要有 4 种&#xff0c;分别是普通索引、唯一索引、主键索引、全文索引。 按照 物理实现方式 &#xff0c;索引可以…

医疗器械中的国产光耦合器浅析

光耦合器&#xff0c;也称为光隔离器&#xff0c;在确保医疗器械的安全性和性能方面发挥着关键作用。通过在系统的不同部分之间提供电气隔离&#xff0c;它们可以防止信号干扰、保护敏感元件并保护患者免受电击。近年来&#xff0c;国产光耦合器制造商一直在加紧生产可靠的高性…

时也命也!转念的力量(深度好文)——早读(逆天打工人爬取热门微信文章解读)

时也命也 引言Python 代码第一篇 洞见 转念的力量&#xff08;深度好文&#xff09;第二篇 意想不到的收入结尾 早上上交所宕机 很多股票都横成直线 我的股却跳了一下水 我怕出什么监管事故 跟着卖出去了 然后查了一下 发现是上交所被买爆了 我想了一下 服务器问题 那么能否事后…

OpenEuler配置本地yum源

0x00 服务器版本 将本地镜像传输至服务器 操作步骤如下 # 创建一个目录用于挂载光盘映像 mkdir /media/cdrom/# 将光盘映像挂载到指定目录 mount /kvm/openeuler.iso /media/cdrom/#进入Yum仓库配置目录 cd /etc/yum.repos.d/# 备份原有的 openEuler.repo 文件 mv openEuler.…

解读: 火山引擎自研vSwitch技术

最近看到一篇文章介绍火山云的网络vSwitch技术&#xff0c;虽然是2022年的比较老的介绍&#xff0c;但是对于我们看到vSwitch技术的发展还是有些参考的。下面就截取了当时火山vSwitch关心的几个问题&#xff0c;做了一下梳理。 背景 在云计算发展过程中&#xff0c;虚拟网络的…

国内光耦合器制造商如何满足特殊行业的需求

在航空航天、国防、电信等行业&#xff0c;对定制解决方案的需求正在增长。通用光耦合器可能并不总是适合这些专业领域的特定要求&#xff0c;因为这些领域必须满足独特的环境条件、尺寸限制和性能基准。国内光耦合器制造商一直在加紧努力&#xff0c;提供可定制的解决方案&…

从 0 到 1:互联网产品经理核心技能全解析

在互联网的浩瀚海洋中&#xff0c;产品经理如同领航员&#xff0c;决定着产品从无到有的走向和命运。从 0 到 1 打造一款互联网产品&#xff0c;需要产品经理具备多方面的核心技能。今天&#xff0c;我们就来详细解读这些关键能力。 一、洞察市场趋势 时刻关注行业动态 互联网…

AOT源码解析4.1-对输入数据和mask进行处理(Associating Objects with Transformers for Video Object Segmentation)

论文阅读 papergithub论文阅读笔记AOT源码解析1-数据集处理AOT源码解析2-encoderdecoderAOT源码解析3-模型训练AOT源码解析4.1-model主体AOT源码解析4.2-model主体AOT源码解析4.3-model主体AOT源码解析4.4-model主体AOT源码解析4.5-model主体 输入数据 VOS的数据集处理操作可…

Python基础语句教学

Python是一种高级的编程语言&#xff0c;由Guido van Rossum于1991年创建。它以简单易读的语法和强大的功能而闻名&#xff0c;被广泛用于科学计算、Web开发、数据分析等领域。 Python的应用领域广泛&#xff0c;可以用于开发桌面应用程序、Web应用、游戏、数据分析、人工智能等…

【中台资料】数字中台建设资料合集(Word,PPT)

目录 1 编写目的 2 背景概述 3 中台概念 4 推动企业组织模式演进 5 建设方法 6 中台内容 7 数据安全体系 8 参考资料 软件全套资料部分文档清单&#xff1a; 工作安排任务书&#xff0c;可行性分析报告&#xff0c;立项申请审批表&#xff0c;产品需求规格说明书&#xff0c;需…

Redis 的 Java 客户端有哪些?官方推荐哪个?

Redis 官网展示的 Java 客户端如下图所示&#xff0c;其中官方推荐的是标星的3个&#xff1a;Jedis、Redisson 和 lettuce。 Redis 的 Java 客户端中&#xff0c;Jedis、Lettuce 和 Redisson 是最常用的三种。以下是它们的详细比较&#xff1a; Jedis&#xff1a; 线程安全&…