【C语言】详解结构体(上)

news2024/11/26 14:29:45

文章目录

  • 前言
  • 1. 结构体类型的含义
  • 2.结构体的声明
    • 2.1 结构体声明的语法
    • 2.2 结构体变量的创建和初始化
  • 3.结构体的特殊声明
  • 4. 结构体的自引用
  • 5.小结

前言

C语言的数据类型分为内置数据类型和自定义的数据类型。所谓的内置的数据类型可以认为是C语言自带的数据类型(char、int、float、double、bool),而自定义的数据类型(数组、结构体、联合体和枚举)中的结构体类型就是本文所要分享给大家的。

1. 结构体类型的含义

我们在正式学习结构体之前,得先了解一下结构体到底是个什么东西?
有句古话说的好:知己知彼,方能百战不殆。
我们想要学好结构体,就必须得对它有一定的了解。为了让大家能够更好的学习结构体,这里就先引入我们之前学过的数组的一些知识。

我们都是知道,数组里面的元素都是相同类型的,并且它们在内存空间中是连续存放的。那这时我们就会有这么一个疑惑?C语言有没有一种数据类型能够存放一次性包括多种不同的数据类型。答案是有的,那就是我们本讲的主角——结构体

总而言之,当我们在编程时遇到了一个个体,这个个体包含着许多不同的属性,一个一个定义就显得过于繁琐且不方便,那么结构体就刚好适应这种场景的需求。

2.结构体的声明

在讲完结构体的含义之后,那我们该如何去定义一个结构体呢?

2.1 结构体声明的语法

struct tag
{
	member-list; 
}varible-list;
符号含义
tag标签,可以理解为结构体名字
member-list成员列表,之后我们就是在这个花括号内来写我们想要存储的变量
varible-list变量列表,这个就是我们利用结构体创建之后直接给结构体变量的名称

注意:结构体名称和结构体变量名称是两个不一样的东西,不要给混淆了

例如:我们描述一个学生

struct Student
{
	char name[20];//姓名
	int age;//年龄
	char sex[5];//性别
	char id[20];//学号
}; //这里有个分号,一定不要忘记写了

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

struct S
{
	char c;
	int i;
	double d;
};

struct Stu
{
	char name[20];//名字
	int age;//年龄
	char sex[5];//性别
	char id[20];//学号
};

int main()
{
	//按照结构体的成员顺序进行赋值
	struct Stu s1 = { "张三",22,"男","123456789" };
	printf("name: %s\n",s1.name);
	printf("age: %d\n", s1.age);
	printf("sex: %s\n", s1.sex);
	printf("id: %s\n", s1.id);

	printf("\n");
	//按照知道指定的顺序赋值
	struct Stu s2 = { .age = 18,.name = "梨花",.id = "563217485",.sex = "女"};
	printf("name: %s\n", s2.name);
	printf("age: %d\n", s2.age);
	printf("sex: %s\n", s2.sex);
	printf("id: %s\n", s2.id);
	return 0;
}

结果演示
除了上述在main函数内创建结构体变量的方式之外,我们还可以在面函数外面创建结构体变量,如果是这样做的话,这个变量就相当于全局变量了。

//方法一
struct Stu
{
	char name[20];//名字
	int age;//年龄
	char sex[5];//性别
	char id[20];//学号
}s1,s2; //变量列表

//方法二
struct Stu s3;

int main()
{
	...
}

3.结构体的特殊声明

在声明结构体时,我们也可以做到不完全声明。具体一点来讲,就是不给结构体名字。
我们将这种结构体称为“匿名结构体
比如:

//匿名结构体类型
struct
{
	int i;
	char ch;
	double d;
}s;
struct
{
	int i;
	char ch;
	double d;
}* ps;

可以观察到,匿名结构体在声明时,的确出现了省略标签(tag)的现象。

不过需要注意的是,匿名结构体只能用一次。这里的“用一次”也就是说该匿名结构体在本声明之初就应该一次性在变量列表中创建好所有变量的名称,等到脱离了匿名结构体的声明后,就再也没有办法创建一个新的结构体变量了。

那么我现在有个问题:

ps = &s; //这样写可以吗?

乍一看,好像确实没有什么问题啊!ps这个结构体指针所指向的结构体与结构体变量s里面的成员变量是一摸一样的。可事实真的如此吗?

错误警告

警告信息为:“=”: 从“*”“*”的类型不兼容
也就是说ps所指向的结构体与变量s所代表的结构体不属于同一个结构体类型,尽管它们里面成员一模一样

为此,我们总结一下匿名结构体使用的注意事项:

  1. 匿名结构体只能使用一次
  2. 即使两个甚至是多个匿名结构体里面的成员列表的内容是一摸一样的,编译器也会把这些结构体视作不同类型的结构体变量

4. 结构体的自引用

在结构体包含一个类型为改结构体本身的成员是否可以呢?
答案是肯定的,不过有一定的语法规则。为什么会这样说呢?请看下面的代码:

//根据上面的意思,我们可以写出以下代码:
struct Node
{
	int data;
	struct Node next;
};

上面的代码合理吗?如果合理的话,请告诉我sizeof(struct Node)的值为多少?
显然,问到这里,你就会发现,这个结构体这样声明确实有点问题。这个结构体的声明给我们一种陷入了死循环的感觉,而这个结构体的大小就为无穷大。

正确子引用的方式:

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

我们用一个指向该结构体的指针作为该成员变量,这样做不仅可以知道该结构体的大小,还可以利用该指针访问其内部的数据,一举两得。

例外,我们还需要注意一种极其容易出现错误的写法:
我们再利用typedef给结构体重命名时:

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

上述写法可行吗?
错误示范
原因是:编译器是从上往下来执行代码的,当执行到 Node* next 这条语句时,编译器由于还未完全读到typedef的所有语句,因此就将Node视作未定义的标识符。

正确的写法是:

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

5.小结

在本文中,我想告诉大家的是:结构体的用途、结构体的声明、结构体的变量的创建及初始化还有结构体的自引用。内容不是很多,希望读者们能好好消化理解。

最后,如果觉得本文写的还不错的话,希望可以给偶带上个赞👍,阿里嘎多❤️❤️❤️。
让我们在详解结构体(下)这个篇章再见!!!

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

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

相关文章

three完全开源扩展案例03-模型加载

https://www.threelab.cn/three-cesium-examples/public/index.html#/codeMirror?navigationThree.js%E6%A1%88%E4%BE%8B[r166]&classifybasic&idmodelLoad 更多内容:https://threelab.cn/ import * as THREE from three import { OrbitControls } from …

AI+折叠屏,荣耀的创新周期论

文|刘俊宏 编|王一粟 2024年,AI和折叠屏的演进路线,已经成为了手机行业的共识。 首先,手机市场的新增量已经被折叠屏所接管。据Counterpoint Research数据显示,中国2024年第一季度折叠屏手机销量同比增长…

最新Qt6的下载与成功安装详细介绍

引言 Qt6 是一款强大的跨平台应用程序开发框架,支持多种编程语言,最常用的是C。Qt6带来了许多改进和新功能,包括对C17的支持、增强的QML和UI技术、新的图形架构,以及构建系统方面的革新。本文将指导你如何在Windows平台上下载和安…

linux后门教程

linux后门教程 alias 用法 系统默认别名:alias 设置别名:alias lsls -laih 删除别名:unalias ls **加参数:**alias ls‘ls -laih;pwd’ 注意 系统启动默认加载的配置文件 /etc/profile 切换用户就会执行/etc/profile /etc/bash…

【JavaScript 算法】冒泡排序:简单有效的排序方法

🔥 个人主页:空白诗 文章目录 一、算法原理二、算法实现三、应用场景四、优化与扩展五、总结 冒泡排序(Bubble Sort)是一种基础的排序算法,通过重复地遍历要排序的数列,一次比较两个元素,如果它…

c语言题目之打印水仙花数

文章目录 一、题目二、思路三、代码实现 提示:以下是本篇文章正文内容,下面案例可供参考 一、题目 二、思路 此题的关键在于只要知道判断一个数据是否为水仙花数的方式,问题就迎刃而解。假定给定一个数据data,具体检测方式如下&a…

HTML+CSS+JS井字棋(来自动下棋)

井字棋 自动下棋 玩家先下&#xff0c;计算机后下 源码在图片后面 点赞❤️收藏⭐️关注&#x1f60d; 效果图 源代码 <!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8"> <title>Tic Tac Toe Game</tit…

批量提取PDF指定区域内容到 Excel , 根据PDF文件第一行文字来自动重命名v1.3-附思路和代码实现

本次文章更新内容&#xff0c;图片以及扫描的PDF也可以支持批量提取指定区域内容了&#xff0c;主要是通过截图指定区域&#xff0c;然后使用OCR来识别该区域的文字来实现的&#xff0c;所以精度可能会有点不够&#xff0c;但是如果是数字的话&#xff0c;问题不大&#xff1b;…

【MobileNet】【模型学习】

MobileNet 模型学习 MobileNet v1 B站视频链接&#xff1a;https://www.bilibili.com/video/BV1i44y1x7hP/关键点&#xff1a; 将常规的卷积&#xff0c;替换成深度可分离卷积。具体为&#xff1a;逐层卷积、逐点卷积。使用 Relu6 替换原先的 Relu。防止在进行 int8 和 float…

LAST_INSERT_ID使用方法-(DM8达梦数据库)

LAST_INSERT_ID使用方法 - DM8达梦数据库 1 示例 11.1 创建表1.2 结果集 2 示例 22.1 创建表2.2 结果集 3 达梦数据库学习使用列表 1 示例 1 1.1 创建表 DROP TABLE AT240715; CREATE TABLE "SYSDBA"."AT240715" ( "ID" INT PRIMARY KEY AUTO_…

leetcode 周赛(406)全AC留念

纪念第一次 leetcode 周赛&#xff08;406&#xff09;全AC 1.(100352. 交换后字典序最小的字符串) 题目描述&#xff1a; 给你一个仅由数字组成的字符串 s&#xff0c;在最多交换一次 相邻 且具有相同 奇偶性 的数字后&#xff0c;返回可以得到的 字典序最小的字符串 。 如…

基于mcu固件反汇编逆向入门示例-stm32c8t6平台

基于mcu固件反汇编逆向入门示例-stm32c8t6平台 本文目标&#xff1a;基于mcu固件反汇编逆向入门示例-stm32c8t6平台 按照本文的描述&#xff0c;应该可以在对应的硬件上通实验并举一反三。 先决条件&#xff1a;拥有C语言基础&#xff0c;集成的开发环境&#xff0c;比如&am…

卫星降雨量数据下载及生成栅格分布图(CMORPH)

一、 降雨 nc 数据下载 1. 登录网址&#xff08;截至到20240712仅有2024年1月的降雨量&#xff09;https://www.ncei.noaa.gov/products/climate-data-records/precipitation-cmorph 2. 选择对应时间分辨率 8km8km (30 min), 0.250.25 (hourly, daily)&#xff08;覆盖全球60…

ZStack Cloud 5.1.8正式发布

2024年7月5日&#xff0c;ZStack Cloud正式发布最新版本——ZStack Cloud 5.1.8&#xff0c;涵盖一系列重要功能&#xff0c;以下为您进行详细介绍。 亮点速览 GPU运维管理增强&#xff1a;新增GPU设备统一管理界面&#xff1b;支持GPU工作状态和实时负载监控报警三层网络运维…

校园工会体育报名小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;赛事公告管理&#xff0c;球员管理&#xff0c;球队信息管理&#xff0c;比赛信息&#xff0c;比赛报名管理 微信端账号功能包括&#xff1a;系统首页&#xff0c;比赛信息&#xff0c;比赛报名&#…

Linux多线程编程-哲学家就餐问题详解与实现(C语言)

在哲学家就餐问题中&#xff0c;假设有五位哲学家围坐在圆桌前&#xff0c;每位哲学家需要进行思考和进餐两种活动。他们的思考不需要任何资源&#xff0c;但进餐需要使用两根筷子&#xff08;左右两侧各一根&#xff09;。筷子是共享资源&#xff0c;哲学家们在进行进餐时需要…

Linux 网络配置与连接

一、网络配置 1.1 ifconfig 网卡配置查询 ifconfig #查看所有启动的网络接口信息 ifconfig 指定的网卡 #查看指定网络接口信息 1.2 修改网络配置文件 vim /etc/sysconfig/network-scripts/ifcfg-ens33 #ens33网络配置文…

【ASTGCN】模型调试学习笔记--数据生成详解(超详细)

利用滑动窗口生成时间序列 原理图示&#xff1a; 以PEMS04数据集为例。 该数据集维度为&#xff1a;(16992,307,3)&#xff0c;16992表示时间序列的长度&#xff0c;307为探测器个数&#xff0c;即图的顶点个数&#xff0c;3为特征数&#xff0c;即流量&#xff0c;速度、平…

车间数据采集网关的工作原理和应用场景-天拓四方

在智能制造日益盛行的今天&#xff0c;车间数据采集作为整个生产流程中的关键环节&#xff0c;其重要性愈发凸显。数据采集网关作为这一环节的核心设备&#xff0c;扮演着承上启下的重要角色。本文旨在深入探讨车间数据采集网关的工作原理和应用场景。 一、数据采集网关的工作…

C++:链表插入排序/删除重复节点题解

插入排序 插入排序的思路很简单&#xff0c;基本都知道。 关键是放在链表中&#xff0c; 1.要建立一个哨兵位&#xff0c;这个哨兵位的下一个节点&#xff0c;始终指向val最小的节点。 2.prev指针作为cur的前一个节点&#xff0c;始终指向val最大的节点。它的下一个节点始终…