c - 我的程序的输出令人困惑



我有这样的代码

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); 
 }

所有 3 个值的输出都相同,任何人都可以告诉我为什么。?

首先 -

正如其他人指出的那样 - 您需要使用正确的格式说明符,并将这些值转换为指针。


现在谈谈为什么它们都赋予相同的价值。

这里 x 是一个数组。并且其元素的类型unsigned int[3].即 x是一个数组的unsigned int[3]数组。

首先,x + 3 给出数组中第四个元素的地址。那就是{10, 11, 12}地址 .此数组在内存中的地址将是其在内存中的第一个元素的地址。这是内存中10的地址。注意这个值是int (*) [3]的,即 address of an unsigned int[3] array .

二、* (x + 3)相当于 x[3],这是第四个元素,即 unsigned int[3] 。它是数组{10, 11, 12}。此值指向数组{10, 11, 12} .也就是说,此值指向 10 。请注意,此值为 unsigned int[3]

第三*(x+2) + 3:这里*(x + 2)相当于x[2]unsigned int[3],是{7, 8, 9}数组,当你做一个+ 3你又得到了10的地址。请注意,此值为 unsigned int[3]

因此,您会看到在所有三种情况下,您的结果都是内存中的相同地址,即存储10的地址 - 即使您在不同的时间表示不同的事物; 一开始unsigned int (*)[3],第二和第三unsigned int[3]

提炼的未定义行为:

printf("%u, %u, %u", x + 3, * (x + 3), * (x + 2) + 3);

所有额外的参数都必须unsigned int,但是 2d 是unsigned int (*)[3]的,3d 是unsigned int *的,4 个也是unsigned int *的。

你得到的值是错误的,因为你的指针算术是错误的。
x的类型是 unsigned int[4][3],一个长度为 4 的数组,其每个成员本身就是一个长度为 3 的数组。

那么什么是x+3?它是x中最后一个成员的地址(请记住,x的成员是数组(。
因此*(x+3)本身就是一个数组。但是,当您将数组作为函数参数传递时,它们会发生什么?它们衰减成指针。因此,您会看到数组中第一个元素的地址,该地址被 printf 中的错误类型说明符破坏。

好的,让我们以元素x[2][3]为例。它将是这种表达*(*(x+2)+3)完全等同于*(&x[0][0] + 2*3 + 3)

相关内容

  • 没有找到相关文章

最新更新