6

我不觉得指针理论特别麻烦,但我偶尔会被一些符号弄糊涂。在下面的例子中,有人能解释一下这条线是如何p = (int*) a工作的。我对代码的解释表明,这一行只是将第一个数组的第一个元素的地址存储在指针 p 中,这样就可以printf("%u", *p)产生5. 如果是这样的话,这条线只是一种更间接的写作方式p = a[0]吗?

int main()
{
    int a[][4] = {
        5, 7, 5, 9,
        4, 6, 3, 1,
        2, 9, 0, 6
        };



    int *p; // create an integer pointer
    int (*q)[4]; // create a pointer to a four-element integer array

    p = (int*)a; // ?
    q = a;


    printf("%u %u\n", p, q);
    p++;
    q++;
    printf("%u %u\n", p, q);


    return 0;
}
4

5 回答 5

9

表达式a在值上下文中使用时,确实会评估为“数组第一个元素的a地址” - 地址a[0]- 正如您正确理解的那样。

但是,请注意,数组a实际上就是我们所说的二维数组。它是一个数组数组。array 的第一个元素a本身就是一个数组:类型为 的数组int [4]。因此,考虑到上述a情况,在值上下文中使用时,表达式等同于表达式&a[0],它是一个类型的指针,int (*)[4]在概念上指向整个一维数组a[0]

出于这个原因,尝试做

p = a;

将导致来自编译器的诊断消息。int (*)[4]int *指针对象赋值是非法的。这些类型不兼容。为了抑制此诊断消息,有问题的代码使用显式强制转换

p = (int *) a;

这有力地将上述int (*)[4]指针值推入p. 在典型的实现中,这保留了原始指针的数值,只执行概念类型转换。

访问 的 值的尝试*p通常会产生 的 值,a[0][0]因为从数字上看,整个a地址与 的地址相同,a[0]并且与 的地址相同a[0][0]。上面的代码利用了这个数字标识,同时使用显式转换来解决类型不兼容问题。

于 2013-02-27T22:10:52.803 回答
7

我对代码的解释表明,这一行只是将第一个数组的第一个元素的地址存储在指针 p 中

正确的。

如果是这样的话,这条线只是一种更间接的写作方式p = a[0]吗?

不,不是。“这一行只存储第一个元素的地址” - 它非常类似于

p = &a[0];

但是上面的说法并不完全正确,因为&a[0]它的类型是int (*)[4]. 没有演员表的正确分配可能类似于

p = &a[0][0];

尝试使用 with-Wall打开编译各种声明并搜索偶尔的错误/警告:)

于 2013-02-27T21:55:31.307 回答
2

为了扩展 H2CO3 的答案,请记住,在大多数情况下,数组类型的表达式将转换为指针类型的表达式,表达式的值将是数组第一个元素的地址。

The type of the expression a is "3-element array of 4-element array of int". Except when it is the operand of the sizeof, _Alignof, or unary & operators, a will be converted to an expression of type "pointer to 4-element array of int" (int (*)[4]), and its value will be the address of a[0]. The problem is that a value of type int (*)[4] cannot be assigned to a variable of type int *; the types are not compatible, so we need to cast the result of the expression a to int *.

This works because the address of the array and the address of the first element of the array are the same - the expressions a, &a, a[0], &a[0], and &a[0][0] all yield the same value, they just have different types (int (*)[4], int (*)[4][4], int *, int (*)[4], and int *, respectively).

于 2013-02-27T22:31:26.233 回答
0

几乎。它类似于写作p = &a[0][0]

于 2013-02-27T21:55:29.033 回答
-2

a是一个数组的3数组4int

的值a是指向 的数组4的指针int。该指针的值是数组开头的地址。

(int *) a将指针转换为指向int. 值不变,但类型不同。

请注意,要打印指针值,正确的规范是p.

于 2013-02-27T21:55:29.940 回答