C/C++ 结构体变量初始化的几种方法总结及内存排列(字节对齐)

news2025/1/11 20:41:59

前言

最近看到一些别人的代码,对结构体的初始化使用了不同的语法,就决定对结构体的初始化方法做个探索,这里小小的记录一下。

注意,没有初始化的结构体变量是不会输出的,比如

struct SBase{
   int iNumberOne;
   int iNumberTwo;
   long double ldNumberThree;
   int gNumber[5];
   int *pNumber;
}
SBase sBase; 
cout<<sBase.iNumberOne<<endl;
//这样会报错error C4700

这样会报错,因为编译器无法确定变量的值;

第一种初始化的方法

定义一个结构体,第一种初始化结构体的方法

struct SBase{
   int iNumberOne;
   int iNumberTwo;
   long double ldNumberThree;
   int gNumber[5];
   int *pNumber;
}
SBase sBase = {12}; //结构体会按照顺序编译,因此,第一个变量iNumberOne初始化为1,第二个变量iNumberTwo初始化为1后面所有的变量初始化为0,也包括指针变量pNumber也被赋值为0;
cout<<sBase.iNumberOne<<endl;
cout<<sBase.pNumber<<endl;
for(int i=0;i<10;i++)
{ 
   cout<<sBase.gNumber[i]<<" ";
}

这种方法是定义结构体时没有初始化,在定义结构体对象的时候,才使对象内的数据变量初始化。因此不同的对象初始化数据不同。

当结构体内嵌套结构体时,此方法是如何初始化的呢?

struct A
{
   int iNumber1;
   int iNumber2;
}
struct B
{
   A a;
   int iNumeber3;
}
B b = {2};
cout<<b.a.iNumber1<<endl;

这种的思路是首先对于对象b而言,a被初始化为2,iNumber3默认为0,而A a ={2},再回到a对象中,iNumber1初始化为2,iNumber2没有指定,默认为0;

第二种初始化的方法

struct SBase{
   int iNumberOne;
   int iNumberTwo;
   long double ldNumberThree;
   int gNumber[5];
   int *pNumber;
   SBase()
   {
      iNumberOne = 1;
      iNumberTwo = 2;
      ldNumberThree = 3.0;
      for(int i = 0; i < 5;i++)
      {
         gNumber[i] = 0;
      }
      pNumber = NULL;
   }
}
SBase sBase;
cout<<sBase.iNumberOne<<endl;

这种方法跟类变量初始化一样,采用的是构造函数,这样便可以在定义结构体的时候便已经赋予了初始化值。这样定义结构体对象的时候就可以不赋予初始值了;

第三种初始化的方法

struct SBase{
   int iNumberOne;
   int iNumberTwo;
   long double ldNumberThree;
   int gNumber[5];
   int *pNumber;
}
SBase sBase;
memset(&sBase,0,sizeof(SBase));
cout<<sBase.iNumberOne<<endl;

这样采用memset的方法,可以将多个变量用一行代码置0,缺点是所有变量的数值一样;但是

memset(&sBase,1,sizeof(SBase));
cout<<sBase.iNumberOne<<endl;

这种方法不代表将所有的变量置1,会将所有的变量赋予乱值;

结构体内各元素内存排列

结构体内元素是连续排列的,但是地址需要满足字节对齐。
什么是字节对齐呢?下面给个例子展示一下。

struct SBase{
   int iNumberOne;
   char chNumberTwo;
   double dNumberThree;
   int iNumberFour;
}
SBase sBase = {1};
cout<<"内存排列是:"<< &sBase.iNumberOne<< " "<< (int *)&sBase.chNumberTwo << " "<<&sBase.dNumberThree << " "<<&sBase.iNumberFour<<endl;

最终显示的结果是
内存排列是:001BF5D8 001BF5DC 001BF5E0 001BF5E8
这里内存排列虽然是连续的,但是char字符占1一个字节,为什么内存地址5DC后面是5E0,差了4个字节?,这里就是因为计算机系统里内存的排列顺序是按照字节对齐的原则排布的。
int占4个字节,其地址应该是4的倍数,同理,char地址是1的倍数,double地址是8的倍数,这里char后面若紧跟double类型,double地址就不是8的倍数了,因此在char后面补了3个0,最终内存排布如图所示。
在这里插入图片描述

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

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

相关文章

Redis的分布式锁问题(八)基于Redis的分布式锁

Redis的分布式锁问题&#xff08;八&#xff09;基于Redis的分布式锁 分布式锁 什么是分布式锁&#xff1f; 分布式锁&#xff1a;满足分布式系统或集群模式下多进程可见并且互斥的锁。 当多个进程不在同一个系统中&#xff0c;用分布式锁控制多个进程对资源的访问。 在…

springboot+vue3+ts实现一个点赞功能

前端&#xff1a;vitevue3tselementplusless 后端&#xff1a;springboot2.7.5mybatisplus 后端&#xff1a; 引入pom依赖 <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</…

通俗理解模拟退火算法,小白也看得懂!

模拟退火的实例 齐白石原是木匠&#xff0c;快30岁才正式学画。直到57岁以后画风开始转变&#xff0c;才真正有所成就。 鲁迅原本留日学医&#xff0c;25岁弃医从文&#xff0c;但37岁时才写出第一篇白话文小说《狂人日记》。 项羽在24岁巨鹿之战成名&#xff0c;26岁封王却走…

Advances in Graph Neural Networks笔记2:Fundamental Graph Neural Networks

诸神缄默不语-个人CSDN博文目录 本书网址&#xff1a;https://link.springer.com/book/10.1007/978-3-031-16174-2 本文是本书第二章的学习笔记。 我们学校没买这书&#xff0c;但是谷歌学术给我推文献时给出了一个能免登录直接上的地址&#xff0c;下次就不一定好使了&#…

Web of science,scopus,Google scholar的介绍和区别

Overview 最近为了和实验室同学分享这几个常见的数据库的区别&#xff0c;因此做了一个简单的 从这张图上面可以看到&#xff0c;Web of science (Wos)是在1997年&#xff0c;由Institute for Scientific Information (ISI)合并多种索引建立的&#xff0c;而ISI在1992年加入了…

11.21二叉树oj

目录 一.队列.栈顺序表总结 二.猫狗问题 三.股票价格跨度 四.二叉树的初始化 1.获取树中节点的个数 1.遍历思路 2.子问题思路 2.叶子节点个数 3.获取第K层节点的个数 4.获取二叉树的高度 6.判断一棵树是不是完全二叉树 一.队列.栈顺序表总结 1.顺序表和栈的底层都是…

C++ 单向链表手动实现(课后作业版)

单向链表&#xff0c;并实现增删查改等功能 首先定义节点类&#xff0c;类成员包含当前节点的值和下一个节点的地址 /node definition template <typename T> class Node { public:T value;Node<T>* next;Node() {}Node(const T& value) {this->value va…

ES6 入门教程 19 Generator 函数的语法 19.7 yield星号表达式

ES6 入门教程 ECMAScript 6 入门 作者&#xff1a;阮一峰 本文仅用于学习记录&#xff0c;不存在任何商业用途&#xff0c;如侵删 文章目录ES6 入门教程19 Generator 函数的语法19.7 yield* 表达式19 Generator 函数的语法 19.7 yield* 表达式 如果在 Generator 函数内部&…

windows域控批量创建账号方法

目录 一、收集信息 二、编写脚本 &#xff08;一&#xff09;新建aduser.ps1的powershell脚本 &#xff08;二&#xff09;New-Aduser命令详解 三、生产环境报错 &#xff08;一&#xff09;ConvertTo-SecureString &#xff08;二&#xff09;指定的账号已存在 &#xff…

debian11 安装后必备配置

debian11 安装后必备配置 运行环境&#xff1a;PVE v7.2-11 CT容器 系统版本&#xff1a;Debian-11-standard_11.3-1_amd64.tar.zst 启动信息 Debian GNU/Linux 11 debian tty1debian login: root Password: Linux debian 5.15.64-1-pve #1 SMP PVE 5.15.64-1 (Thu, 13 Oct …

【数据结构】堆的实现堆排序Top-K

文章目录一、堆的概念及结构二、堆实现&#xff08;1&#xff09;创建结构体&#xff08;2&#xff09;具体函数实现及解析1.0 交换函数1.1 堆的打印1.2 堆的初始化1.3 堆的销毁1.4 堆的插入1.5堆的向上调整算法1.6 堆的删除1.7堆的向下调整算法1.8 取堆顶的数据1.9 堆的数据个…

【力扣练习】找一个字符串中不含有重复字符的最长字串的长度

class Solution: def lengthOfLongestSubstring(self, s: str) -> int: # 哈希集合&#xff0c;记录每个字符是否出现过 occ set() n len(s) # 右指针&#xff0c;初始值为 -1&#xff0c;相当于我们在字符串的左边界的左侧&#xff…

【项目实战】Spring Boot项目抵御XSS攻击

本专栏将为大家总结项目实战相关的知识&#xff01; 点击即可关注本专栏&#xff0c;获取更多知识&#xff01; 文章目录前言一、什么是XSS攻击二、如何抵御XSS攻击三、实现抵御XSS攻击结语前言 作为Web网站来说&#xff0c;抵御XSS攻击是必须要做的事情&#xff0c;这是非常常…

C++基础知识

目录 C的基本使用 C数据的输入与输出 C使用命令行 具体案例 C生成随机数 关键字 标识符命名规则 数据类型 整形 实型&#xff08;浮点型&#xff09; 浮点型变量分为2种 表示小数的两种方式 案例演示 字符型 案例演示 字符串类型 两种风格 两种风格字符串之间…

【MyBatis】MyBtis入门程序

1. 目录结构 2. 数据库表的设计 /*Navicat Premium Data TransferSource Server : MysqlSource Server Type : MySQLSource Server Version : 50726Source Host : localhost:3306Source Schema : mybatisTarget Server Type : MySQLTarget Se…

python_循环

一、while循环的基础语法程序中的循环&#xff1a;while 条件&#xff1a;条件满足时&#xff0c;做的事情1条件满足时&#xff0c;做的事情2......即只要条件满足&#xff0c;会无限循环执行代码示例&#xff1a;# 简单示例&#xff1a;向Vivian表白100次i 0 while i < 10…

RabbitMQ系列【13】优先级队列

有道无术&#xff0c;术尚可求&#xff0c;有术无道&#xff0c;止于术。 文章目录前言1. 设置优先级队列2. 消息设置优先级前言 RabbitMQ将消息写入队列中都是按顺序写的&#xff0c;消费时也是按顺序进行消费&#xff0c;队列中的消息是先进先出(FIFO).。 首先测试一下没有优…

多数银行人都会忽略5个影响系统性能的因素总结

性能测试往往在投产上线前开展&#xff0c;无法对整个系统变更进行全面的覆盖测试&#xff0c;因此性能测试需求提出十分关键。 性能测试需求交付过程中&#xff0c;需要对开发团队提出的测试需求进行审查&#xff0c;重点分析交付的测试需求是否充分覆盖了影响系统性能的因素…

【OpenCV-Python】教程:3-7 Canny边缘检测

OpenCV Python Canny 边缘检测 【目标】 Canny 边缘检测的概念cv2.Canny 【原理】 1. 去噪 由于边缘检测非常容易收到图像的噪声影响&#xff0c;第一步使用 5x5 高斯滤波去除图像中的噪声。 2. 寻找图像的亮度梯度 在平滑后&#xff08;去噪后&#xff09;的图像利用 S…

1.5 阻塞与非阻塞I/O

文章目录1、阻塞I/O2、非阻塞I/O3、异步I/O4、同步I/O5、epoll原理函数5.1、int epoll_create(int size)5.2、int epoll_ctl(int epfd,int op,int fd,struct epoll_event* event)5.3、int epoll_wait(int epfd,struct epoll_event* events,int maxevents,int timeout)5.4、内核…