通过指向不完整数组类型的指针,将多维数组传递给没有最大尺寸的函数

时间:2015-07-15 18:18:29

标签: c c11

据我记得,数组总是作为指针传递。例如,声明:

void foo(int array[2][5]);

对于编译器来说意味着完全相同的东西:

void foo(int (*array)[5]);

你可以说这两种形式都是等价的。现在,我想知道,为什么允许将其声明为:

void foo(int (*array)[]);

虽然不是:

void foo(int array[][]);

举个例子:

#include <stdio.h>

void foo(int (*p)[3]);
void bar(int (*p)[]);

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

    foo(a);
    bar(a);

    return 0;
}

// The same as int p[][3] or int p[N][3] where N is a constant expression
void foo(int (*p)[3]) 
{

}

// Would it the same as int p[][] or int p[N][] (by analogy)?
void bar(int (*p)[])
{

}

编译很好但没有警告,但如果我将bar的声明更改为:

void bar(int p[][]);

那么这是一个错误。

为什么C允许这样的&#34;模糊&#34;传递数组的方法?

2 个答案:

答案 0 :(得分:5)

数组不是指针,如果你声明一个具有未指定大小的指针数组就可以了,因为它将存储在poitners中存储的地址,并且每个元素的大小都是已知的,但p[][]需要数组没有他们的地址和数组的大小是不知道的,所以这是问题。

如果您说int p[][]p[0] p[1] int (*p)[] IntStream IntStream.range(0, Integer.MAX_VALUE) Integer.MAX_VALUE java -version | sed 3p java -version | tail -1 java -version | cut -d$'\n' -f3 java -version 知道距离是大小,请说清楚openssl s_client -connect smtp.gmail.com:587 -starttls smtp < /dev/null 2>/dev/null | openssl x509 -fingerprint -noout -in /dev/stdin | cut -d'=' -f2 指针。

数组被转换为指针但不是指针。

答案 1 :(得分:2)

您对未指定&#39;的阵列的C语言支持感到绊倒。尺寸,您可以声明,但通常不能直接使用,除非您在某处给它更具体的尺寸。

在您的示例中,如果您实际尝试对bar中的数组执行任何操作,则会收到错误:

void bar(int (*p)[])
{
    printf("%d\n", p[1][1]);
}

% gcc -Wall t.c
t.c: In function ‘bar’:
t.c:23:5: error: invalid use of array with unspecified bounds
     printf("%d\n", p[1][1]);
     ^

你在bar中使用p唯一能做的就是将它强制转换为具有显式大小的某种类型,或者将其传递给另一个带有指向数组(指定或未指定大小)的指针的函数,如果你使用错误的显式大小来尝试访问数组,你会得到未定义的行为而没有警告。