从int *转换后,我的char指针指向无效值

时间:2013-07-02 11:07:15

标签: c arrays pointers

我正在学习C编程语言,我刚开始学习带指针的数组。我在这个问题上遇到了问题,我希望该输出必须 5 ,但 2 ,有人可以解释原因吗?

int main(){
   int arr[] = {1, 2, 3, 4, 5};
   char *ptr = (char *) arr;
   printf("%d", *(ptr+4));
   return 0;
}

7 个答案:

答案 0 :(得分:80)

假设一个小端字节结构,其中int是32位(4字节),int arr[]的单个字节看起来像这样(较低地址的最低有效字节。所有十六进制值):

|01 00 00 00|02 00 00 00|03 00 00 00|04 00 00 00|05 00 00 00
char *ptr = (char *) arr;

现在,ptr指向第一个字节 - 因为你已经转换为char*,它被视为char数组:

|1|0|0|0|2|0|0|0|3|0|0|0|4|0|0|0|5|0|0|0
 ^
 +-- ptr

然后,*(ptr+4)访问char数组的第五个元素并返回相应的char值:

|1|0|0|0|2|0|0|0|3|0|0|0|4|0|0|0|5|0|0|0
         ^
         +-- *(ptr + 4) = 2

因此,printf()打印2

Big Endian系统上,每个int内的字节顺序相反,导致

|0|0|0|1|0|0|0|2|0|0|0|3|0|0|0|4|0|0|0|5
         ^
         +-- *(ptr + 4) = 0

答案 1 :(得分:13)

这是因为char的大小为1,int的大小为4。这意味着将4添加到ptr会使结果指向int数组中的第二个条目。

如果你在一个大的endian系统上编译了这个,你就会打印33554432。

答案 2 :(得分:3)

int main(){
 int arr[] = {1,2,3,4,5};
 char *ptr = (char *) arr;
 printf("%d",*(ptr+4));
 return 0;
}

arr的每个案例都有sizeof(int)大小(在您的实施中可能为4)。

由于ptr是指向char的指针,pointer arithmetic使ptr + 4指向&arr[0]之后的4个字节,可能是&arr[1]。< / p>

在记忆中,它看起来像是:

Address | 0 1 2 3 | 4 5 6 7 | ...
Value   |  arr[0] |  arr[1] | ...

答案 3 :(得分:2)

在32位平台上,int的大小是char的四倍。当您向ptr添加4时,将ptr指向的大小的4倍添加到ptr(它本身就是一个内存位置)。这恰好是int数组中第二个元素的地址。

在64位平台上,int 八倍大小char;你的输出会有很大不同。

简而言之,你的代码不可移植,(也见Joachim Pileborg的答案重新结束)但有趣的是取消。

答案 4 :(得分:2)

在制作代码中绝对不建议你做什么,但对于理解学习过程中的指针,演员表等非常有用,所以为此你的例子很棒。那么,为什么你得到2.这是因为你的数组是一个int数组,这取决于你的体系结构有不同的大小(在你的情况下,sizeof(int)是4)。您将ptr定义为char指针,char的大小为1个字节。指针算术(这是你在编写ptr+4时所做的)与指针引用的对象的大小一起工作,在你的情况下使用字符。因此ptr+4距离数组的开头4个字节,因此位于int数组的第2个位置。这就对了。试试ptr+5,你应该得到0。

答案 5 :(得分:1)

因为你将int *转换为char *,ptr [0] = 1,ptr [4] = 2,ptr [8] = 3,ptr [12] = 4,ptr [16] = 5以及所有其他等于0. ptr + 4点到ptr数组中的第4个元素。所以结果是2。

答案 6 :(得分:1)

int main(){
 int arr[] = {1,2,3,4,5};
 char *ptr = (char *) arr;
 printf("%d",*(ptr+4));
 return 0;
}

想象一下arr存储在地址100(完全愚蠢的地址)。所以你有了: arr[0]存储在地址100处。 arr[1]存储在地址104.(由于int类型,因此为+4) arr[2]存储在地址108处。 arr[3]存储在地址112.等等。

现在您正在进行char *ptr = (char *) arr;,因此ptr = 100(与arr相同)。 下一个陈述很有意思,特别是printf的第二个论点:*(ptr+4)。 请记住,ptr = 100.所以ptr + 4 = 104,与arr[1]相同的地址!因此它将打印arr[1]的值,即2。