大小端?堆栈增长方向?数组增长方向?
来源:互联网 发布:淘宝自行车哪家好 编辑:程序博客网 时间:2024/04/29 09:51
这个问题源自某讨论课题,闲话少说,直接上代码:
#include<stdio.h>int main(int argc, char** argv) { int a[] = {('l'<<24) + ('l'<<16) + ('e'<<8) + 'h', 'o'}; printf("%x%x\n", a[0], a[1]); puts((char*)a); return 0;}
输出结果为:
6c6c65686f
hello
这个代码十分简单,就是在测试c标准对一些“神奇”的操作的默认做法以及机器内存存储方式。这里疑点最大的为数组a,为什么会是‘l’‘l’‘e’‘h’‘o’呢?分析一下:
1. 字符在进行数值运算时将会转化为int,这点可以通过sizeof('c'-'a')来验证。(因此这里不会出现这样的warning: left shift count >= width of type [-Wshift-count-overflow])
2. 可以发现a此时在内存中的呈现(这里用assic字符代替对应的数值,也就是'l' = 0x6c、'e' = 0x65)为:
上为高地址
\0 -------
\0 |
\0 | a[1]
‘o’ |
------------------------------
'l' |
'l' | a[0]
'e' |
'h' -------- <-a
3. 基于2以及第二行输出,可以得出结论:数组增长方向为从低向高地址增长, puts、scanf 等输出函数在输出字符串时输出按照从低地址到高地址的顺序
4. 由已知结论可知,栈的增长方向为从高地址向低地址增长,而堆的增长方向为从低地址向高地址增长
5. 由3、4得出结论,数组的增长方向与栈(堆)增长方向没有必然联系
6. 再看3中的a[1], 可知int a = 0x6c6c6568在写入内存中方向从左到右(从高有效位到低有效位)为从低地址向高地址(小端,即little endian表示法)
经过以上分析,现在再来看
int a[] = {('l'<<24) + ('l'<<16) + ('e'<<8) + 'h', 'o'};
和
int s[] = {'h', 'e', 'l', 'l', 'o'};
产生“违和感”感的原因是什么呢?如果把数组看作许多单元的集合,那么数组的增长方向对象为数组单元之间,大小端表示法为单元本身,至于栈(和堆)的方向,与他们俩没有半毛钱关系。在小端表示法的机器上,数组的增长方向和单元内部的方向正好相反!当前四个字节作为一个整体int时按照小端法需要将顺序倒转过来,这是正产生“违和感”的原因。
于是现在可以写出大端法的int数组表示了:
int b[] = {('h'<<24) + ('e'<<16) + ('l'<<8) + 'l', 'o'<<24};
表现在内存中为:
上为高地址
\0 ----------
\0 |
\0 | a[1]
'o' |
------------------------------
'l' |
'l' | a[0]
'e' |
'h' -----------
与小端法内存表现一致。所谓大小端,都是以byte为单位,是针对一个单元内部的byte排列方式。
现在再来看移位操作,左移操作方向为向高有效位方向,对应小端,就是向低地址方向移动,而对应大端,则是向高地址方向移动,恰好相反。
这里有几个方向,一个是堆栈方向,一个是数组方向,一个是有效位高低方向,一个是地址高低方向。
至于结构体、类等,方向表现为与数组方向一致。
- 大小端?堆栈增长方向?数组增长方向?
- 判断堆栈增长方向
- 堆栈的增长方向
- STM32 大小端模式 与 堆栈及其增长方向分析
- STM32 大小端模式 与 堆栈及其增长方向分析
- STM32 大小端模式 与 堆栈及其增长方向分析
- STM32 大小端序 与 堆栈及其增长方向分析
- STM32 大小端模式 与 堆栈及其增长方向分析
- STM32 大小端模式 与 堆栈及其增长方向分析
- STM32 大小端模式 与 堆栈及其增长方向分析
- 确定堆栈的增长方向
- arm堆栈的增长方向
- STM32 大小端模式 与 堆栈及其增长方向分析(转自原子哥)
- 堆栈的区别 及 增长方向
- 堆栈的区别及增长方向
- 获得堆栈增长方向的一种方法
- 获得堆栈增长方向的一种方法
- 堆栈的区别及增长方向
- LinkedList类
- ORA-01733: 此处不允许虚拟列
- ZendStudio11.0.2破解教程
- 行高与字号
- 关于Android gridview setOnItemClickListener 监听 无效
- 大小端?堆栈增长方向?数组增长方向?
- codeblocks平台配置GDAL教程(史上首发)
- Android 6 SdCard Path
- Spring@Autowired注解与自动装配
- Head First设计模式学习笔记-------(14)复合模式
- Angularjs bootstrap jquery jquery easyUI extjs 详解
- C语言case关键字后面的值有什么要求?
- ConcurrentHashMap源码解析(JDK 1.8)
- Linux串口编程详解