C语言进阶——自定义类型——结构体

news2025/1/11 15:01:26

目录

一.   结构体类型的声明

结构体的声明

特殊的声明

二.   结构的自引用

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

定义

初始化

四.   结构体内存对齐

 未完待续


一.   结构体类型的声明

结构体的声明

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

struct tag
{
        member-list;
}variable-list;

例如描述一个学生:

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

在使用时,需要带上struct,我们也可以使用typedef将其重命名。

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

特殊的声明

在声明的时候可以省略掉结构体标签(tag)

struct
{
    int a;
    char b;
    float c;
}x;

当然,这种特殊的声明在一个作用域中只能声明一次

struct
{
    int a;
    char b;
    float c;
}x;
struct
{
    int a;
    char b;
    float c;
}*p;

在上面的两个结构体中,即使结构体成员都是相同的,但编译器依然会将其认作是两个结构体,固而不能使用 p=&x 这种写法



二.   结构的自引用

结构的自引用,就是在结构中包含一个类型为该结构本身的成员

例如在链表中就使用了结构体的自引用

在自引用中,使用的应该是指针类型,而不是该结构体本身的成员

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

 这是因为若是为该结构本身的成员,会不断发生嵌套定义。

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

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

而在使用typedef重命名的情况下,我们并不能使用第一种自引用方式,因为重命名是在成员定义之后发生的。



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

定义

struct Point
{
    int x;
    int y;
}p1; 
struct Point p2

两种方式


初始化

struct Point
{
    int x;
    int y;
}
struct Point p3 = {1, 2};

不仅如此,我们还可以乱序进行初始化

struct Point
{
    int x;
    int y;
}
struct Point p3 = {.y=2, .x=1};

当然,若是结构体成员中包含结构体变量,直接使用多层花括号进行初始化即可



四.   结构体内存对齐

1.结构体的第一个成员,对齐到结构体在内存中存放位置的0偏移处。

2.从第二个成员开始,每个成员都要对齐到(一个对齐数)的整数倍处对齐数:结构体成员自身大小和默认对齐数的较小值(VS:默认对齐数数8Linux gcc:没有默认对齐数,对齐数就是结构体成员的自身大小)

3.结构体的总大小,必须是所有成员的对齐数中最大对齐数的整数倍。

4.如果结构体中嵌套了结构体成员,要将嵌套的结构体成员对齐到自己的成员中最大对齐数的整数倍处。

直接看定义不太好理解,我们来举几个例子

struct S1
{
    char c1;
    int i;
    char c2;
};

首先,第一个成员对齐到0偏移处

之后int 的大小为4个字节,对齐数为4,因此第二个成员需要对齐到4

之后char 的大小为1个字节,对齐数为1,直接对齐到8     

这样大小为9,由于需要为最大对齐数(4)整数倍,所以最后总大小为12

struct S2
{
    char c1;
    char c2;
    int i;
};

首先,第一个成员对齐到0偏移处

之后char 的大小为1个字节,对齐数为1,直接对齐到1

之后int的大小为4个字节,对齐数为,4,对齐到4   

这样大小为8,由于需要为最大对齐数(4)整数倍,所以最后总大小也是8

 

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

 首先,第一个成员对齐到0偏移处

之后char 的大小为1个字节,对齐数为1,直接对齐到8

之后int的大小为4个字节,对齐数为4,对齐到12

这样大小为16,由于需要为最大对齐数(8)整数倍,所以最后总大小也是16

struct S4
{
    char c1;
    struct S3 s3;
    double d;
};

 首先,第一个成员对齐到0偏移处

之后是嵌套的结构体成员,可以看到,最大对齐数为8,所以需要对齐到8

之后double的大小为8个字节,对齐数为8,对齐到24

这样大小为32,由于需要为最大对齐数(8)整数倍,所以最后总大小也是32

 

为什么存在内存对齐?

这个问题到现在也没有一个明确的答案,但就大多数参考书所言,主要有两点

1. 平台原因(移植原因):

不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。

2. 性能原因:

数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。
 



 未完待续

 

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

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

相关文章

08-Alibaba微服务组件Nacos配置中心实战源码分析

Nacos配置中心源码分析 Config相关配置 Nacos 数据模型 Key 由三元组唯一确定, Namespace默认是空串,公共命名空间(public),分组默认是DEFAULT_GROUP 配置中心的架构 nacos config client源码分析 获取配置 获取配置的主要方…

windows配置java环境

windows配置java环境下载JDK安装JDK配置环境变量java9及以上版本配置环境变量(以java17为例,只需要配置JAVA_HOME和Path变量)配置JAVA_HOME变量配置Path变量java8及以下版本配置环境变量(以java8为例,需要配置JAVA_HOM…

Unity官方本地化插件localization

官方文档地址:https://docs.unity3d.com/Packages/com.unity.localization1.0/manual/QuickStartGuideWithVariants.html 使用流程 安装 PackageManager搜索Localization完成对应插件的安装 配置 PlayerSetting->Localization 创建本地化相关配置 创建之后点…

python的安装以及pycharm的配置

大家好,我是csdn的博主:lqj_本人 这是我的个人博客主页:lqj_本人的博客_CSDN博客-微信小程序,html特效,vue2基础领域博主 哔哩哔哩欢迎关注:小淼前端 小淼前端的个人空间_哔哩哔哩_bilibili 本篇文章主要讲述python的安装以及pych…

【Linux】小程序进度条

目录回车换行问题日常中的换行代码中的回车换行倒计时函数进度条回车换行问题 日常中的换行 即: 回车:回到当前行的最开始 换行:列不变,新起一行 代码中的回车换行 我们先看一段代码: 这个是带\n的 🌍结…

什么是运动神经元 你们真的知道吗

大家好,你们知道什么运动神经元吗,你们有误入这些误区吗? 运动神经元是一种神秘的疾病,导致的原因尚且不明确。这种疾病的发生可能是体内的运动神经元细胞的减少或是凋亡导致的,是一种慢性发展的神经类疾病。虽然导致运…

【晶振】NTP网络校时服务器(卫星时钟)电路里的主心跳

【晶振】NTP网络校时服务器(卫星时钟)电路里的主心跳 【晶振】NTP网络校时服务器(卫星时钟)电路里的主心跳 晶振是NTP网络校时服务器(卫星时钟)电路板数字电路的"心跳",在…

阿狸(Hans设计卡通形象)的幸福生活 ---- 充满趣味性(可自定义更改)

Ali the fox 目录 一、前言 二、关于代码 三、效果展示 四、详细介绍 五、编码实现 index.html css 文件夹 88rh.css js 文件夹 img 文件夹 fonts 文件夹 六、获取源码 需要源码,可以私信我(⊙o⊙)?关注我? 一、前言 时光荏苒&…

MyBatis­Plus快速入门

介绍 MyBatisPlus(简称 MP)是一个 MyBatis的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。 特性: 无侵入:只做增强不做改变,引入它不会对现有工程产生影响&#xf…

冰冰学习笔记:异常处理

欢迎各位大佬光临本文章!!! 还请各位大佬提出宝贵的意见,如发现文章错误请联系冰冰,冰冰一定会虚心接受,及时改正。 本系列文章为冰冰学习编程的学习笔记,如果对您也有帮助,还请各位…

Github-Action-Workflow-概念和基本操作

workflow 文件 GitHub Actions 的配置文件叫做 workflow文件,存放在代码仓库的.github/workflows/目录下。比如写一个first.yaml文件,存储的目录就是.github/workflows/first.yaml workflow/下的文件采用 YAML 格式,文件名可以任意取&#xf…

代码随想录第56天|● 583. 两个字符串的删除操作 ● 72. 编辑距离

583.两个字符串的删除操作 思路一 dp[i][j]:以i-1为结尾的字符串word1,和以j-1位结尾的字符串word2,想要达到相等,所需要删除元素的最少次数。 当word1[i - 1] 与 word2[j - 1]相同的时候 dp[i][j] dp[i - 1][j - 1];当word1[…

检修盒面板AI视觉检测系统,赋能工业发展!

制造业是中国工业化的源头,也是工业生产大国。任何一步的质量都可能影响生产过程的变化。表面缺陷不仅影响产品的美观和舒适性,还会对其性能产生不良影响。因此,制造商对产品的表面缺陷检测非常重视。传统的检修盒面板按钮安装是否正确的质量…

【深度学习】CNN应用于图像分类的建模全流程

文章目录1.摘要2.图片的准备及预处理3.打包并保存数据4.搭建模型5.训练模型6.测试模型7.总结1.摘要 图像分类,也可以称作图像识别,顾名思义,就是辨别图像中的物体属于什么类别。核心是从给定的分类集合中给图像分配一个标签的任务。实际上&a…

DBeaver连接InterSystems IRIS、Ensemble、Cache操作说明

一、驱动获取 1.1、本地安装目录获取 JDBC驱动:“安装目录\dev\java\lib\JDK18” 如需获取ODBC等其他连接驱动则返回“安装目录\dev”路径选择对应文件夹2.1、Intersystems官方获取 官方下载:https://intersystems-community.github.io/iris-driver-…

深度学习基本部件-激活函数详解

激活函数概述 前言激活函数定义激活函数性质 Sigmoid 型函数 Sigmoid 函数Tanh 函数 ReLU 函数及其变体 ReLU 函数Leaky ReLU/PReLU/ELU/Softplus 函数 Swish 函数激活函数总结参考资料 本文分析了激活函数对于神经网络的必要性,同时讲解了几种常见的激活函数的原理…

纸牌游戏红心大战拱猪设计(C语言)

纸牌游戏红心大战设计 ( C语言 ) 红心大战是Windows的经典游戏,中国式的红心是拱猪游戏,加入了方块J羊和梅花10 变压器(即俗称加倍)。加大了游戏难度和趣味性。 试制此游戏是准备编制网络版拱猪或红心大战的基础框架&#xff0c…

Linux下时间处理相关函数

Linux下时间处理相关函数 1 .系统时间和 RTC 时间 Linux 系统下包含两个时间: 系统时间和 RTC 时间。   系统时间: 是由主芯片的定时器进行维护的时间, 一般情况下都会选择芯片上最高精度的定时器作为系统时间的定时基准, 以避…

深度聚类方法之对比聚类(Contrastive Clustering,CC)

1.参考文献 《Contrastive Clustering》 2.深度聚类方法 深度聚类方法大致分为以下几类: ①分阶段:使用深度网络进行对比学习or自动编码器完成表征学习(目的:把同类样本集中到一起,拉开不同类样本的聚类),然后使用聚…

【6】SCI易中期刊推荐——人工智能神经科学机器人学(中科院3区)

🚀🚀🚀NEW!!!SCI易中期刊推荐栏目来啦 ~ 📚🍀 SCI即《科学引文索引》(Science Citation Index, SCI),是1961年由美国科学信息研究所(Institute for Scientific Information, ISI)创办的文献检索工具,创始人是美国著名情报专家尤金加菲尔德(Eugene Garfield…