以下代码如何给出答案,如2036,2036,2036。
以下C代码的输出是什么?假设x的地址是2000(十进制),整数需要四个字节的内存。
int main()
{
unsigned int x[4][3] = {{1, 2, 3}, {4, 5, 6},
{7, 8, 9}, {10, 11, 12}};
printf("%u, %u, %u", x+3, *(x+3), *(x+2)+3);
}
答案 0 :(得分:3)
正如您刚刚发现的那样,如果您不发布经过精心设计的代码,那么人们可能会对此感到有点苛刻。要打印地址,请使用%p
中的<inttypes.h>
或来自PRIXPTR
的宏,例如uintptr_t
并投射到%p
。
只使用#include <stdio.h>
int main(void)
{
unsigned int x[4][3] =
{
{ 1, 2, 3 }, { 4, 5, 6 },
{ 7, 8, 9 }, { 10, 11, 12 }
};
printf("%p\n", (void *)x);
printf("%p, %p, %p\n", (void *)(x+3), (void *)(*(x+3)), (void *)(*(x+2)+3));
return 0;
}
,您的代码应该是:
x+3
现在你已经定义了行为,虽然这些值不像2000和2036那样方便。
但是,int
是数组开始后第4个sizeof(int) == 4
数组的地址,所以假设x
如上所述,那就是{ {1}} - 如果x
是2000,则为2036。
*(x+3)
是第四个数组开头的地址;在同样的假设下,这是在2036年。
*(x+2)+3
将3添加3 int
的第三个数组的地址,然后再添加3个。x
这也是x
开始后的36个字节,如果0x7fff5800a440
0x7fff5800a464, 0x7fff5800a464, 0x7fff5800a464
是2000,则结束于2036。
在我的64位计算机上,输出显示为:
((MainActivity) getActivity()).showTwoLinearLayout();
((MainActivity) getActivity()).hideCategoryContainerLayout();
Hex 0x24当然是36位小数。
答案 1 :(得分:1)
2000 4 8 12 16 20 24 28 32 36 40 44 48
+---+---+---+---+---+---+---+---+---+---+---+---+
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10| 11| 12|
+---+---+---+---+---+---+---+---+---+---+---+---+
x { } size = 48
{ x[0] } { x[1] } { x[2] } { x[3] } size = 12 * 4
x = 2000
x + 3 = &x[3] = 2000 + 3 * ( 3 * 4) = 2036
^ ^-----^ size of int[3]
index
*(x+2) + 3 = &x[2] + 3 off = 2000 + 2 * (3 * 4) + 3 * 4 = 2036
x
和x[0]
的地址相同,其类型(以及大小)不同。
您应该在return 0
功能的末尾添加main
。您的print语句也应如下所示:
printf("%p, %p, %p\n", (void *)(x+3), (void *)*(x+3), (void *)(*(x+2)+3));
/* ^^ ^^ ^^^^ ^^^^^^^^^ ^ ^^^^^^^^ ^^^^^^^^^ ^ */
对于明确界定的行为。
答案 2 :(得分:1)
修改:正如Jonathan Leffler所指出的那样,我应该在打印(void*)
之前投射到%p
也许这将澄清内存寻址方面的情况:
#include <stdio.h>
int main() {
unsigned int x[4][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}, {10, 11, 12}};
// Output: Address, 1
printf("%p, %u\n", (void*)(x), **x);
// Output: Address + 12, 4
printf("%p, %u\n", (void*)(x+1), **(x+1));
// Output: Address + 24, 7
printf("%p, %u\n", (void*)(x+2), **(x+2));
// Output: Address + 4, 2
printf("%p, %u\n", (void*)((*x)+1), *(*(x)+1));
return 0;
}
**x
应该用来获取x[0][0]
**(x+1)
应该用来获取x[1][0]
**(x+2)
应该用来获取x[2][0]
*(*(x)+1)
应该用来获取x[0][1]
为了更加清晰:
#include <stdio.h>
int main() {
unsigned int x[4][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}, {10, 11, 12}};
printf("%p, %u\n", (void*)(x), **x); // Output: Address, 1
printf("%u\n", x[0][0]); // Output: 1
printf("%p, %u\n", (void*)(x+1), **(x+1)); // Output: Address + 12, 4
printf("%u\n", x[1][0]); // Output: 4
printf("%p, %u\n", (void*)(x+2), **(x+2)); // Output: Address + 24, 7
printf("%u\n", x[2][0]); // Output: 7
printf("%p, %u\n", (void*)((*x)+1), *(*(x)+1)); // Output: Address + 4, 2
printf("%u\n", x[0][1]); // Output: 2
return 0;
}