用于指向一行二维数组的C指针声明

时间:2013-05-10 15:59:10

标签: c

我在第299页的KN King的书中看到了这个声明

int a[ROWS][COLS], (*p)[COLS];

p = &a[0];

p现在指向第一行的二维数组。我理解为什么a[0]指向第一行的二维数组。但我不明白声明p的语法。这是什么意思,我怎么记得它?

*p周围的问题是什么? (*p)这种语法在运算符优先级方面意味着什么?

4 个答案:

答案 0 :(得分:16)

> "But I do not understand the syntax for declaring p"

所以p被声明为:

int (*p)[COLS];

它指向int的{​​{1}}数组,其大小为COLS

> "What does that mean and how do I remember it?"

以下是use the spiral rule的工作方式,并从()开始工作:

    ( p)                    p 
    (*p)                    p is a pointer
    (*p)[    ]              p is a pointer to an array
int (*p)[    ]              p is a pointer to an array of ints
int (*p)[COLS]              p is a pointer to an array of ints of size COLS

当然你总是cheat to get the answer too

enter image description here

> "what does this syntax mean in terms of operator precedence?"

C Language, [] has precedence over the unary *中,这意味着您需要()才能使p成为指向int数组的指针,而不是指针数组到int s。

答案 1 :(得分:2)

postfix []()运算符的优先级高于一元*运算符,因此它们首先绑定。 IOW,T *p[N]被解释为T *(p[N]); p是指向T的指针数组。为了声明一个指向数组的指针(或指向函数的指针),你必须使用括号来强制*运算符在[]之前绑定:

T *p[N];     // p is an array of pointer to T
T (*p)[N];   // p is a pointer to an array of T

T *f();      // f is a function returning pointer to T
T (*f)();    // f is a pointer to a function returning T

答案 2 :(得分:1)

忽略逗号并重写为:

int a[ROWS][COLS];
int (*p)[COLS];

p = &a[0];

p是指向一个整数COLS数组的指针 声明不会分配那么多内存,但它确实允许一些边界检查。阵列的内存分配在以下声明中:
a => int a[ROWS][COLS];

答案 3 :(得分:1)

  

我理解为什么[0]指向第一行的二维数组

这已经不准确了。在值上下文中,a[0]并未真正指向“2D数组的第一行”。 a[0]实际上指向第一行2D数组的第一个元素。换句话说,在值上下文a[0]是指向a[0][0]的指针。正如您可能知道的那样,a[0]的类型会衰减到int *sizeof *a[0]等于sizeof(int)。所以,它并没有真正指向整行。它指向一个唯一的int对象。

现在,如果您真的想要指向2D数组的第一行,即指向整个行,则需要&a[0]。这将为您提供类型为int (*)[COLS]的指针。请注意sizeof *&a[0]等于sizeof (int[COLS]),因此它确实是指向2D数组第一行的指针。这就是您在示例中看到的内容。

请注意,数值a[0]&a[0](作为值上下文中的指针)是相同的,因为它们指向线性内存中的相同位置。但是,类型&a[0]指向整行,而a[0]指向单个元素。