2016-08-04 59 views
0

我的代码是这样的我的程序的输出是混乱

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个值都相同谁能告诉我为什么?

+0

使用错误的格式说明符是未定义的行为。 – mch

+0

错误的格式说明符%u是用于unsigned int的。 –

+0

'x + 3'的类型是'unsigned int(*)[3]'(一个指针),'*(x + 3)'和'*(x + 2)+ 3'的类型是'unsigned int *'。所有3个都不是'unsigned int',而是指针,所以你应该使用'%p'并且转换为'(void *)'。 – mch

回答

2

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


现在至于为什么他们都给出相同的价值。这里x是一个数组。其元素的类型是unsigned int[3]。即xunsigned 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]

0

蒸馏水未定义行为:

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

所有额外的参数必须是unsigned int,但2D是unsigned int (*)[3],三维是unsigned int *,第四是unsigned int *了。

1

你得到错误的值,因为你做指针算术错误。
xunsigned int[4][3]型,长度为4的阵列,其中每个部分是本身长度3.

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

好吧,让我们来看看元素x[2][3]。这将是*(*(x+2)+3)这种表示,全部相当于*(&x[0][0] + 2*3 + 3)