结构体(声明、初始化、内存对齐、如何传参)

2023-11-03

结构基础知识

聚合数据类型能够同时存储超过一个的单独数据。C提供了两种类型的聚合数据类型,分别是数组和结构体。数组是相同元素的集合,它的每个元素是通过下标引用或指针间接访问的。结构体也是一些值的的集合,这些值称为它 的成员,但一个结构的成员可能具有不同的类型。数组元素可以通过下标访问,这是因为数组元素长度相同,但在结构体中并非如此,由于每个成员的类型可能不同,那么长度也就可能不同,所以就不能通过下标来访问。但是结构体成员都有自己的名字,他们是通过名字访问的。另外,结构体在表达式中使用时,不能被替换为指针。结构体变量也无法使用下标来选择特定的成员。

结构体的声明


这个结构体创建了结构体变量x,结构体包含了2个成员:整型a,字符ch。

结构体声明哪些可以省略?

标签A可以省略,那么就是匿名结构体类型,但不建议。在声明时可以没有结构体变量x,如果有,那么该变量为全局变量。如果在main函数中,就是局部变量。

如下:


struct A  x;

int          x;

struct A 相当于int ,也就是类型,属于结构体类型,x是结构体变量。

a[20]包含了20个结构,p是一个指针,它指向结构。

上面两个结构都忽略了结构体标签(如A),那么这个语句成立吗?p=&x?

警告:这两个声明被编译器当做两种截然不同 的类型,即使成员相同。所以,变量a,p,x,类型不同,不可p=&x。


注:用typedef后,simple是个类型名,可以创建变量。

访问结构体成员

通过.操作符访问成员:


通过->进行访问:


两者结果为:10  zhangsan

结构体自引用

我们已经知道在结构体中可以包含数组,指针,标量,结构体...那么结构体里面能不能包含该结构体本身呢?


不可以,因为不知道结构体大小,无法开辟空间存y。

正确的结构体自引用如下:


因为struct stu *y是指针类型,即为4个字节,可以开辟空间。

结构的不完整声明

偶尔,必须声明一些相互之间存在依赖的结构。即,一个结构包含了另一个结构的一个或多个成员。和自引用一样,至少一个结构必须在另一个结构中以指针的形式存在。问题在于声明部分:如果每个结构体都引用了其他 结构的标签,哪个结构应该首先声明?

这个问题的解决方案是使用不完整声明,它声明一个作为结构标签的标识符。然后,把这个标签用在不需要知道这个结构的长度的声明中,如声明指向这个结构的指针。


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

结构的初始化方式和数组初始化很相似。一个位于一对花括号内部,由逗号分隔的初始值列表可用于结构的初始化。这些值根据结构成员列表的顺序写出。


注:数组不可以整体赋值,可整体初始化。同理,结构体不可整体赋值,可以整体初始化。结构体地址数值等于第一个成员地址数值。

结构体内存对齐

为什么存在内存对齐?

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

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

2.性能原因:

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

图如下:


结构体对齐规则:

1.第一个成员在与结构体变量偏移量为0的地址处。

2.其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。对齐数=编译器默认的对齐数与该成员大小的较小值。VS中默认对齐数为8,linux默认对齐数为4.

3.结构体总大小为最大对齐数(每个成员都有一个对齐数)的整数倍。

4.如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。

那么首先看一道题:


通过内存对齐规则,答案肯定不是6,答案是12,解释如下:


再看其他例子:


结果为8。1+1+2+4=8,8是最大对齐数4的倍数。


结果为16。8+1+3+4=16,16是最大对齐数4的倍数。


结果为32。1+7+16+8=32,32是最大对齐数8的倍数。

结构体传参

我们知道数组传参会发生降级,那么结构体会不会降级呢?


结构体传参有两种形式,一个是传结构体,一个是传地址,但是建议选择传地址。因为在栈帧知识中,函数传参,是需要压入栈的,但是如果传结构体对象时,结构体过大,所占空间也就过大,会导致性能下降。

结论:结构体传参,是不会发生降级,要将参数设置为结构体的地址。










本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

结构体(声明、初始化、内存对齐、如何传参) 的相关文章

  • python - seaborn sns

    Q 这个怎么搞用sns 可以用hue sns scatterplot x y data df hue smoker plt show Q relplot vs scatterplot 比较 Q 这个图怎么搞 切换row与col来调节位置 i
  • Java工程师成神之路笔记-面向对象、平台无关性、值传递

    原文地址 Java工程师成神之路 面向对象 面向过程与面向对象 什么是面向过程 面向过程 将问题拆解成一个一个步骤 每个步骤用函数实现 依次调用即可 面向对象 将问题拆解成一个一个步骤 对每个步骤进行相应的抽象 形成对象 对每个对象进行组合
  • Linux中jdk的安装与卸载,及多版本jdk配置(宝塔面板)

    微信支付中getInputStream readAllBytes 需要用到java11 因此需要卸载之前安装的java8 一 卸载 1 获取当前已安装版本 rpm qa grep jdk 2 卸载不需要的版本 jdk名字得是上边查出来的全称

随机推荐

  • python 爬虫抓取亚马逊数据

    可以参考 亚马逊是如何反爬虫的 如果我们在请求时带上一个变化着的header 成功率就能大大的增加了 headers randHeader rHtml requests get url headers headers timeout 20
  • Docker容器监控之 CAdvisor+InfluxDB+Granfana(CIG)

    docker 命令 docker stats 这样虽然也能展示 但是数据没有持久化 没有健康指标过线预警等功能 CAdvisor CAdvisor是一个容器监控资源工具 包括容器的内存 CPU 网络IO 磁盘IO等监 同时提供了一个web页
  • Linux vim的简单配置(高亮+自动缩进+行号+折叠+优化)+初始代码

    在Linux中配置文件的位置 在目录 etc 下面 有个名为vimrc的文件 这是系统中公共的vim配置文件 对所有用户都有效 而在每个用户的主目录下 都可以自己建立私有的配置文件 命名为 vimrc 首先输入su命令 获得root权限 输
  • node-red的udp数据处理及switch应用

    1 配置udp in节点 本次实验接受是字符串信息 故打开udp监听端口 输出也是字符串 f0 AF31A1FBA599 19 F6D88D5A2302 00 00 00 005E00410000580000120953000000 83
  • intellij idea 13&14 插件推荐及快速上手建议 (已更新!)

    早些年 在外企的时候 公司用的是intellij idea 当时也是从eclipse MyEclipse转过去的很是不习惯 用了一周明显感觉爱上它了 因为它很智能 而且能纠正你很多不好的习惯 后来跳巢到一家上市公司 因为大家都在用MyEcl
  • CUDA 11.2.targets(606,9): error : The CUDA Toolkit v11.2 directory ‘‘ does not exist. Please verify

    SET CMAKE CUDA COMPILER C sdk CUDA 11 2 bin nvcc exe Check for working CUDA compiler C sdk CUDA 11 2 bin nvcc exe Check
  • 关于Android Studio2.3版本用小米4,小米5调试报Installation failed with message Failed to establish session. 解决办法

    最近刚把AS版本升级到2 3 突然发现以前可以用小米4 小米5调试的 升级后发现不能用了 一直提示Installation failed with message Failed to establish session 一直是以为我手机上有
  • 互金场景下竞价广告投放简介

    目录 引言 实时竞价广告是什么 竞价广告的最优投放策略是什么 分层出价之如何进行人群分层 如何确定最优出价 o C P X oCPX oCPX下的最优出价 结语 引言 自2014年井喷式爆发以来 互金行业经历了从野蛮生长到理性回归的过程 由
  • 2022.10 一文解决Mac M1/M2 从Homebrew到Python的坑

    目录 Homebrew安装 Homebrew优势 正确安装 常见命令 Anaconda安装 官网下载 不推荐 Homebrew下载 推荐 Anaconda Navigator在哪里 Anaconda常见命令 创建环境 激活环境 查看现有环境
  • oracle 标识符无效

    drop table CM CREDIT SORT cascade constraints Table CM CREDIT SORT create table CM CREDIT SORT type VARCHAR2 32
  • mysql 存储文本数据类型_MYSQL中的五种数据类型

    MYSQL中的五种数据类型 字符型 文本型 数值型 逻辑型和日期型 字符型 VARCHAR VS CHAR VARCHAR型和CHAR型数据的这个差别是细微的 但是非常重要 他们都是用来储存字符串长度小于255的字符 假如你向一个长度为四十
  • 带宽的含义解释

    参考博客 https blog csdn net Ideality hunter article details 77923335 depth 1 utm source distribute pc relevant none task ut
  • 在anaconda中安装pillow(Python Image Library,PIL)以供某些图像操作

    pillow库安装的来由 安装anaconda时 会自动安装python 当需要使用PIL时 可能会发生报错 这时要安装对应的库 也可理解为模块 包 这时可以通过安装pillow调用PIL PIL只是存在于python2中 它没有随pyth
  • 测试开发实战项目

    预研背景 目前系统研发多为前后端分离 当后端接口研发完成后 可以不依赖前端界面通过接口测试提前发现问题并解决 同时由于软件迭代周期不断缩短 开发新功能后又担心影响原有功能 可以通过接口自动化进行原有功能快速回归测试 将更多精力专注于迭代功能
  • C#读取Modbus数据

    前面连续写了关于SOCKET编程的东西 似乎有点高大上 为了学习而学习 因此这里我们来整点实际应用的东西 C 如何读取Modbus数据 Modbus很多人可能一点都不知道 也正常 隔行如隔山嘛 Modbus在自动化行业就不一样 属于路人皆知
  • leetcode链表相关的题

    总结一下最近做过的链表相关的题目 后续不定时更新内容 1 反转链表 本题使用指针反转 其他的方法 可以先遍历head 把数据保存到数组中 数组反转 然后定义一个新指针类遍历复制即可 1 gt 2 gt 3 gt 4 gt 5反转输出为 5
  • 读者写者问题的三种打开方式——写者优先

    读者写者问题的三种打开方式 读者优先 今天遇到了操作系统的世 界 名 题 读者写者问题 经过我一两天的不懈努力 我终于没能想出来 再经过一两天的不懈努力 我终于勉勉强强地看懂了别人写的是什么 在这里 我会把我自己写的版本放上来 然后尽可能地
  • 【华为OD机试真题2023B卷 JS】生日礼物

    华为OD2023 B卷 机试题库全覆盖 刷题指南点这里 生日礼物 知识点排列组合 时间限制 1s 空间限制 256MB 限定语言 不限 题目描述 小牛的孩子生日快要到了 他打算给孩子买蛋糕和小礼物 蛋糕和小礼物各买一个 他的预算不超过x元
  • 2023年第六届先进控制,自动化与机器人国际会议(ICACAR 2023)

    2023年第六届先进控制 自动化与机器人国际会议 ICACAR 2023 重要信息 会议网址 www icacar org 会议时间 2023年4月7 9日 召开地点 中国广州 截稿时间 2023年3月10日 录用通知 投稿后2周内 收录检
  • 结构体(声明、初始化、内存对齐、如何传参)

    结构基础知识 聚合数据类型能够同时存储超过一个的单独数据 C提供了两种类型的聚合数据类型 分别是数组和结构体 数组是相同元素的集合 它的每个元素是通过下标引用或指针间接访问的 结构体也是一些值的的集合 这些值称为它 的成员 但一个结构的成员