我正在学习C编程语言,我刚开始学习带指针的数组。我在这个问题上遇到了问题,我希望该输出必须 5
,但 2
,有人可以解释原因吗?
int main(){
int arr[] = {1, 2, 3, 4, 5};
char *ptr = (char *) arr;
printf("%d", *(ptr+4));
return 0;
}
答案 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。