<c语言学习>结构体

结构体类型

        为什么要有结构体

                我们用c语言描述年龄时候,可以定义一个整形类型来实现:

int age;
age = 18;
printf("年龄为%d",age);

(c语言描述年龄)

                由于年龄这一属性比较单一,类似性别、某游戏角色攻击力、血量都可以用c语言内置的变量来描述。

                但是如果现在需要描述一本书或一个游戏装备,这种有多种属性的角色,只用一个变量看起来就不够用了,我们需要一种方式(结构体)来描述他们:

                例如描述一本书,我们可以这样说:“书的名字是xxx,书的作者是xxx,书的总页数是xxx”,这时我们需要定义一个结构体类型,以描述这些属性。

        结构体类型定义,初始化,使用

                结构体定义

                        以下是定义一个用来描述书的结构体类型,模样如下:
 

//struct 表示结构体 book 表示结构体类型名称
struct book
{//此处为自定义结构体类型“book” 的属性们char name[20];char writer[20];int n;
}
                结构体初始化
//前面定义了结构体变量类型,现在用定义好的类型创建一个结构体:
struct book doom; //"wtruct book"表示类型  “doom”表示结构体变量名//结构体初始化类似于普通变量的初始化:
int a; //“int”表示类型 “a”表示变量名doom.n = 30;//赋值结构体doom中的n(书的页数)strcpy(doom.name,"老人与海")//f赋值结构体doom中的name(书名)
                结构体使用
printf("%d",doom.n);//打印书的页数

结构体对齐

        为什么要有结构体对齐

                假如我们现在有这样的一个结构体:

struct test//定义类型
{char a;int b;int c;int d;
}struct test A;//创建一个结构体A

                

      我们可能想象的A在内存中是这样放的:

        对于我们来说一目了然,但是对于计算机读取来说就麻烦了,假如现在有一个机器,他一次可以读四个字节,那么他访问结构体A可能需要七次才能读完:

        我们可以通过某种规则让他变成方便计算机读取的存储形式:

        空间换时间,用三个字节的代价,让计算机读取这个结构体用的次数减少了三次。

        对齐规则

      以下是结构体对齐规则的基本要点:

  1. 首个成员对齐

    • 结构体的第一个成员总是从结构体变量的起始地址开始存放,偏移量为0。
  2. 成员对齐规则

    • 后续每个成员在结构体中的偏移量需要是对齐数的整数倍,其中对齐数一般等于该成员的大小或编译器默认的对齐数(机器相关的最小对齐单位)两者中的较小值。
    • 比如,如果一个结构体里有一个int成员,而在当前平台上int大小为4字节且默认对齐单位也为4字节,那么该int成员将被放在4字节对齐的位置上。
  3. 结构体大小对齐

    • 结构体的总大小(包括可能存在的填充字节)需要是所有成员中最大对齐数的整数倍。
    • 结构体末尾可能会添加额外的字节作为填充,以满足上述对齐要求。
  4. 结构体自身的对齐值

    • 结构体的有效对齐值通常是其所有成员中最大对齐值的成员的对齐值,确保整个结构体实例的起始地址也符合这个最大对齐值的要求。
    • 当结构体组成数组时,结构体之间的间隔也将按照结构体的有效对齐值来确定。
  5. 编译器控制

    • 许多编译器允许通过预编译指令(如C/C++中的#pragma pack(n))来指定自定义的对齐值,这样会暂时改变当前作用域内的结构体对齐策略。

        

结构体位段

        为什么要有结构体位段

                假如有这样的一个结构体类型:
                

//类型名称考试成绩
struct Scores
{int math;int english;int chinese;
}

                一般来说,一个成绩只需要三位数就可以描述,也就是只需要八个机器码(比特)完全够用了,而一个int类型要占用32个机器码(比特),这样就显得很浪费了。

                为了解决这个问题(节省空间),我们可以使用结构体位段。简单来说,就是让变量们挤一挤。比如上面的Scores结构体,让三科的成绩挤在一个整形int里。

        

                这样浪费的空间就少了很多,用位段定义这个成绩结构体类型如下:
 

struct Scores
{int :math;int :english;int :chinese;
}

        结构体位段规则(不同编译器有所差异)

        结构体位段(Bit-field)是C语言中一种特殊的数据结构,允许在一个整型变量(通常为intunsigned int)内划分多个命名的位区域。位段的规则主要包括:

  1. 声明格式: 在结构体中定义位段时,格式如下:

    struct {type member_name : bit_width;// 其他位段...
    } variable_name;

  2. 其中,type是位段成员的类型,但实际存储时会被隐式转换为足够容纳所有位段的整型类型;member_name是位段的名称;bit_width是在该位段中使用的位数。

  3. 分配顺序: 位段成员在内存中按照声明顺序从左向右分配,但不同的编译器可能会有不同的分配策略,有的是从最低有效位(LSB)开始分配,有的是从最高有效位(MSB)开始分配。

  4. 位段宽度: bit_width指定的位数不能超过成员类型的位宽。例如,在32位系统中,一个int类型的位段的宽度范围是1到32。

  5. 未指定宽度: 如果省略位宽,则大多数编译器会根据成员类型自动选择合适的位宽,直到填满包含位段的整数。

  6. 存储开销: 编译器会尽可能紧凑地安排位段,但可能会在位段之间加入额外的位作为填充,以便于整体对齐,并且至少会分配一个完整的基本整型变量的空间(如一个int)来存储所有位段。

  7. 跨边界行为: 不同编译器对于位段跨越一个基本整型变量边界的处理方式不同。有些编译器会在下一个整型变量中继续分配,而有些则可能不支持跨越边界。

  8. 初始化和赋值: 可以初始化位段,但赋值时要注意仅修改指定位段的位,不会影响同一存储单元内其他位段的值。

  9. 跨平台差异: 位段的具体行为依赖于编译器实现,因此在不同平台和编译器之间可能存在显著差异,编写可移植的位段代码时需特别小心。

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

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

相关文章

string类详解及重要函数实现

🪐🪐🪐欢迎来到程序员餐厅💫💫💫 今日主菜:string类 主厨:邪王真眼 所属专栏:c专栏 主厨的主页:Chef‘s blog 前言: 咱们之前也是…

第十三届蓝桥杯物联网试题(省赛)

做后感悟: OLED显示函数需要一直显示,所以在主函数中要一直循环,为了确保这个检错功能error只输出一次,最好用中断串口进行接收数据,数据收完后自动进入中断函数中,做一次数据检查就好了,该开灯…

银行数字人民币系统应用架构设计

2019年10月,01区块链联合数字资产研究院发布了《人民币3.0:中国央行数字货币运行框架与技术解析》,从数字货币界定和人民币发展历程出发,区分了央行数字货币与比特币、移动支付等的区别,全面介绍了央行数字货币的发展历…

Linux设备驱动开发 - 三色LED呼吸灯分析

By: fulinux E-mail: fulinux@sina.com Blog: https://blog.csdn.net/fulinus 喜欢的盆友欢迎点赞和订阅! 你的喜欢就是我写作的动力! 目录 展锐UIS7885呼吸灯介绍呼吸灯调试方法亮蓝灯亮红灯亮绿灯展锐UIS7885呼吸灯DTS配置ump9620 PMIC驱动ump9620中的LED呼吸灯驱动LED的tr…

代码+视频,R语言logistic回归交互项(交互作用)的可视化分析

交互作用效应(p for Interaction)在SCI文章中可以算是一个必杀技,几乎在高分的SCI中必出现,因为把人群分为亚组后再进行统计可以增强文章结果的可靠性,不仅如此,交互作用还可以使用来进行数据挖掘。在既往文章中,我们已…

【理解机器学习算法】之分类问题的模型评估(ROC-AUC)

ROC曲线(接收者操作特性曲线)和AUC(曲线下面积)是在不同阈值设置下,用于分类问题的性能度量工具。下面是它们所代表的含义以及使用方法: ROC曲线 代表含义:ROC曲线是一个图形化的表示&#xf…

掌握收支明细,轻松记录收支明细,一键打印财务自由

在繁忙的生活中,你是否曾感到对个人的财务状况一头雾水?是否曾在需要证明收支情况时手忙脚乱,翻箱倒柜地寻找凭证?今天,我要向你揭示一个简单而高效的方法,帮助你轻松记录收支明细,并一键打印&a…

Cesium 默认选中框设置

Cesium 默认提供的选中框 进来关注下不迷人,还有更多集合专栏! 1、设置状态: 设置false 就不会出现这个默认的状态,如果需要修改如下: viewer._selectedEntitynewEntity newEntity 就是你需要设置选中框的样式 可以…

BGP4+简介

定义 BGP是一种用于自治系统AS(Autonomous System)之间的动态路由协议,常用版本是BGP-4,BGP-4只能传递IPv4路由。针对IPv6的BGP4扩展,通常称为BGP4。 目的 BGP4用于在AS之间传递路由信息,并不是所有情况…

python - 更改pdf中文本的字体高亮颜色(fitz模块)

import fitzdoc fitz.open(r"e:/test.pdf") pagedoc[0]# 按照指定的位置设置颜色 highlight page.add_highlight_annot((20, 500,60, 520)) highlight.set_colors(stroke[1, 1, 0]) # light red color (r, g, b) 颜色rgb每个除以255得出 highlight.update()# 按照…

YZ系列工具之YZ09: VBA_Excel之读心术

我给VBA下的定义:VBA是个人小型自动化处理的有效工具。利用好了,可以大大提高自己的工作效率,而且可以提高数据的准确度。我的教程一共九套一部VBA手册,教程分为初级、中级、高级三大部分。是对VBA的系统讲解,从简单的…

大数据分析-基于Python的电影票房信息数据的爬取及分析

概要 现如今,人民群众对物质生活水平的要求已不再局限于衣食住行,对于精神文化有了更多的需求。电影在我国越来越受欢迎,电影业的发展越来越迅猛,为了充分利用互联网技术的发展,掌握电影业的态势,对信息进行…

uniapp 写安卓app,运行到手机端 调试

手机 设置》关于手机》点击版本号 4-5次,弹出手机锁屏页面,输入手机锁屏密码 2.手机 设置中 》搜索 开发人员选项 》 调试》打开USB调试 同页面 找到 选择USB配置》选择 MIDIhbuilder 编辑器 点击 》运行》运行到手机或模拟器》运行到Android App基座 》…

打卡--MySQL8.0 三 (SQL语言)

SQL语言介绍 SQL 是 Structured Query Language(结构化查询语言)的缩写。 SQL 是用来与关系数据库进行通信的。 它是关系数据库管理系统的标准语言。 SQL 语句用于执行任务,如更新数据库中的数据,或从数据库中检索数据。 一些常见…

【滑动窗口】长度最小的子数组|无重复字符的最长子串|最大连续1的个数 III|将 x 减到 0 的最小操作数

1. 长度最小的子数组 - 力扣(LeetCode) 1.题目解析: 2.算法原理 (1)方法一:暴力列举出所有的子数组的和 时间复杂度:O(n**2):枚举所有子数组O(…

在Windows中安装wsl2和ubuntu22.04

目录 一、概述二、安装wsl22.1 虚拟化设置2.2 虚拟化设置2.3 切换和更新wsl2 三、安装ubuntu3.1 下载Ubuntu22.043.2 配置Ubuntu22.04 一、概述 wsl2是一种面向Windows操作系统的虚拟化技术,可以让我们在Windows操作系统中“丝滑”的运行Linux系统。wsl2由微软团队…

WMI接口设计实现

WMI是Windows操作系统管理数据和操作的基础设施,系统管理员可以使用VB Script、PowerShell及Windows API(C、C#等)管理本地或远程计算机。 使用WMI框架应用程序可以直接访问EC RAM、 I/O端口、Memory地址、寄存器、Setup NV设定值&#xff0c…

ideaSSM 财务凭证管理系统bootstrap开发mysql数据库web结构java编程计算机网页源码maven项目

一、源码特点 idea 开发 SSM 财务凭证管理系统是一套完善的信息管理系统,结合SSM框架和bootstrap完成本系统,对理解JSP java编程开发语言有帮助系统采用SSM框架(MVC模式开发),系统具有完整的源代码和数据库&#xff…

【史上最全面arduino esp32教程】ESP32Time时间库

文章目录 前言一、安装ESP32Time库二、ESP32Time使用2.1 基础使用构造ESP32Time对象设置当前时间获取当前时间结构体 2.2 其他函数 总结 前言 欢迎来到这篇Arduino ESP32教程!在本教程中,我们将介绍ESP32Time时间库的使用。时间在许多项目中起着重要的作…

基于SSM的手机商城管理系统+数据库+论文+免费远程调试

项目介绍: 基于SSM的手机商城管理系统。Javaee项目,采用M(model)V(view)C(controller)三层体系结构,通过Spring SpringMvc Mybatis JspBootstrapLayui来实现。MySQL数据库作为系统…