指针问题,问了N个人还没明白,100分求助

hedongfu 2006-10-28 10:52:44
int a[5]={1,2,3,4,5};
int *ptr=(int *)((&a)+1);

printf("%d,%d",*(a+1),*(ptr-1));
...全文
1576 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
anchor720 2006-10-31
  • 打赏
  • 举报
回复
mark
todototry 2006-10-29
  • 打赏
  • 举报
回复
mark
贵子潘 2006-10-29
  • 打赏
  • 举报
回复
这里的高手解释得很清楚
lz应该满意了
zjbirdman 2006-10-29
  • 打赏
  • 举报
回复
mark
skkcpp 2006-10-29
  • 打赏
  • 举报
回复
我觉得是 2,2
gxh9314 2006-10-29
  • 打赏
  • 举报
回复
ding
ppx3200 2006-10-29
  • 打赏
  • 举报
回复
非常的清楚了。MARK
zhongfusong 2006-10-29
  • 打赏
  • 举报
回复
a的类型可以认为是int[5],所以&a + 1,就增加5个int的地址,就指向a[4]的下一个int 地址
但由于p是int *,所以p-1只减小一个int类型的地址
yutongjun108 2006-10-29
  • 打赏
  • 举报
回复
mark
lsd1025 2006-10-29
  • 打赏
  • 举报
回复
wanfustudio这位已经讲得太清楚了,
这个问题我完全同意他的讲法
kookworm 2006-10-28
  • 打赏
  • 举报
回复
a是一维数组名,所以&a就是以定义的一维数组a做为一个存储单元,由于数组a有5个整形元素,占10个字节,这样&a+1就相当于一次移动10个字节,即移到了数组后的第一个字节。而(int *)又将以数组a为一个单元的指针类型,转化为了以整形为一个单元的指针类型(每移动一次为2个字节),结果使得ptr-1指向了数据的最后一个元素
chinese_zmm 2006-10-28
  • 打赏
  • 举报
回复
int *ptr=(int *)((&a)+1);//&a+1相当于&a是一个2级指针a[0][5],它加一的偏移量是5,而
*(&a)+1的偏移量才是一。
Jokar 2006-10-28
  • 打赏
  • 举报
回复
&a: 行指针 :)
mumutingyu 2006-10-28
  • 打赏
  • 举报
回复
关键时对于指针加法的理解,是移动指针到该类型的下一个上。&a+1时中是对&a进行加1,而&a是数组的指针,所以+1应该是移动到数组最后也就是a[4]的下一个位置上了。
下面int *ptr=(int *)((&a)+1);也就是说ptr是指向a[4]的下一个int型指针。
所以(ptr-1)应该是指向a[4]的int型指针,所以*(ptr-1)=a[4]=5成立
飞哥 2006-10-28
  • 打赏
  • 举报
回复
一道笔试题不理解
silver6 | 25 十一月, 2005 23:36


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

printf("%d,%d",*(a+1),*(ptr-1));
}

int *ptr=(int *)(&a+1); //指向整个数组末尾
int *ptr=(int *)(a+1); //指向a的下一个元素

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

printf("%d,%d",*(a+1),*(ptr-1));
}

cout<<*(a+1)<<endl; output:2 没有什么费话~
cout<<*(ptr-1)<<endl; output :5
因为 int *ptr=(int *)(&a+1);
这里是(&a +1) 而非 a+1

&a的类型是数组,所以加1的话,系统会认为加一个a数组的偏移,即5个int

&a+1就是首地址+1
主要是(int*)做了操作,具体什么操作也不是很了解。等高手回答。
如果
&a0x0012ff6c ""

&a+10x0012ff6d ""
这里
int *ptr=(int *)(&a+1);
ptr的地址和(&a +1)的地址并不相同
等待高手回答(int *)做了什么操作

&a[0] 才是首地址。

&a是指向首地址的指针。

事实证明:
*(a+1)就是a[1],*(ptr-1)就是a[4]
执行结果是2,5
&a+1不是首地址+1,系统会认为加一个a数组的偏移,是偏移了一个数组的大小(本例是5个int)

,&a可以认为是整个数组的地址,因此不能单纯的用首地址+1。

1.int * 是强制转换为int型指针。
2.对于int a[5]={1,2,3,4,5};a就是数组首地址。a+1是首地址+1. a 等价于&a[0].
3. &a不是首地址,可以看作是整个数组的指针。&a+1是 a[5]后面的地址.
&a+1≠a+1

废话少说;接:2,5

int a[5]={1,2,3,4,5};

//
// &a 指向是 a[5]的类型, &a + 1指向下一个a[5]类型,等同于指向第6(索引为5)个int
// int *ptr = (int*)(&a + 1) 强制转换指针为int*
int *ptr=(int *)(&a+1);

printf("%d,%d",*(a+1),*(ptr-1)); //ptr - 1 指向上一个int,即索引号为4的整数

int *ptr=(int *)(&a+1);
则ptr实际是&(a[5]),也就是a+5
原因如下:
&a是数组指针,其类型为 int (*)[5];
而指针加1要根据指针类型加上一定的值,
不同类型的指针+1之后增加的大小不同
a是长度为5的int数组指针,所以要加 5*sizeof(int)
所以ptr实际是a[5]
但是prt与(&a+1)类型是不一样的(这点很重要)
所以prt-1只会减去sizeof(int*)

int *ptr=(int *)(&a);
0040105B lea eax,[ebp-14h] ;a[0]的地址
0040105E mov dword ptr [ebp-18h],eax

int *ptr=(int *)(&a+1);
0040105B lea eax,[ebp] ;这里比上边增加了14h,即20个字节
0040105E mov dword ptr [ebp-18h],eax

&a是数组指针,其类型为 int (*)[5];
同意,谭浩强的c语言编程里讲的很清楚!
mu_yang 2006-10-28
  • 打赏
  • 举报
回复
2,5
飞哥 2006-10-28
  • 打赏
  • 举报
回复
关键是那个强制转化~
left_zxp 2006-10-28
  • 打赏
  • 举报
回复
象int a[i][j]中一样,&a[i][j]是int *[j],即是一个行指针,对它的操作是以j*sizeof (size)为单位的
jixingzhong 2006-10-28
  • 打赏
  • 举报
回复
关键就是 指针类型和它对应的步长!

对指针 +1 -1 是移动指针“元素长度”距离,
一个 int 指针ptr, -1 就是退后一个 int 元素位置;

而一个 指向5元素数组 的指针(楼主若还是不清晰,请看 指向数组的指针部分内容)
移动一个元素就是移动一个 数组长度空间,
或者理解为是一个 2维数组 的行指针也可以 ...
jixingzhong 2006-10-28
  • 打赏
  • 举报
回复
int a[5]={1,2,3,4,5};
int *ptr=(int *)((&a)+1);

printf("%d,%d",*(a+1),*(ptr-1));
================
a+1 的结果是明显的,
得到的是指向第二个元素的指针, 所以结果输出2,
下面说一下第二个式子:

a 是数组,
对数组名字取地址后, 得到是一个指向一个5个元素数组的指针,
然后这里 (&a)+1 表示指针下移一个 “元素”,
注意, 这里的元素是一个5元素数组, 相当于是指向了 a 的第六个元素,
(这里越界溢出了,但是 C 中没有越界保护,只要没有非法操作, 那么程序继续运行)
也就是说, ptr 初始化为指向了 a 的第六个元素!!

然后有一个强制转换 int *,
这里就把一个 指向 5 元素数组的指针, 变成了一个指向 int 的指针,
这个变化导致的结果就是 指针步长变化了,
一个 int 指针, ptr-1 表示退后一个元素位置,
注意, 现在 ptr 的类型是 int 指针, 退后一个 int 元素, 就是指向a第五个元素,
结果就是输出了 5
加载更多回复(2)

69,371

社区成员

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

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