i
不是p =(int *)(p + 1);指向数组的下一个元素? (即3?)所以输出应该是2,3。但产量是2,0。为什么呢?
答案 0 :(得分:3)
您正在将char
指针p
增加到下一个char
内存位置 - 这是数字0
的{{1}}填充字节之一,其中,2
需要4个记忆位置(其他3个用零填充)。
简而言之,只需将int
替换为char *p;
并摆脱int *p;
处的所有演员阵容 - 您的程序应该正常工作。
(为了使其保持无用的转换,更改p = (char*)((int*)(p));
p = (int*)(p+1);
,以便增量发生在整数指针上,而不是在char指针上)
在小端存储器模型中,例如在当前PC中使用的,int数字在内存中占用4个字节 - 第一个是最不重要的(因此,对于小于256(2 ^ 8)的数字,它们包含整数。)
你的内存中有这个字节序列:'02 00 00 00 03 00 00 00 04 00 00 00'
当您使用“char *”指针时,编译器知道char数据元素的大小是1个字节。在增加它时,它只会进入相邻字节,即“0”。
在“printf”调用中,您访问“char * p”的内容,这是一个单字节编号 - 0,并且编译器在调用“printf”时填充该值,以便该函数仍然可以看到“0” - 但在其他compielrs和系统中,它可能会打印垃圾或段错误,因为p = (char *) (((int *) p) + 1);
的“%d”参数所预期的3个字节将不存在。
答案 1 :(得分:2)
那是因为p
是数据类型的错误指针。
当您增加p
时,它的值不会增加1 * sizeof(int)
,而是会增加1 * sizeof(char)
。
字节级arr
的内容,假设int
为4个字节且字节序排序为:
2 0 0 0 3 0 0 0 4 0 0 0
首次设置p
时,您有:
2 0 0 0 3 0 0 0 4 0 0 0
^------ p
当您将p
设置为(int*)(p + 1)
时,您将p
仅增加1.此演员阵容对您没有帮助。所以你明白了:
2 0 0 0 3 0 0 0 4 0 0 0
^------ p
因此解引用p
在该内存位置读取1个字节,因此您有0。
如果您希望将p
增加int
的大小,则需要投射p
本身,然后添加到其中:
p = `(int*)(p) + 1`
然后你会得到你期望的结果。
答案 2 :(得分:1)
这就是为什么指针类型应该与它为Pointer Arithmatics
将1
添加到特定数据类型的指针将向指针当前指向的内存地址添加字节数,现在它将指向p +(x字节)地址并取消引用它将为您提供该地址的价值
例如
你声明一个int类型的指针,如
int *p = new int[5];
数组中的每个元素(如果填充数组)将存储在内存中,内存中的空间为4字节(在地址方面,在32位系统的情况下)。
将1
添加到像p = p+1
这样的指针将带您进入数组中的下一个元素,该元素位于它之前的4字节地址处。
对于任何其他类型的指针,情况都是如此,区别在于它将跳转到地址空间中的那么多字节,因为指针本身就是数据类型。
现在你可以说指针只是指向内存所以我们是否声明任何类型的指针都不应该有任何区别。是的,这是真的但不建议任何时候,因为当你使用指针时,指针算术非常肯定在那里使用。为了在内存地址中精确跳转,我们声明了与它们指向的数据相同的数据类型的指针