问题:指定的类型变量地址 随意赋值给 其他类型指针是否可行?
前期知识介绍,如下:
程序运行时的数据存储地点是RAM区域,RAM即为动态存储空间,特点是断电时数据清空,物理位置处在CPU当中。
RAM内存地址的范围解释:
若为32位(一字节8位,32位是4字节)cpu,内存地址大小范围在{ 0~[ 2^(32)-1 ] }=={ 0~4294967295 }之间,转化为16进制就是{ 00000000~ffffffff }之间。这时改CPU的RAM中最大地址范围。
64位CPU地址空间计算如上,10进制是[ 0~18446744073709551999 ],16进制为[ 0000000000000000 ~ ffffffffffffffff ]。
以下内容都按照 sizeof(int)=4说明!
问题解答:
当程序中使用 int * 指针时,其指向的地址取值范围被局限于[ 00000000~ffffffff ],也就是十进制的[0~4294967295]之间。
int *可容纳的范围非常宽,
但定义变量时用:
int a = 5;
正确操作是:
int * p = &a;
然而错误的将代码编写为:
int a = 5;
char* p = &a;
这时使用编译器进行编译的时候,如VC++6.0会报错。
其实并不是无法运行,而是VC++6.0的编译器为了减少不必要的BUG而进行的优化。
那么带着问题,让我们来分析这其中的原因,当进行
int a = 5;
有可能系统会给变量a安排的内存地址是 CPU中的RAM中的最大编号:fffffffffffffffff(以64位操作系统来说);
fffffffffffffffff 正确的赋值给 int * p 是没有问题的,但是如果将其赋值给来了
char * p ;
这时就会出现 p 的存储范围过小,无法完全存储下 ffffffffffffffff 这个地址编号,实际 char * p 的存储会对改地址进行截断处理,有原本的 ffffffffffffffff 变为 ffffffff,如果后续存在调用 char * p 中的 p 时,p 并不是指向所期望的值 a = 5 ,而是指向一个地址为 ffffffffff 的内存单元,这事一个未知的数据。
以上是举了一个 { (int 值)->char *}例子进行说明,这是一个“大地址”--到-->”小内存“时出现的问题。
那么,“小地址”--到-->“大内存”时,以上的数据丢失的问题则不会出现。
同样的也可以对float与double进行分析。注意到由于浮点的存储方式不同于整形变量,所以当对 (int 值)->( float * )分析时应考虑到这一点。
得出结论:
在将变量的存储地址赋值给指针时,为了不出现数据意外,需要求报的原则是:类型对应!