C语言中的二维数组初始化

9

我知道这是一个老生常谈的问题,但是我想在我的代码中静态分配一个小的2D数组。我知道实现这个的方法是:

static int A[3][2] = { { 1, 2 }, { 3, 4 }, { 5, 6 } };

这很好,我可以访问它的所有成员。然而,我在将其传递给函数时遇到了几个问题,例如:

void print_matrix(int **a, int r, int c)
{
    int x, y;

    for(x = 0; x < r; x++)
    {
        printf("Row %02d = %#x = ", x, a[x]);

        for(y = 0; y < c; y++)
        {
            printf("%s%d", (0 == y) ? "" : ", ", a[x][y]);
        }
        printf("\n");
    }
}

首先,我不能简单地将A传递给函数,需要将其强制转换为(int **)。由于char *char []同义,因此我对此感到有些惊讶。其次,它会崩溃,在调试器中检查,子函数中的a [0]报告为1,而不是指向整数数组的指针。
我知道这里发生了编译器/C语言神秘的魔法。但是这一切都有点令人困惑。如果我尝试初始化为:
static int *A[3] = { { 1, 2 }, { 3, 4 }, { 5, 6 } };

我收到了很多警告。这与以下情况有何不同:
static char *S[3] = { "hello", "there", "stackoverflow" };

除了那些我从未学过的神秘 C 语言技巧,尽管我已经使用 C 编程超过十年了 :(,我想知道如何生成我的数组,以便我可以成功地将其作为 int ** 传递,而不必通过所有繁琐的 for 循环或将静态分配的数组复制到动态分配的数组中。
以下方法可行吗?
int *A0 = { 1, 2 };
int *A1 = { 3, 4 };
int *A2 = { 5, 6 };
int **A = { A0, A1, A2 };

有没有比这更好的方法呢?

谢谢大家。

附言:我知道在实际生活中,我们会从数据库或文件中读取值到动态分配的数组中,并避免所有这些麻烦。


我会先查阅C FAQ中的这个问题,然后再阅读整个章节 - NPE
3个回答

15

多维数组不会变成多级指针(我不知道正确的术语)。只有一个维度会衰减。例如:

int [20] 变成 int *int [20][5] 变成 int (*)[5](不是 int **)等。

如果非常想使用多维数组(通过 [r][c] 语法),则必须传递其他边界(必须是常数)。如果需要变量边界,则最好手动执行索引转换(即,使用 a[r*C + c] 而不是 a[r][c])。


6
在 C99 中,可以这样定义函数:"void f(int c, int a[][c])..." 或 "void f(int c, int (*a)[c])..."。然后,您可以像使用其他多维数组一样索引该数组。 - tiftik

2
int A0[2] = { 1, 2 };
int A1[2] = { 3, 4 };
int A2[2] = { 5, 6 };
int *A[3] = { A0, A1, A2 };

你在上一节中已经很接近了,但需要稍微不同的声明。生成的A可以作为int **传递给函数。
使用此方法,print_matrix(A, 3, 2); 输出如下:
Row 00 = 0x5eaeda70 = 1, 2
Row 01 = 0x5eaeda68 = 3, 4
Row 02 = 0x5eaeda60 = 5, 6

2
最快的方法是将参数a声明为int a[][2]
void print_matrix(int[][2] a, int r, int c);

// and call the function like this:
print_matrix(A, 3, 2);

3
这是C语言,因此 void print_matrix(int a[][2], <etc>) - lijie

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接