「java中的结构体对齐」java对齐方式有哪些
今天给各位分享java中的结构体对齐的知识,其中也会对java对齐方式有哪些进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!
本文目录一览:
- 1、结构体内存对齐
- 2、Java中使代码对齐的快捷键是什么
- 3、Java 中的组件如何能够对齐呢?
- 4、刚开始学结构体,什么叫结构体成员对齐?
- 5、结构体成员的字节对齐
- 6、操作系统中的结构体对齐,字节对齐
结构体内存对齐
1、数据成员对齐规则: 结构( struct )(或联合( union )的)数据成员,第一个数据成员放在 offset 为 0 的地方,以后每个数据成员存储的起始位置要从该成员大小或者成员的子成员大小(只要该成员有子成员,比如说数组,结构体等)的整数倍开始(如int为4字节,要从4的整数倍地址开始存储)
2、结构体作为成员: 如果一个结构体有某些结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存储。(struct a 里存有struct b, b里有 char, int ,double等元素,那b 应该从8的整数倍开始存储。)
3、收尾工作:结构体的总大小,也就是sizeof的结果,必须是内部最大成员的整数倍,不足要补齐
( 注 :如自定义类或继承关系 属性的多少变化而变化,如单纯的继承NSObject并且没有任何属性 打印为8 因为 有隐藏 isa 万物皆对象,而对象的本质为 继承 objc_object 的结构体 它就是对象模板)
拓 : 我们知道alloc 流程 最重要的三部曲
cls-instanceSize:计算需要开辟的内存空间大小(这里有一个算法为16字节对齐)
calloc:申请内存,返回地址指针
obj-initInstanceIsa:将 类 与 isa 关联
首先创建 3个结构体 这三个结构体内部参数类型 都一样 只不过 是顺序不一样
根据内存规则 我们画图来分析
分析: ofsize 0 开始 存储 char 类型占 一个 字节的 a ; b 要存储了 首先分析 自己自身多大 我是 double 类型的 我需要占 8 个字节 可是 如果从 a 后面 开始 不满足自身 8 的倍数 的地方 那我只能往下数 看来只能到 8的位置开始 容纳我的身体 【8 - 15 】 ; 该 c 出厂 存储了 我自身占用 4字节 我是 int 类型的 我只能先从16 开始 我的天 真幸运 正好符合我 自身4字节的倍数 我可以 存储了 【16- 19】 d 出场了 我 自身占 2个字节 得需要从20 位开始找 能不能满足 我的倍数的规则要求 20 除 2 可以的 我也可以放下了 【20 - 21】
Mystruct1 结构体 承载了 21+1 个字节 突然 大喇叭喊出规则:结构体的 总大小 ,也就是sizeof的结果, 必须是内部最大成员的整数倍,不足要补齐 :好的 那我里面最大的是 8 字节 那么 我现在 算出来 22 那么 补齐就好了嘛 不要激动 心里默念: 二 八 16, 不满足 ; 三八 24 满足啦 结束了。所以 Mystruct1 占用 24个字节空间
分析: 从 0 的位置开始存 自身是double 类型的占用8个字节的 b【0-7】
a 是 占用一个字节的char类型 ,从 8的位置 满足自身1字节的倍数 所以 存储在8的位置【8】,c来了 首先 我自己是 int类型 我占用 4个字节 我只能从 9的位置开始存 可是 不满足 规则 必须是自己字节数的倍数,那我只能往下数了 9.10.11.12 咦!12是我的位置 那就从12开始【12-15】, d来了 首先想自己是 short类型的占用2个字节 我只能先从 16 的位置看 咦!这么巧 正好符合规则 是我的倍数 存这没毛病
Mystruct2 结构体 承载了 17+1 个字节 ,大喇叭又开始广播了:结构体的 总大小 ,也就是sizeof的结果, 必须是内部最大成员的整数倍,不足要补齐 ,好的村长 我补齐: 结构体最大的是 double占 用8个字节 我算出来18。 2*8 = 16 不满足 3 *8 = 24 村长 我满足了。所以 Mystruct2 占用 24个字节空间
分析:从0 开始 存入一个 char类型的a d 来了 首先分析自己 是short类型 占用2个字节 那我如果从1 开始 那不是我的倍数 不满足规则。所以 往下看 2 好像 是我字节的倍数 ,好的存入 【2-3】 c来了我是 int类型的 占4字节 我只能从4开始存储 好像也满足 是我的自身4字节的倍数 ,好的存入【4-7】,b来了 嗯我是double类型 我自身占用8字节 我只能从 8号位置 开始存储 好像 8也是我的倍数 好的 存入【8-15】
`Mystruct3 结构体 承载了 15+1个字节,行了大喇叭别广播了 我知道了 我内部成员最大 的为8字节 必须是 8字节的整数倍 不足要补齐。
2*8 = 16 我满足了 ,所以 Mystruct3占用 16个字节
我们已经对结构体内存很明晰了 那么来个嵌套的
上面我们分析了 Mystruct3 占用 16 个字节 那么 Mystruct4占用多少呢
分析:
a 是占用一个字节的char类型 放在【0】
b是 占4字节的int类型 找到最近的 自身的占用字节的倍数的位置 为【4-7】
sturct3 是一个占用 16字节 的结构体 我们首先分析它最大的成员占多少内存 这里 为double 类型 占8个字节 所以应该 从8 的倍数开始存放第一个元素 上面的b占了【4-7】故只能从8往后数 正好8的位置 是 sturct3里最大元素的倍数 故第一个元素位置为【8】第二个元素为short类型占2个字节 所以需要从8 往后数正好满足自身的倍数 也就是【10 11】 第三个元素为double类型 占8个字节 所以需要从11 往后数满足8 的倍数 也就是【16 - 23】 因为 sturct3 是个结构体 也满足内存对齐原则 也就是 最大元素的倍数 sturct3占了 16字节 正好满足 对齐原则 a 占1 个 空白占3 b 占4 个 加在一起占 24个
sturct4 内存对齐 为 最大成员的倍数 最大成员 为struct3 里double 8 字节 所以
又是大喇叭所说的 内部成员最大字节 的倍数
所以 sizeof(Mysturct4) 最终 为 24
注意:
Java中使代码对齐的快捷键是什么
Ctrl+Shift+F 格式化当前代码
其他快捷键:
Ctrl+1 快速修复(最经典的快捷键,就不用多说了)
Ctrl+D: 删除当前行
Ctrl+Alt+↓ 复制当前行到下一行(复制增加)
Ctrl+Alt+↑ 复制当前行到上一行(复制增加)
Alt+↓ 当前行和下面一行交互位置(特别实用,可以省去先剪切,再粘贴了)
Alt+↑ 当前行和上面一行交互位置(同上)
Alt+← 前一个编辑的页面
Alt+→ 下一个编辑的页面(当然是针对上面那条来说了)
Alt+Enter 显示当前选择资源(工程,or 文件 or文件)的属性
Shift+Enter 在当前行的下一行插入空行(这时鼠标可以在当前行的任一位置,不一定是最后)
Shift+Ctrl+Enter 在当前行插入空行(原理同上条)
Ctrl+Q 定位到最后编辑的地方
Ctrl+L 定位在某行 (对于程序超过100的人就有福音了)
Ctrl+M 最大化当前的Edit或View (再按则反之)
Ctrl+/ 注释当前行,再按则取消注释
Ctrl+O 快速显示 OutLine
Ctrl+T 快速显示当前类的继承结构
Ctrl+W 关闭当前Editer
Ctrl+K 参照选中的Word快速定位到下一个
Ctrl+E 快速显示当前Editer的下拉列表(如果当前页面没有显示的用黑体表示)
Ctrl+/(小键盘) 折叠当前类中的所有代码
Ctrl+×(小键盘) 展开当前类中的所有代码
Ctrl+Space 代码助手完成一些代码的插入(但一般和输入法有冲突,可以修改输入法的热键,也可以暂用Alt+/来代替)
Ctrl+Shift+E 显示管理当前打开的所有的View的管理器(可以选择关闭,激活等操作)
Ctrl+J 正向增量查找(按下Ctrl+J后,你所输入的每个字母编辑器都提供快速匹配定位到某个单词,如果没有,则在stutes line中显示没有找到了,查一个单词时,特别实用,这个功能Idea两年前就有了)
Ctrl+Shift+J 反向增量查找(和上条相同,只不过是从后往前查)
Ctrl+Shift+F4 关闭所有打开的Editer
Ctrl+Shift+X 把当前选中的文本全部变味小写
Ctrl+Shift+Y 把当前选中的文本全部变为小写
Ctrl+Shift+F 格式化当前代码
Ctrl+Shift+P 定位到对于的匹配符(譬如{}) (从前面定位后面时,光标要在匹配符里面,后面到前面,则反之)
下面的快捷键是重构里面常用的,本人就自己喜欢且常用的整理一下(注:一般重构的快捷键都是Alt+Shift开头的了)
Alt+Shift+R 重命名 (是我自己最爱用的一个了,尤其是变量和类的Rename,比手工方法能节省很多劳动力)
Alt+Shift+M 抽取方法 (这是重构里面最常用的方法之一了,尤其是对一大堆泥团代码有用)
Alt+Shift+C 修改函数结构(比较实用,有N个函数调用了这个方法,修改一次搞定)
Alt+Shift+L 抽取本地变量( 可以直接把一些魔法数字和字符串抽取成一个变量,尤其是多处调用的时候)
Alt+Shift+F 把Class中的local变量变为field变量 (比较实用的功能)
Alt+Shift+I 合并变量(可能这样说有点不妥Inline)
Alt+Shift+V 移动函数和变量(不怎么常用)
Alt+Shift+Z 重构的后悔药(Undo)
编辑
作用域 功能 快捷键
全局 查找并替换 Ctrl+F
文本编辑器 查找上一个 Ctrl+Shift+K
文本编辑器 查找下一个 Ctrl+K
全局 撤销 Ctrl+Z
全局 复制 Ctrl+C
全局 恢复上一个选择 Alt+Shift+↓
全局 剪切 Ctrl+X
全局 快速修正 Ctrl1+1
全局 内容辅助 Alt+/
全局 全部选中 Ctrl+A
全局 删除 Delete
全局 上下文信息 Alt+?
Alt+Shift+?
Ctrl+Shift+Space
Java编辑器 显示工具提示描述 F2
Java编辑器 选择封装元素 Alt+Shift+↑
Java编辑器 选择上一个元素 Alt+Shift+←
Java编辑器 选择下一个元素 Alt+Shift+→
文本编辑器 增量查找 Ctrl+J
文本编辑器 增量逆向查找 Ctrl+Shift+J
全局 粘贴 Ctrl+V
全局 重做 Ctrl+Y
查看
作用域 功能 快捷键
全局 放大 Ctrl+=
全局 缩小 Ctrl+-
窗口
作用域 功能 快捷键
全局 激活编辑器 F12
全局 切换编辑器 Ctrl+Shift+W
全局 上一个编辑器 Ctrl+Shift+F6
全局 上一个视图 Ctrl+Shift+F7
全局 上一个透视图 Ctrl+Shift+F8
全局 下一个编辑器 Ctrl+F6
全局 下一个视图 Ctrl+F7
全局 下一个透视图 Ctrl+F8
文本编辑器 显示标尺上下文菜单 Ctrl+W
全局 显示视图菜单 Ctrl+F10
全局 显示系统菜单 Alt+-
导航
作用域 功能 快捷键
Java编辑器 打开结构 Ctrl+F3
全局 打开类型 Ctrl+Shift+T
全局 打开类型层次结构 F4
全局 打开声明 F3
全局 打开外部javadoc Shift+F2
全局 打开资源 Ctrl+Shift+R
全局 后退历史记录 Alt+←
全局 前进历史记录 Alt+→
全局 上一个 Ctrl+,
全局 下一个 Ctrl+.
Java编辑器 显示大纲 Ctrl+O
全局 在层次结构中打开类型 Ctrl+Shift+H
全局 转至匹配的括号 Ctrl+Shift+P
全局 转至上一个编辑位置 Ctrl+Q
Java编辑器 转至上一个成员 Ctrl+Shift+↑
Java编辑器 转至下一个成员 Ctrl+Shift+↓
文本编辑器 转至行 Ctrl+L
搜索
作用域 功能 快捷键
全局 出现在文件中 Ctrl+Shift+U
全局 打开搜索对话框 Ctrl+H
全局 工作区中的声明 Ctrl+G
全局 工作区中的引用 Ctrl+Shift+G
文本编辑
作用域 功能 快捷键
文本编辑器 改写切换 Insert
文本编辑器 上滚行 Ctrl+↑
文本编辑器 下滚行 Ctrl+↓
文件
作用域 功能 快捷键
全局 保存 Ctrl+X
Ctrl+S
全局 打印 Ctrl+P
全局 关闭 Ctrl+F4
全局 全部保存 Ctrl+Shift+S
全局 全部关闭 Ctrl+Shift+F4
全局 属性 Alt+Enter
全局 新建 Ctrl+N
项目
作用域 功能 快捷键
全局 全部构建 Ctrl+B
源代码
作用域 功能 快捷键
Java编辑器 格式化 Ctrl+Shift+F
Java编辑器 取消注释 Ctrl+\
Java编辑器 注释 Ctrl+/
Java编辑器 添加导入 Ctrl+Shift+M
Java编辑器 组织导入 Ctrl+Shift+O
Java编辑器 使用try/catch块来包围 未设置,太常用了,所以在这里列出,建议自己设置。
也可以使用Ctrl+1自动修正。
运行
作用域 功能 快捷键
全局 单步返回 F7
全局 单步跳过 F6
全局 单步跳入 F5
全局 单步跳入选择 Ctrl+F5
全局 调试上次启动 F11
全局 继续 F8
全局 使用过滤器单步执行 Shift+F5
全局 添加/去除断点 Ctrl+Shift+B
全局 显示 Ctrl+D
全局 运行上次启动 Ctrl+F11
全局 运行至行 Ctrl+R
全局 执行 Ctrl+U
重构
作用域 功能 快捷键
全局 撤销重构 Alt+Shift+Z
全局 抽取方法 Alt+Shift+M
全局 抽取局部变量 Alt+Shift+L
全局 内联 Alt+Shift+I
全局 移动 Alt+Shift+V
全局 重命名 Alt+Shift+R
全局 重做 Alt+Shift+Y
Java 中的组件如何能够对齐呢?
你可以使用JPanel内部面板嘛..
先分别把JLabel与TextField组装放到内部面板里,
再把它们分别放到外部面板哦...
我把程序写给你哦..
JPanel panel1,panel2;
JLabel label1,label2;
JTextField textField1,textField2;
label1=new JLabel("name:");
label2=new JLabel("password:");
textField1=new textField1(10);
textField2=new textField2(10);
panel1=new JPanel();
panel1.setLayout(new FlowLayout());
panel1.add(label1);
panel1.add(textField1);
panel2=new JPanel();
panel1.setLayout(new FlowLayout());
panel2.add(label2);
panel2.add(textField);
Container container=getContentPane();
container.add(panel1,BorderLayout.NORTH);
container.add(panel2,BorderLayout.CENTER);
这样大概就OK了哦...
其实你只要掌握了怎样使用布局管理器来安排主件就OK了哦...
刚开始学结构体,什么叫结构体成员对齐?
举个例子:
struct {
char a; //1byte
int b; //4byte
char c[2] //2byte
double d; //8byte
}Struct_A;
在计算机内存中,结构体变量的存储通常是按字长对齐的,比如8位机里就按字节对齐,那么上述结构体共
占用1+4+2+8=15byte。
在16位机里,变量就按照2字节对齐,比如a这个成员,虽然是个char类型,地址在0x80000000本身只占1字节,但是下一个成员b却不能使用0x80000001这个地址,而必须使用0x80000002,这就是按字长对齐。以上结构体占用的空间也就是2+4+2+8=16字节
同理,在32位机中,如果a在0x80000000的话,b只能放在0x80000004,因为这里的字长是4个字节。以上结构体占用空间4+4+4+8=20字节
也就是说总有一些字节是浪费掉的,这样做的目的很简单,就是因为在大多数计算机体系结构中,对内存操作时按整字存取才能达到最高效率,相当于是以空间换取时间。当然在某些计算机体系结构中,比如ARM,是支持非对齐字传输的,也就是说变量并不一定要按照字长对齐,尽管这样可能会降低效率,但换来的是存储空间上的节约。对于程序员来讲,则需要将结构体声明为紧凑型结构体。声明的关键字依编译器不同而异,你可以去查一下__packed
关键字,可以得到更详细的说明。使用紧凑型结构体,则会强制编译器将结构体成员按1字节对齐,则以上结构体占用空间仍为15字节。不知道回答清楚了没有
结构体成员的字节对齐
这个问题都很有深度啊;
首先我要说的是,字节对齐在不同编译器下语法是不一样的,在GCC中是#pragma push(1) #pragma pack(); 在MS C++中用VC的代码项里可以调整,默认是8字节;
typedef struct
{
char c;
int i;
}test;
字节对齐,是对齐,比如说char 与 int 如果是4字节对齐,那么char也会占用4个字节,总共占8字节,而且结构体对象存储是按照顺序存的,char 肯定在int前面。第二种情况如果1字节对齐,意味着char只占1字节,而结下来int会占用4字节,这个N字节对齐的意思是,每个成员占用空间必须是N字节的倍数,不足N字节的占用N字节。那么以1字节对齐那它占用5个字节。
还有你说的每种数据是低位还是高位在前,这个根处理器有关,Intel处理是小端对齐,比如说一个整数522387969用16进制表示是:0x1f 23 02 01,在Intel处理器中表示是0x01 02 23 1f,所以在内存用0x01 02 03 1f来示522387969,这就是所谓有小端对齐;但在arm处理器中522387969表示是0x1f 23 02 01,这就是所谓的大端对齐,这种方式又叫作网络字节序。
当然前面说的字节序只是对int long short这些内置(built in)数据类型用效,对结构体内如果有int long这类成员也会有所谓的字节序,如前面所说,不管是什么序结构体对象存储是按照顺序存,先定义的成员肯定在后定义的成员前面,但单个成员有字节序,不知这样说,你的明白?
不是,请仔细体会这句话:这个N字节对齐的意思是,每个成员占用空间必须是N字节的倍数,不足N字节的占用N字节。
大于N字节就凑够N字节的倍数,比如按3字节对齐,那么一个4字节的int将占据6字节~
操作系统中的结构体对齐,字节对齐
1.平台原因:不是所有的硬件平台都能访问任意地址上的任何数据;某些硬件平台智能在某些地址处取特定类型的数据,否则抛出硬件异常。
2.性能原因:数据结构(尤其是栈)应该尽可能在自然边界上对齐,原因在于,为了访问未对齐的内存,处理器需要作两次内存访问,而对齐的内存访问仅需要一次访问。
规则:
数据成员对齐规则:结构(struct)的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员的对齐按照#pragma pack指定的数值和这个数据成员自身长度中,比较小的那个进行。
结构(struct)的整体对齐规则:自数据成员完成各自对齐后,结构本身也要对齐,对齐将按照#pragma pack指定的数值和结构最大数据成员长度中,比较小的那个进行
结构体作为成员:如果一个结构里有某些结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存储
假设CPU要读取一个4字节大小的数据到寄存器中(假设内存读取粒度是4)
1.数据从0字节开始(内存对齐)
2.数据从1开始(内存不对齐)
当数据从0字节开始的时候,直接将0-3四个字节完全读取到寄存器,结算完成
当数据从1开始的时候,问题很复杂,首先将前4个字节读到寄存器,再次读取4-7字节的数据进寄存器,接着把0字节,567字节的数据剔除,最后合并1234字节的数据进寄存器,对一个内存未对齐的寄存器进行了这么多额外操作,大大降低了CPU的性能。
这还属于乐观情况(性能原因),还有平台的移植原因,因为只有部分CPU肯干,其他部分CPU遇到未对齐边界就直接罢工了
字节对齐:
1.第一个成员在与结构体变量偏移量(offset)为0的地址处。
2.其他成员变量要对齐到对齐数的整数倍的地址处
(1)对齐数=对齐系数与该成员大小的较小值。
(2)如果有宏定义 #pragma pack(n); 则它中的n 就是对齐系数。
(3)VS中默认的对齐系数为8,linux中的默认为4.
3.结构体总大小为最大对齐数(每个成员变量除了第一个都有对齐数)的整数倍。
4.如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,
结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。
java中的结构体对齐的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于java对齐方式有哪些、java中的结构体对齐的信息别忘了在本站进行查找喔。
发布于:2022-11-28,除非注明,否则均为
原创文章,转载请注明出处。