int *ptr1 = (int *)(&a+1);
int *ptr2 = (int *)((int)a+1);
cout << ptr1[-1] << '\t' << *ptr2;
被问倒了,第一个结果是5还能理解,第二个是一个很大的数,为什么啊?谁知道吗
27 个解决方案
#1
指向未知内存的数?
#2
int强制类型转换改变了a的值..
#3
把地址转换成整形+1 栈地址都很大的。。。
#4
不记得是在那本书上看过这个了 !
嘿嘿 !
a ptr2
01 [color=#FF0000]00 00 00, 02 [/color]00 00 00,
所以 *ptr2 = 0x 02 00 00 00;
#5
菜鸟表示关注中
#6
抱歉不清晰 !
建议你去测试下 a, 和 ptr2 ; 看看他们的地址的关系!
a ptr2
01 00 00 00 , 02 00 00 00,
所以 *ptr2 = 0x 02 00 00 00 ;
#7
int a[5] = {1,2,3,4,5};
int *ptr1 = (int *)(&a+1); //表示下一个数组,也可以说是a[5]
int *ptr2 = (int *)((int)a+1);//int(a)+1 先将a所在的地址转换成10进制,然后加1,也就是说ptr2指向的是 a的十进制地址+1处,注意,如果是(int)a+4的话,恰好是a[1],所以加1这块你理解下,所以这个值是无效值
cout << ptr1[-1] << '\t' << *ptr2;
输出值为5 和 一个任意值
int *ptr1 = (int *)(&a+1); //表示下一个数组,也可以说是a[5]
int *ptr2 = (int *)((int)a+1);//int(a)+1 先将a所在的地址转换成10进制,然后加1,也就是说ptr2指向的是 a的十进制地址+1处,注意,如果是(int)a+4的话,恰好是a[1],所以加1这块你理解下,所以这个值是无效值
cout << ptr1[-1] << '\t' << *ptr2;
输出值为5 和 一个任意值
#8
int *ptr2 = (int *)((int)a+1);
指向的是*a往后移动一个字节的位置,这是没有意义的操作,所以强制转化为int类型后变成了一个很大的数,如果写成int *ptr2 = (int *)((int)(a+1));就是指的数组第二个元素
指向的是*a往后移动一个字节的位置,这是没有意义的操作,所以强制转化为int类型后变成了一个很大的数,如果写成int *ptr2 = (int *)((int)(a+1));就是指的数组第二个元素
#9
你的无效值,让我很不安!
#10
小端模式下 是0x2000000
大端模式下 是0x100
怎么会是个无效值呢 ?
#11
01 00 00 00 , 02 00 00 00, 小端模式! 0x00 02 00 00
00 00 00 01 , 00 00 00 02, 大端模式! 0x00 00 01 00
*ptr2 的值应该为元素a[0]的第二个字节开始的连续4 个byte 的内容。
#12
呵呵,误解了楼主,这个解释正确...
#13
第一个ptr1 = (int *)(&a + 1); //加1 加的是整个数组的长度也就是 + sizeof(a)*1, 大家可以理解,也可以说表示a[5]。。。
而ptr2 = (int *)((int)a + 1);//这里的加1 加的是数值 1(也就是1个字节),因为把他强制转换为整型。问题就是加整型1怎么理解。a[0]有4个字节,加了一个字节后就是后3个字节和a[1]的前一个字节组成了四个字节。输出*ptr2所以结果如何就看你的机器是大端模式还是小端模式了。
内存如下布局
01 00 00 00 02 00 00 00
a[0] a[1]
小端的话a[0]后3个和a[1]的前一个字节就组成了,0X02000000
大端...................................,0x00000100
#14
学习。。。。
#15
ptr2所指的是a[0]的第二个字节开始连续4个字节
01 00 00 00,02 00 00 00,小端模式!ptr2 所指的4个字节: 00 00 00 02,*ptr2的值为0x02000000
00 00 00 01,00 00 00 02,大端模式!ptr2 所指的4个字节:00 00 01 00,*ptr2的值为0x00000100
01 00 00 00,02 00 00 00,小端模式!ptr2 所指的4个字节: 00 00 00 02,*ptr2的值为0x02000000
00 00 00 01,00 00 00 02,大端模式!ptr2 所指的4个字节:00 00 01 00,*ptr2的值为0x00000100
#16
(int *)((int)a+1);
转换成int型,加1以后再转换成int*
#17
这个是正解 所以你在windows 用 vc 结果是 0x2000000
#18
同意11楼,答案。
#19
正解,楼主结贴吧。
#20
VC调试(TC或BC用TD调试)时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。
(Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
不要迷信书、考题、老师、回帖;
要迷信CPU、编译器、调试器、运行结果。
不要写连自己也预测不了结果的代码!
(Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
不要迷信书、考题、老师、回帖;
要迷信CPU、编译器、调试器、运行结果。
不要写连自己也预测不了结果的代码!
#21
//代码最清楚了,您请看
#include <iostream>
using namespace std;
int main(int argc, char **argv)
{
char *p;
int x=0x12345678;
p=(char*)&x; //低地址单元
if (*p==0x12)
{
cout<<"大端"<<endl;
}
else if (*p==0x78)
{
cout<<"小端"<<endl;
}
//一般你电脑是8086的pc,小端模式
int a[5] = {1,2,3,4,5};
int *ptr1 = (int *)(&a+1);//这个a+1,加的1是数组类型,就是加5个字节
int *ptr2 = (int *)((int)a+1);//ox 00 00 00 02
cout << ptr1[-1] << '\t' << *ptr2;
cout<<endl<<"推测:"<<(int)0x02000000<<endl;//把上面的地址,依据小段方案,就是02 00 00 00
return 0;
}
#22
经常看到这样的回复 TT
#23
学习了
#24
学习~~~
#25
搞不明白。
#26
mark
#27
+1为什么是加了一个数组的长度?
#1
指向未知内存的数?
#2
int强制类型转换改变了a的值..
#3
把地址转换成整形+1 栈地址都很大的。。。
#4
不记得是在那本书上看过这个了 !
嘿嘿 !
a ptr2
01 [color=#FF0000]00 00 00, 02 [/color]00 00 00,
所以 *ptr2 = 0x 02 00 00 00;
#5
菜鸟表示关注中
#6
抱歉不清晰 !
建议你去测试下 a, 和 ptr2 ; 看看他们的地址的关系!
a ptr2
01 00 00 00 , 02 00 00 00,
所以 *ptr2 = 0x 02 00 00 00 ;
#7
int a[5] = {1,2,3,4,5};
int *ptr1 = (int *)(&a+1); //表示下一个数组,也可以说是a[5]
int *ptr2 = (int *)((int)a+1);//int(a)+1 先将a所在的地址转换成10进制,然后加1,也就是说ptr2指向的是 a的十进制地址+1处,注意,如果是(int)a+4的话,恰好是a[1],所以加1这块你理解下,所以这个值是无效值
cout << ptr1[-1] << '\t' << *ptr2;
输出值为5 和 一个任意值
int *ptr1 = (int *)(&a+1); //表示下一个数组,也可以说是a[5]
int *ptr2 = (int *)((int)a+1);//int(a)+1 先将a所在的地址转换成10进制,然后加1,也就是说ptr2指向的是 a的十进制地址+1处,注意,如果是(int)a+4的话,恰好是a[1],所以加1这块你理解下,所以这个值是无效值
cout << ptr1[-1] << '\t' << *ptr2;
输出值为5 和 一个任意值
#8
int *ptr2 = (int *)((int)a+1);
指向的是*a往后移动一个字节的位置,这是没有意义的操作,所以强制转化为int类型后变成了一个很大的数,如果写成int *ptr2 = (int *)((int)(a+1));就是指的数组第二个元素
指向的是*a往后移动一个字节的位置,这是没有意义的操作,所以强制转化为int类型后变成了一个很大的数,如果写成int *ptr2 = (int *)((int)(a+1));就是指的数组第二个元素
#9
你的无效值,让我很不安!
#10
小端模式下 是0x2000000
大端模式下 是0x100
怎么会是个无效值呢 ?
#11
01 00 00 00 , 02 00 00 00, 小端模式! 0x00 02 00 00
00 00 00 01 , 00 00 00 02, 大端模式! 0x00 00 01 00
*ptr2 的值应该为元素a[0]的第二个字节开始的连续4 个byte 的内容。
#12
呵呵,误解了楼主,这个解释正确...
#13
第一个ptr1 = (int *)(&a + 1); //加1 加的是整个数组的长度也就是 + sizeof(a)*1, 大家可以理解,也可以说表示a[5]。。。
而ptr2 = (int *)((int)a + 1);//这里的加1 加的是数值 1(也就是1个字节),因为把他强制转换为整型。问题就是加整型1怎么理解。a[0]有4个字节,加了一个字节后就是后3个字节和a[1]的前一个字节组成了四个字节。输出*ptr2所以结果如何就看你的机器是大端模式还是小端模式了。
内存如下布局
01 00 00 00 02 00 00 00
a[0] a[1]
小端的话a[0]后3个和a[1]的前一个字节就组成了,0X02000000
大端...................................,0x00000100
#14
学习。。。。
#15
ptr2所指的是a[0]的第二个字节开始连续4个字节
01 00 00 00,02 00 00 00,小端模式!ptr2 所指的4个字节: 00 00 00 02,*ptr2的值为0x02000000
00 00 00 01,00 00 00 02,大端模式!ptr2 所指的4个字节:00 00 01 00,*ptr2的值为0x00000100
01 00 00 00,02 00 00 00,小端模式!ptr2 所指的4个字节: 00 00 00 02,*ptr2的值为0x02000000
00 00 00 01,00 00 00 02,大端模式!ptr2 所指的4个字节:00 00 01 00,*ptr2的值为0x00000100
#16
(int *)((int)a+1);
转换成int型,加1以后再转换成int*
#17
这个是正解 所以你在windows 用 vc 结果是 0x2000000
#18
同意11楼,答案。
#19
正解,楼主结贴吧。
#20
VC调试(TC或BC用TD调试)时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。
(Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
不要迷信书、考题、老师、回帖;
要迷信CPU、编译器、调试器、运行结果。
不要写连自己也预测不了结果的代码!
(Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
不要迷信书、考题、老师、回帖;
要迷信CPU、编译器、调试器、运行结果。
不要写连自己也预测不了结果的代码!
#21
//代码最清楚了,您请看
#include <iostream>
using namespace std;
int main(int argc, char **argv)
{
char *p;
int x=0x12345678;
p=(char*)&x; //低地址单元
if (*p==0x12)
{
cout<<"大端"<<endl;
}
else if (*p==0x78)
{
cout<<"小端"<<endl;
}
//一般你电脑是8086的pc,小端模式
int a[5] = {1,2,3,4,5};
int *ptr1 = (int *)(&a+1);//这个a+1,加的1是数组类型,就是加5个字节
int *ptr2 = (int *)((int)a+1);//ox 00 00 00 02
cout << ptr1[-1] << '\t' << *ptr2;
cout<<endl<<"推测:"<<(int)0x02000000<<endl;//把上面的地址,依据小段方案,就是02 00 00 00
return 0;
}
#22
经常看到这样的回复 TT
#23
学习了
#24
学习~~~
#25
搞不明白。
#26
mark
#27
+1为什么是加了一个数组的长度?