内存和指针.docx
《内存和指针.docx》由会员分享,可在线阅读,更多相关《内存和指针.docx(10页珍藏版)》请在冰豆网上搜索。
内存和指针
内存和指针
1范例截取部分内存
浮点数0.054float=0x3D5D2F1B在内存中,按如下存储(后面将知道这不完全正确)
下面程序将获得低2字节:
(short*)类型的指针内存布局(后面会详细分析)为两个单元
2范例内存的危险操作
下面程序使用了未定义的内存
short型内存只能存放16位数,而int型为32位数。
这样的结果是内存溢出而s存放了600000的最低两个字节
C语言运行结果
ST语言运行结果
程序非常危险地在s前面写入了两个字节,这两个字节有可能引起程序崩溃
3大端小端
下面的数据0x41424344在内存中有两种保存的方式:
小端是:
低字节先保存(低字节0x44先存);大端是:
高字节先保存(高字节0x41先存)。
无论是大端还是小端,C语言的指针总指向低地址[0]。
大端在网络上看起来非常舒服(高字节先发,排列起来从左到右对应着由高到低),小端看起来很别扭。
但是在内存中刚好相反,低字节存在低地址。
Modbus是大端(网络上舒服)
CANopen是小端(网络上别扭)
KeilC51是大端(内存中别扭)
变量i在内存中的排布
指针总指向对象的b0位置
下面例子同样也得到与之前一样的结果
c不是我们期待的0x22而是0x11(由于大端系统高字节先)
在大小端不同的系统中,同样的指针运算将得到不同的结果
对于大端的情况,范例1的结果完全不一样
大端情况下总是从高部分进行字节迁移
如何测试CPU是大端还是小端?
先分析一下大端和小段的区别
可以通过读取指针低字节来判断。
*备注:
Keil的浮点数也遵循IEEE754
4数组的公理
将浮点数复制到数组(小端,VS和CodeSys)
下面是小端结构的内存情况
复制到数组(大端,Keil)
下面是大端结构的内存情况
初始化数组(小端VS和CodeSys)
对一个数组ints[4]进行如下初始化
内存分析
代码
初始化数组(大端Keil)
对一个数组ints[4]进行如下初始化
内存分析
由于是大端模式,因此要将高字节01放入b0
代码
上面的代码对内存进行了疯狂地操作,不过还是达到了目的
5内存布局
每个指针眼里内存都是不一样的(内存布局),这在指针定义的时候就被确定下来。
下图是几个例子:
由于不同指针眼里内粗不同,所以指针之间是不可以自由复制:
有一种没有布局的指针void*,可以容纳任何指针
利用void*的无布局,完成通用的swap模版函数。
该函数最大的好处是调用时不用强制类型转换
6不如叫地址变量
下面例子为了截断一个字符串:
一般把保存地址的变量叫指针,数组名字代表了数组的地址。
这种说法显然概念不清晰,应该把int*看成地址而地址根地址有关的符号是变量和常量:
要记住的是一个符号只有两种含义(常量或变量):
至于一个符号是不是指针,其实那不是它的本质。
只是符号的内容比较特殊罢了。
由于常数不能在等号左,可以利用这一点测试一个符号是否为常数:
地址常量可以利用索引器寻找单元:
地址变量也可以利用索引器寻找单元: