1

可能重复:
如何在 C++ 中使用数组?

一维数组作为函数参数:

#include <stdio.h>
#include <string.h>

int func(int a[], int n)
{
    int i;
    for(i = 0; i < n; i++)
        printf("%d ", a[i][j]);
}

int main(void)
{   
    int a[2] = {1,2};
    func(a, 2);
}

它编译并正确运行。

但是当二维数组作为函数参数时:

#include <stdio.h>
#include <string.h>

int func(int a[][], int n)
{
    int i, j;
    for(i = 0; i < n; i++)
        for(j = 0 ; j < n; j++)
            printf("%d ", a[i][j]);
        printf("\n");
}

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

它无法正确编译。我必须像这样修改代码:

#include <stdio.h>
#include <string.h>

int func(int a[][2], int n)
{
    int i, j;
    for(i = 0; i < n; i++)
        for(j = 0 ; j < n; j++)
            printf("%d ", a[i][j]);
        printf("\n");
}

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

我不知道为什么?任何人都可以解释它是如何工作的?非常感谢。

4

5 回答 5

7

c 中的数组(一维和多维)驻留在连续的内存块中。这意味着当您定义 时char a[3],数组在内存中的布局是这样的(原谅我糟糕的 ascii 艺术技能):

| a[0] | a[1] | a[2] |

对于二维数组char a[2][3],布局如下:

| a[0][0] | a[0][1] | a[0][2] | a[1][0] | a[1][1] | a[1][2] |  
                              ^
                              +--- first row ends here

因此,当您索引二维数组a[i][j]时,编译器会生成与此等效的代码:

*(a + i*3 + j)

可以读作“跳过 i 行并在该行中取单元格 j”。为此,编译器必须知道行的长度(即第二维)。这意味着第二维是类型定义的一部分!

因此,当您想要将二维数组传递给函数时,您必须为类型定义指定所需的维度。

于 2013-01-01T14:26:40.743 回答
3

最近的(例如C2011,可能还有C99C标准启用了可变长度数组,因此以下函数确实有效

int
sum (int n, int t[n][n])
{
  int s = 0;
  for (int i = 0; i < n; i++)
    for (int j = 0; j < n; j++)
      s += t[i][j];
  return s;
}   

这是在没有警告的情况下编译的,gcc-4.7 -std=gnu99 -Wall -O -c ex.c并且生成的汇编程序是您所期望的

至于为什么int t[][]不能工作,那是因为整体的每个元素都是大小不定t的类型。int []

于 2013-01-01T14:22:21.310 回答
0

这是一个很好的解释:http: //www.eskimo.com/~scs/cclass/int/sx9a.html

于 2013-01-01T14:21:37.707 回答
0

如果没有数组的第二维,编译器不知道如何索引它。这是因为编译器使用指针进行了一些算术运算,以找出在内存中找到值的位置。

于 2013-01-01T14:21:41.567 回答
0

C 中的数组非常“弱”,通常在运行时仅由指向第一个元素的指针表示。当您声明类似int a[][]的内容时,不可能知道如何计算每个元素的地址,因为类型声明没有说明。这就是它无法编译的原因,因为类型无效。

如果你可以有int a[][], 然后调用它传递一个int big[8][8]or int small[2][2],那么函数内部的代码就无法神奇地“适应”这些不同数组的正确地址计算。这就是为什么它不起作用。

您可以编写一个通用函数int *matrix, size_t width,例如手动进行地址计算,即元素 " matrix[i][j]"matrix[i * width + j]用于row-major ordering

于 2013-01-01T14:21:57.737 回答