| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 872 人关注过本帖
标题:帮忙分析一下这个程序的运行结果,为什么呢?
只看楼主 加入收藏
xichong
Rank: 7Rank: 7Rank: 7
来 自:四川南充
等 级:黑侠
威 望:2
帖 子:146
专家分:582
注 册:2009-6-10
结帖率:100%
收藏
已结贴  问题点数:50 回复次数:10 
帮忙分析一下这个程序的运行结果,为什么呢?
程序代码:
#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\n",ptr1[-1],*ptr2);
    return 0;
}
图片附件: 游客没有浏览图片的权限,请 登录注册
搜索更多相关主题的帖子: 结果 运行 
2010-08-22 18:50
清风拂晓
Rank: 8Rank: 8
来 自:火星
等 级:蝙蝠侠
威 望:1
帖 子:356
专家分:889
注 册:2010-8-13
收藏
得分:0 
ptr1[-1]里面可以是负数?这样是不是随便指向一个数了?后面输出的那个2000000好象是一个地址吧?int *ptr2=(int*)((int)a+1);是不是这里有问题?


清风拂暮(木)
2010-08-22 19:40
yesyesgirl
Rank: 1
等 级:新手上路
帖 子:43
专家分:9
注 册:2010-7-20
收藏
得分:0 
新手路过!!
2010-08-22 20:12
vandychan
Rank: 15Rank: 15Rank: 15Rank: 15Rank: 15
等 级:贵宾
威 望:18
帖 子:2296
专家分:6418
注 册:2010-8-20
收藏
得分:5 
&a+1相当于a[1] 所以*ptr1指向2  ptr1[-1]意思是*ptr1这个指针的地址的上一个地址
ptr1-1就是a[0]也就是1
(int)a+1是a[0]的地址强制为int类型  也就是地址的值+1

到底是“出来混迟早要还”还是“杀人放火金腰带”?
2010-08-22 20:35
BlueGuy
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:29
帖 子:4476
专家分:4055
注 册:2009-4-18
收藏
得分:0 
这题目是楼主自己编造的吧? 这么怪异,新手路过

我就是真命天子,顺我者生,逆我者死!
2010-08-22 20:44
御坂美琴
Rank: 11Rank: 11Rank: 11Rank: 11
来 自:魔術の禁書目錄
等 级:小飞侠
威 望:9
帖 子:952
专家分:2929
注 册:2010-8-18
收藏
得分:0 
以下是引用BlueGuy在2010-8-22 20:44:37的发言:

这题目是楼主自己编造的吧? 这么怪异,新手路过
肯定不是,别的地方也出现过的,御坂说道

永远为正义而奋斗,锄强扶弱的Level 5 超能力者
とある魔術の禁書目錄インデックス__御み坂さか美み琴こと
http://bbs.bccn.net/space.php?action=threads&uid=483997
2010-08-22 20:49
waterstar
Rank: 11Rank: 11Rank: 11Rank: 11
等 级:小飞侠
威 望:5
帖 子:984
专家分:2810
注 册:2010-2-12
收藏
得分:25 
首先,a是具有5个整型变量的数组,&a就是取数组的首地址,其结果和a是相同的。
&a+1是指针的加法运算,其本质是使指针指向下一个数据。而a是一个数组的首地址,
从而使&a+1指向了下一个具有5个整型变量的数组,于是,就把数组中元素5的下一个地址赋值给
了ptr1。比如说,在我的机子上,a的地址是0x0012ff6c,五个整型变量使得a【4】的地址是0x0012ff7c.
于是,下一个地址就是0x0012ff80,这就是赋值给ptr1的值,ptr1[-1]是让ptr1指向前一个整型变量的地址,
也就是a[4]的地址0x0012ff7c,从而,打印出的就是a[4]的值5。

int *ptr2=(int*)((int)a+1);
这一行的意思是吧指针变量强制转换为整型数据,+1之后,再转回int型指针,其本质是指向了a地址的下一个
字节的地址,即0x0012ff6d,要打印*ptr2就要从0x0012ff6d开始取四个字节的值,组成一个整数输出。读出时,
牵扯到大端还是小端序的问题:
1、所谓大端(big-endian)序,就是读取或者存放数据时,最低 位 对应 高地址 。
2、所谓小端(big-endian)序,就是读取或者存放数据时,最低 位 对应 低地址 。
从你的结果看来,你的平台是小端序的,数据存储方式如下:
01 00 00 00 02 00 00 00 03 00 00 00 04……
(低地址)---------------------------------(高地址)
当你读取数字的时候,就是读取的我上面的用红色字体显示的数字,按照小端序的读法,读出的值变成正常顺序之后就是
02 00 00 00即2000000
解释完毕,如有疑问,我很可以再讨论

冰冻三尺,非一日之寒;士别三日,不足刮目相看!
2010-08-22 20:51
erikyo
Rank: 9Rank: 9Rank: 9
等 级:蜘蛛侠
威 望:2
帖 子:270
专家分:1154
注 册:2010-6-10
收藏
得分:20 
以下是引用xichong在2010-8-22 18:50:58的发言:

#include  
int main()
{
    int a[5]={1,2,3,4,5};
    int *ptr1=(int*)(&a+1);
    int *ptr2=(int*)((int)a+1);
    printf("%x,%x\n",ptr1[-1],*ptr2);
    return 0;
}
这个问题是《c语言深度剖析》里的一个例子。要理解这个问题首先得分清楚&a和a的区别。
&a代表的是数组的首地址,a代表的是数组首元素的首地址,他们的值一样,但是意义不同。
&a+1代表的就是数组的地址加1,而指针在作加1操作的时候,是无视数据类型,
他实现的是把地址一致下一个同类型的数据处,&a是一个数组,于是指针移至下一个数组的首地址处。
也就是题中的ptr1,他只想下一个数组的首地址,于是ptr[-1]其实就是a[4]=5的值
ptr2中(int)a表示把指针a强制转换成int类型的数据,然后加上1,再把这个值强制转换成int类型的指针赋值给ptr2
也就是说ptr2的值就是这个经过加1操作,强制转换之后的值,*ptr2就是取这个值(内存地址)里的数据。
2010-08-22 22:22
HFXH
Rank: 1
等 级:新手上路
帖 子:2
专家分:1
注 册:2010-8-23
收藏
得分:0 
看了
2010-08-23 13:39
燕强
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:78
专家分:188
注 册:2010-8-11
收藏
得分:0 
学学。。。
2010-08-23 16:59
快速回复:帮忙分析一下这个程序的运行结果,为什么呢?
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.023261 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved