奇怪的指向数组语法的指针

时间:2017-10-12 15:47:21

标签: c arrays pointers

什么是激励int (*arr)[5];arr声明为指向5个元素数组的指针的逻辑,而int *arr[5]arr声明为5个指针的数组?特别是考虑到*具有低优先级(不确定该部分,因为它不用作解除引用运算符)?

3 个答案:

答案 0 :(得分:2)

在声明和表达式中,像[]这样的后缀运算符比*之类的一元运算符具有更高的优先级,所以像

这样的声明
T *a[N];

解析

T *(a[N]);

因此

   a       -- a is
   a[N]    -- an N-element array of
  *a[N]    -- pointer to
T *a[N];   -- T

如果要将a声明为指向数组的指针,则需要使用*明确地将a运算符分组:

T (*a)[N];

因此:

    a      -- a is
  (*a)     -- a pointer to
  (*a)[N]  -- an N-element array of
T (*a)[N]; -- T

幸运的是,你更有可能使用指针数组而不是指向数组的指针,因此声明“简单”形式的声明会产生这种类型。

答案 1 :(得分:1)

您已经说明了原因:*的优先级低于[]。 所以

int *a[5];

int *(a[5]);

意味着a首先是一个数组,它是一个指针数组。

对我来说,这是一个很好的结果。我一直声明指针数组,int a[5]是方便的语法。尝试键入int (*a)[5]感觉很奇怪,但这没关系,因为我从不声明指向数组的指针(因为它们实际上从未有用)。

答案 2 :(得分:0)

  

什么是激励int(* arr)[5];

的逻辑

这取决于具体情况。例如,如果你有一个二维数组,那么你可以使用这种类型的指针作为迭代器。

这是一个示范程序

#include <stdio.h>

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

    for (int(*row)[5] = a; row != a + 2; ++row)
    {
        for (int *col = *row; col != *row + 5; ++col)
        {
            printf("%d ", *col);
        }
        putchar('\n');
    }

    return 0;
}

或者,如果你有一个函数将其参数声明为二维数组,例如

void f( int a[][5], size_t n );

然后隐式地将参数调整为类型int ( * )[5]

的指针

考虑到如果你有这样的数组

int * a[5];

然后指向数组的指针将显示为

int * ( *p )[5] = &a;

如果你有这样的数组

int a[5];

然后指向数组的指针看起来像

int ( *p )[5] = &a;