当前位置: 首页 > news >正文

c语言回顾-结构体

前言

在前面的学习中,我们知道C语言提供了许多内置类型,如:char、short、int、long、float、double等,但是只有这些内置类型还是不够的。当我们想描述学生,描述一本书,这时单一的内置类型是不行的。描述一个学生需要名字、年龄、学号、身高、体重等;描述一本书需要作者、出版社、定价等。C语言为了解决这个问题,增加了结构体这种自定义的数据类型,让我们可以自己创造适合的类型。

结构体的定义

结构体是一种用户自定义的数据类型,用于将多个不同类型的数据组合在一起形成一个新的数据类型。结构体由多个成员变量组成,每个成员变量可以是不同的数据类型,可以是基本数据类型(如整型、浮点型、字符型等)或其他结构体类型。结构体的成员变量在内存中是按照声明的顺序依次存储的。

1.结构的声明

定义结构体的语法如下:

struct 结构体名 {

类型 成员1;

类型 成员2; ... };

通过定义结构体,可以创建结构体变量,用于存储结构体类型的数据。结构体变量的定义语法如下:

struct 结构体名 变量名;

当然也可以直接在{}后面命名(后面会讲到)

假设我们有一个描述学生的结构体:

struct Student {
int id;
char name[50];
int age;
float score; };

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

//代码1:变量的定义
struct Point
{int x;int y;
}p1; //声明类型的同时定义变量p1
struct Point p2; //定义结构体变量p2
//代码2:初始化。
struct Point p3 = {10, 20};
struct Stu //类型声明
{char name[15];//名字int age; //年龄
};
struct Stu s1 = {"zhangsan", 20};//初始化
struct Stu s2 = {.age=20, .name="lisi"};//指定顺序初始化
//代码3
struct Node
{int data;struct Point p;struct Node* next; 
}n1 = {10, {4,5}, NULL}; //结构体嵌套初始化
struct Node n2 = {20, {5, 6}, NULL};//结构体嵌套初始化

下面具体介绍下初始化方法:

假设我们有一个描述学生的结构体:

struct Student {int id;char name[50];int age;float score;
};

1.可以定义了一个名为student1Student类型的结构体变量,然后通过点操作符.对结构体的各个成员变量进行逐个初始化。

struct Student student1; // 定义结构体变量
student1.id = 1001; // 初始化成员变量
strcpy(student1.name, "Alice"); // 初始化成员变量
student1.age = 20; // 初始化成员变量
student1.score = 85.5; // 初始化成员变量

2.除了逐个初始化,还可以使用一种更简洁的方式,即在定义结构体变量时直接初始化

struct Student student2 = {1002, "Bob", 21, 90.0}; // 定义结构体变量并初始化

3.还有一种初始化结构体变量的方式是使用指定成员的方式进行初始化

struct Student student3 = {.id = 1003, .name = "Charlie", .age = 22, .score = 95.0}; // 指定成员进行初始化

在这种方式中,我们使用成员名来指定要初始化的成员变量,这样可以更清晰地表达出初始化的意图。

无论是逐个初始化、直接初始化,还是指定成员初始化,都可以根据实际情况选择合适的方式来初始化结构体变量,以满足需求。

结构体嵌套初始化

struct Point
{int x;int y;
}
struct Node
{int data;struct Point p;struct Node* next; 
}n1 = {10, {4,5}, NULL}; //结构体嵌套初始化
struct Node n2 = {20, {5, 6}, NULL};//结构体嵌套初始化

Node结构体中包含Point结构体,需要注意的是,嵌套结构体的初始化顺序应与结构体定义中的成员顺序一致,以确保正确地对应初始化。

3.结构成员访问

3.1结构体成员的直接访问

结构体成员的直接访问是通过点操作符(.)访问的。点操作符接受两个操作数。
#include <stdio.h>
struct Point
{int x;int y;
}p = {1,2};
int main()
{printf("x: %d y: %d\n", p.x, p.y);return 0;
}
使用方式:结构体变量.成员名

3.2结构体成员的间接访问

有时候我们得到的不是一个结构体变量,而是得到了一个指向结构体的指针。
#include <stdio.h>
struct Point
{int x;int y;
};
int main()
{struct Point p = {3, 4};struct Point *ptr = &p;ptr->x = 10;ptr->y = 20;printf("x = %d y = %d\n", ptr->x, ptr->y);return 0;
}
使用方式:结构体指针->成员名
综合例子
#include <stdio.h>
#include <string.h>
struct Stu
{char name[15];//名字int age; //年龄
};
void print_stu(struct Stu s)
{printf("%s %d\n", s.name, s.age);
}
void set_stu(struct Stu* ps)
{strcpy(ps->name, "李四");ps->age = 28;
}
int main()
{struct Stu s = { "张三", 20 };print_stu(s);set_stu(&s);print_stu(s);return 0;
}

4.结构的特殊声明

在声明结构的时候,可以不完全的声明。
⽐如:
//匿名结构体类型
struct
{int a;char b;float c;
}x;
struct
{int a;char b;float c;
}a[20], *p;
匿名结构体是指在定义结构体变量时不指定结构体名称,直接定义结构体的成员变量。这样定义的结构体没有结构体名,只有成员变量名。

匿名结构体常用于临时的、不需要重复使用的数据结构,可以在需要时直接定义和使用,无需为命名。

需要注意的是,由于匿名结构体没有结构体名称,因此无法在其他地方再次定义相同的结构体类型。匿名结构体的作用范围仅限于定义该结构体的作用域内。

5.结构的自引用

在结构中包含一个类型为该结构本身的成员是否可以呢?
比如,定义一个链表的节点:
struct Node
{
int data;
struct Node next;
};
上述代码正确吗?如果正确,那 sizeof(struct Node) 是多少?
仔细分析,其实是不行的,因为一个结构体中再包含一个同类型的结构体变量,这样结构体变量的大小就会无穷的大,是不合理的。

结构体的自引用是指在结构体定义中包含对自身类型的成员变量。

在C语言中,结构体的自引用可以通过使用指针来实现。为了在结构体中引用自身类型,需要先定义一个指向自身类型的指针成员变量。

正确的自引用方式:
struct Node {int data;struct Node* next;  // 指向自身类型的指针成员变量
};

在上述示例中,结构体Node包含一个整型成员变量data和一个指向自身类型struct Node的指针成员变量next。这样就实现了结构体的自引用。

自引用的结构体常用于构建链表、树等数据结构。通过指针成员变量,可以将多个结构体实例链接在一起形成复杂的数据结构。(详细结构请友友们参照数据结构的相关内容理解)

在结构体自引用使用的过程中,夹杂了 typedef 对匿名结构体类型重命名,也容易引⼊问题,看看
下面的代码,可行吗?
typedef struct
{
int data;
Node* next;
}Node;
答案是 不行的,因为Node是对前面的匿名结构体类型的重命名产生的,但是在匿名结构体内部提前使用Node类型来创建成员变量,这是不行的。
故定义结构体不要使用匿名结构体了
typedef struct Node
{int data;struct Node* next;
}Node;

结束语

本节内容小编对结构体的大部分内容都做了详细的解释,相信大家都对结构体有了了解,下节内容小编将带领大家进一步理解结构体的大小,如何计算,遵循什么规则等!

支持小编的留下赞赞和评论吧,感谢大家!!!

相关文章:

c语言回顾-结构体

前言 在前面的学习中&#xff0c;我们知道C语言提供了许多内置类型&#xff0c;如&#xff1a;char、short、int、long、float、double等&#xff0c;但是只有这些内置类型还是不够的。当我们想描述学生&#xff0c;描述一本书&#xff0c;这时单一的内置类型是不行的。描述一个…...

stable diffusion最全插件大全,新手必备指南

Stable diffusion30个必备插件推荐&#xff0c;给我点个赞吧&#xff0c;兄弟们 1&#xff0c;ComfyUI&#xff0c;SD扩展里面直接搜索就行&#xff0c; ComfyUI 是一个基于节点操作的UI界面&#xff0c;玩过建模的更容易学 安装后大概是这样的 评价&#xff1a;comfyui,更适…...

大模型开发LangChain简介

LangChain 是一个用于构建大型语言模型 (LLM) 驱动应用程序的开发框架。它提供了强大的工具和功能&#xff0c;帮助开发者更高效地使用语言模型来构建复杂的应用程序。 LangChain 的主要功能和特点 1、模块化设计&#xff1a; LangChain 采用模块化设计&#xff0c;分为多个…...

Camtasia Studio 2024软件最新版下载【安装详细图文教程】

​Camtasia是美国TechSmith公司出品的一款集电脑屏幕录制、视频剪辑为一体的软件套装。同时包含Camtasia 录制器、Camtasia Studio&#xff08;编辑器&#xff09;、Camtasia 菜单制作器、Camtasia 剧场、Camtasia 播放器和Screencast的内置功能。 安 装 包 获 取 地 址&#x…...

抖音视频素材在哪找无版权?免版权可以剪辑视频素材网站分享

在抖音视频制作中&#xff0c;素材的选择至关重要。今天&#xff0c;我就为大家推荐几个宝藏网站&#xff0c;帮你找到既好用又无版权纠纷的视频素材。无论你是新手还是老手&#xff0c;这些网站都能满足你的需求。 蛙学府 首先推荐的是蛙学府。这个网站提供丰富的视频素材&am…...

Dubbo-使用zookeeper作为注册中心时节点的概述

本文内容很容易理解&#xff0c;会阐述当dubbo使用zookeeper作为注册中心时候&#xff0c;zookeeper节点是什么样子的 本文的代码使用的dubbo版本是2.7.x&#xff0c;几年前的版本了&#xff0c;但是不影响探究 首先我们创建一个简单的maven项目&#xff0c;然后写出一段dubb…...

秋招突击——第四弹——Java的SSN框架快速入门——Maven

文章目录 引言Maven分模块开发与设计分模块开发的过程 依赖管理可选依赖与排除依赖 继承与聚合聚合继承 属性和版本管理属性扩大集中管理的范围版本管理 多环境开发多环境开发 私服简介安装私服资源操作流程分析上传和下载 总结 引言 前一个部分花了太多时间&#xff0c;后续得…...

【Python】数据处理:CSV文件操作

CSV 文件&#xff08;Comma-Separated Values&#xff0c;逗号分隔值文件&#xff09;是一种常见的文本文件格式&#xff0c;用于存储表格数据。它的特点是用逗号或其他特定字符&#xff08;如分号、制表符等&#xff09;来分隔不同的字段&#xff0c;每行代表表格中的一条记录…...

SpringBoot集成Elasticsearch实例

SpringBoot项目集成Elasticsearch实例 导包 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-elasticsearch</artifactId> </dependency>配置es连接 spring:data:elasticsearch:cluster…...

2024.ZCPC.M题 计算三角形个数

题目描述&#xff1a; 小蔡有一张三角形的格子纸&#xff0c;上面有一个大三角形。这个边长为 的大三角形&#xff0c; 被分成 个边长为 1 的小三角形(如图一所示)。现在&#xff0c;小蔡选择了一条水平边 删除&#xff08;如图二所示&#xff09;&#xff0c;请你找出图上剩余…...

Java常见设计模式入门与实践

设计模式是软件开发中被反复应用的、为解决特定问题而总结出的最佳实践。它们提供了开发可重用、灵活和高效软件系统的方法。在Java中&#xff0c;设计模式可以帮助开发者编写更高质量的代码。以下是Java中一些常用设计模式的入门介绍及其实践示例。 1. 单例模式 (Singleton P…...

110.平衡二叉树

给定一个二叉树&#xff0c;判断它是否是 平衡二叉树 题解&#xff1a;平衡二叉树 是指该树所有节点的左右子树的深度相差不超过 1。可以采用递归遍历每一个节点&#xff0c;得到其高度&#xff0c;在判断高度时不可避免的要用到其左右子树的高度&#xff0c;所以可以顺便判断出…...

字符串数组——传递文本的不同方法实例

一、实例化一个文本并在文本上直接显示接收的信息 1、制作一个预制体 (1) UI-Text (TMP)&#xff0c;TitleText (2) 给Text (TMP)添加Recipients.cs组件 using System.Collections; using System.Collections.Generic; using TMPro; using UnityEngine;public class Recipi…...

JDBC简介

JDBC最基本的知识点要求理解并会使用下边的两个案例即可&#xff1a; 前言&#xff1a; Jdbc操作步骤简析&#xff1a; 1.Connection connDriverManager.getConnection(url,账号&#xff0c;密码)&#xff1a;用DriverManager类的连接方法根据url账号密码连接数据库&#xf…...

RK3568平台(触摸篇)触摸屏基本原理

一.触摸屏概述 触摸屏作为一种新的输入设备&#xff0c;它是目前最简单、方便、自然的一种人机交互方式。 触摸屏又称为“触控屏”、“触控面板”&#xff0c;是一种可接收触头等输入讯号的感应式液晶显示装置&#xff1b;当接触了屏幕上的图形按钮时&#xff0c;屏幕上的触觉…...

【太原理工大学】软件系统安全—分析题

OK了&#xff0c;又是毫无准备的一场仗&#xff0c;我真是ありがとうございます 凸^o^凸 根据前几年传下来的信息&#xff0c;所谓“分析”&#xff0c;就是让你根据情节自行设计&#xff0c;例如如何设计表单等&#xff0c;这类多从实验中出&#xff0c;王老师强调好好做实验一…...

【仪器仪表/电源专题】浮地信号的测试的四种方案对比

接地信号和浮地信号区别 所有的电压测量都是差分测量&#xff0c;差分测量定义为两点之间的电压差。所以会分成两类&#xff1a; 1.参考地电平测量&#xff08;有时也叫接地信号&#xff09; 2.非参考地电平测量&#xff08;也称为浮地测量&#xff09; 测试信号可以分为接地信…...

Centos7安装jdk8或11以及切换方案

目录 jdk安装 安装OpenJDK11 安装OpenJDK8 配置默认的 Java 版本 验证 全局环境变量&#xff08;选配&#xff09; 个人版&#xff08;自己可以用&#xff0c;公司不建议&#xff09; 公司版本 /etc/profile 和 ~/.bash_profile 区别 前言-与正文无关 生活远不止眼前的苦…...

计算机二级Access选择题考点—代码篇

第1题 窗体的事件过程如下: Private Sub Form MouseDown(Button As Integer ,Shift As integer,X As Single,Y As Single)If Shift 6 And Button 2 Then MsgBox "Hello World."End lf End Sub程序运行后&#xff0c;要在窗体消息框中显示"Hello World."…...

海外仓系统如何让海外仓受益,WMS海外仓系统使用指南

随着跨境电商业务的快速发展&#xff0c;海外仓面临着需要更加高速运转的巨大挑战。 当海外仓出现因为手动作业导致效率低下&#xff0c;成本不断飙升或者出现库存管理问题的时候&#xff0c;意味着是时候引入一套合适的海外仓管理系统了。 对于寻求海外仓业务流程优化的企业…...

基于算法竞赛的c++编程(28)结构体的进阶应用

结构体的嵌套与复杂数据组织 在C中&#xff0c;结构体可以嵌套使用&#xff0c;形成更复杂的数据结构。例如&#xff0c;可以通过嵌套结构体描述多层级数据关系&#xff1a; struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...

uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖

在前面的练习中&#xff0c;每个页面需要使用ref&#xff0c;onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入&#xff0c;需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...

SCAU期末笔记 - 数据分析与数据挖掘题库解析

这门怎么题库答案不全啊日 来简单学一下子来 一、选择题&#xff08;可多选&#xff09; 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘&#xff1a;专注于发现数据中…...

cf2117E

原题链接&#xff1a;https://codeforces.com/contest/2117/problem/E 题目背景&#xff1a; 给定两个数组a,b&#xff0c;可以执行多次以下操作&#xff1a;选择 i (1 < i < n - 1)&#xff0c;并设置 或&#xff0c;也可以在执行上述操作前执行一次删除任意 和 。求…...

多模态大语言模型arxiv论文略读(108)

CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题&#xff1a;CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者&#xff1a;Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...

稳定币的深度剖析与展望

一、引言 在当今数字化浪潮席卷全球的时代&#xff0c;加密货币作为一种新兴的金融现象&#xff0c;正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而&#xff0c;加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下&#xff0c;稳定…...

JVM 内存结构 详解

内存结构 运行时数据区&#xff1a; Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器&#xff1a; ​ 线程私有&#xff0c;程序控制流的指示器&#xff0c;分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 ​ 每个线程都有一个程序计数…...

从面试角度回答Android中ContentProvider启动原理

Android中ContentProvider原理的面试角度解析&#xff0c;分为​​已启动​​和​​未启动​​两种场景&#xff1a; 一、ContentProvider已启动的情况 1. ​​核心流程​​ ​​触发条件​​&#xff1a;当其他组件&#xff08;如Activity、Service&#xff09;通过ContentR…...

算法打卡第18天

从中序与后序遍历序列构造二叉树 (力扣106题) 给定两个整数数组 inorder 和 postorder &#xff0c;其中 inorder 是二叉树的中序遍历&#xff0c; postorder 是同一棵树的后序遍历&#xff0c;请你构造并返回这颗 二叉树 。 示例 1: 输入&#xff1a;inorder [9,3,15,20,7…...

客户案例 | 短视频点播企业海外视频加速与成本优化:MediaPackage+Cloudfront 技术重构实践

01技术背景与业务挑战 某短视频点播企业深耕国内用户市场&#xff0c;但其后台应用系统部署于东南亚印尼 IDC 机房。 随着业务规模扩大&#xff0c;传统架构已较难满足当前企业发展的需求&#xff0c;企业面临着三重挑战&#xff1a; ① 业务&#xff1a;国内用户访问海外服…...