代写C代码 代做C程序 C辅导 C家教

远程写代码 Debug 讲解答疑 不是中介,本人直接写

微信: ittutor QQ: 14061936 Email: ittutor@qq.com

导航

指针是C语言的核心,可它却迷惑了不少人,看下面的几行程序:
int a[5]={1,2,3,4,5}; 
int *ptr1=(int *)(&a+1); 
int *ptr2=(int *)((int )a+1); 
printf("%x,%x",ptr1[-1],*ptr2);
 
假设以上代码运行在32位小字节序的PC机上,那么它的结果应该是什么呢?
 
不写答案。
 
下面来简单分析一下:
a是一个5个元素int数组,那么sizeof(a)=size(int)*5
对于一个指针 Type* p,如果p+1,那实际地址向高地址偏移sizeof(Type)个字节,这是C语言的基本常识
&a是对a取地址,就是a类型的指针,那么&a+1就会向高地址偏移sizeof(a),也就是指向了数组的末尾
然后将a类型的指针强转成int类型的指针,那么此时进行加减运算的偏移步长就成了sizeof(int)
ptr1[-1]这种写法在C语言里并不奇怪,等同于ptr1-1,向低地址偏移了sizeof(int)个字节,指向了数组的最后一个元素
第一个答案出来了
 
第一个的操作地址增减的步长都是sizeof(int)的整数倍,所以和运行平台无关,肯定是数组的最后一个元素
第二个的答案依赖于程序运行的平台
在小字节序的机器上,一个整形数的内存分布是高字节占高地址,低字节占高地址,这是8086的基本常识
那么a[5]在内存中的分布应该是:
 
低地址---------------------------------------------->高地址
01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 05 00 00 00
a的地址指向01
将a强转成int,那么它的增减步长将变为1
此时a+1这个整型数将执行01的下一个字节00
此时再将这个整型数强转成int*,它的取值单位又变为sizeof(int)
再对这个指针取值,就是:
01 (00 00 00 02) 00 00 00 03 00 00 00 04 00 00 00 05 00 00 00
括号中的4个字节,由于02处于高自己,自然就占了这个整型数的最高位,后面是0
 
这是32位系统的情况,我们把这段程序放在TC环境,即运行平台变成16位,那么它的内存分别如下:
01 00 02 00 03 00 04 00 05 00
取值结果应该是
01 00 (02 00) 03 00 04 00 05 00
在64位系统又是另一个结果,就不赘述了
 
如果这段程序运行在大字节序的机器上呢,很多服务器和嵌入式系统的CPU都是大字节序的,高字节占低地址,低字节占高地址
内存分别是(32位)
00 00 00 01 00 00 00 02 .........
结果自然有是另外一种
 
有些人认为这种题名没有实际意义,当你的程序将要运行在不同的系统下的时候,这种知识将变得极为重要
这个题目我给不少相关专业的学生看过,多数人觉得做不出来无所谓,甚至有些人也就看了一眼就关掉了,但还是有少数几个积极探索寻找答案

 

相关推荐