x86系统下,输出的值为多少?

百无成 2017-08-21 01:02:43
#include <stdio.h>

int main()
{
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);
return 0;
}
...全文
444 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
jena_wy 2017-08-22
  • 打赏
  • 举报
回复
int *ptr1 = (int*)(&a+1); 因为对a再取地址加1,所以&a+1相当于&a看成一个整体,对其加1就是加了5对应的地址,即ptr1对应的是a[5]所对应的地址。所以ptr1[-1]是5. int *ptr2 = (int*)((int)a+1);:内存中对应的数据是:00 00 00 02 00 00 00 01 ,a指向01的地址,然后给(int)a+1得到的地址是01前面的00的地址,00 00 00 02 00 00 00 01 ,所以打印的ptr2对应的值是2000000。 http://blog.csdn.net/wyyy2088511/article/details/77337301
赵4老师 2017-08-22
  • 打赏
  • 举报
回复
http://edu.csdn.net/course/detail/2344 C语言指针与汇编内存地址-一.代码要素
棉猴 2017-08-22
  • 打赏
  • 举报
回复
以下是输出

首先,数组a的地址是0x00affcc4,而
int *ptr1 = (int*)(&a + 1);

所以ptr1的内容应该是a的地址加上1个“单位”,这里的“单位”指的是数组a整个的大小
(为什么1个“单位”是数组a整个的大小,请参考http://blog.csdn.net/hou09tian/article/details/75332577
所以ptr1的值是0x00affcc4+4*5(5个int,每个int的4个字节)=0x00affcd8
对于ptr2
int *ptr2 = (int*)((int)a + 1);

此时将a看成是一个普通的int,所以ptr2的值是0x00affcc4+1=0x00affcc5
对于输出
printf("%x ,%x", ptr1[-1], *ptr2);

ptr1[-1]表示向“前”移动1个“单位”,因为ptr1的类型是int的指针;所以这里的1个“单位”值得是1个int的大小,即4个字节
所以,ptr1[-1]实际上指的是0x00affcd8-4=0x00affcd4

相当于输出的数组a的第5个元素。
而对于*ptr2,因为其值是0x00affcc5,可以看下图

所以,输出的是20000000

shiter 2017-08-22
  • 打赏
  • 举报
回复
一个老考题,主要是强转地址可能会有很多问题
百无成 2017-08-21
  • 打赏
  • 举报
回复
引用 4楼自信男孩 的回复:
#include <stdio.h>

int main()
{
    int a[5] ={1,2,3,4,5};
    int *ptr1 = (int*)(&a+1);
    int *ptr2 = (int*)((int)a+1);

    printf("%p \n", a);
    printf("%p , %p, %p\n", ptr1, ptr1-1, ptr2);
    printf("%d\n", ptr1[-1]);
    //printf("%x ,%x", ptr1[-1],*ptr2);
    return 0;
}
注意ptr[-1]能够得到值是5,但是ptr2就不能了,通过打印ptr2指向的内存地址就可以发现,它的地址和a的地址就相差很大。主要是因为(int)a + 1已经改变了a的地址,地址是unsigned int类型,强转int类型就改变了它的值。
嗯。我搞懂了
百无成 2017-08-21
  • 打赏
  • 举报
回复
引用 3楼das白 的回复:
5,2 第一个偏移了一个数组 减一是最后一个数字5 第二个偏移了一个int 即2 感觉就是这样 但是我的编译器输出的是 5,2000000 后面的0是什么鬼
证明你还没到那水平
百无成 2017-08-21
  • 打赏
  • 举报
回复
引用 2楼cain-won 的回复:
x86系统就是32位的。你这代码里错误一大堆,你自己没调试?
是你自己看不懂,没错的。自己去看c语言深度剖析
自信男孩 2017-08-21
  • 打赏
  • 举报
回复
#include <stdio.h>

int main()
{
    int a[5] ={1,2,3,4,5};
    int *ptr1 = (int*)(&a+1);
    int *ptr2 = (int*)((int)a+1);

    printf("%p \n", a);
    printf("%p , %p, %p\n", ptr1, ptr1-1, ptr2);
    printf("%d\n", ptr1[-1]);
    //printf("%x ,%x", ptr1[-1],*ptr2);
    return 0;
}
注意ptr[-1]能够得到值是5,但是ptr2就不能了,通过打印ptr2指向的内存地址就可以发现,它的地址和a的地址就相差很大。主要是因为(int)a + 1已经改变了a的地址,地址是unsigned int类型,强转int类型就改变了它的值。
大米粥哥哥 2017-08-21
  • 打赏
  • 举报
回复
5,2 第一个偏移了一个数组 减一是最后一个数字5 第二个偏移了一个int 即2 感觉就是这样 但是我的编译器输出的是 5,2000000 后面的0是什么鬼
cain-won 2017-08-21
  • 打赏
  • 举报
回复
x86系统就是32位的。你这代码里错误一大堆,你自己没调试?
赵4老师 2017-08-21
  • 打赏
  • 举报
回复
不要迷信书、考题、老师、回帖; 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实!

69,380

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧