C语言中当二维数组和多维数组作为函数参数时[重复]

Posted

技术标签:

【中文标题】C语言中当二维数组和多维数组作为函数参数时[重复]【英文标题】:When two-dimensional array and multidimensional array as function parameters in C language [duplicate] 【发布时间】:2012-12-16 04:19:39 【问题描述】:

可能重复:How do I use arrays in 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);

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

【问题讨论】:

int a[] 然后a[i][j] - 这到底是如何正确编译的? 这个问题不是“如何在 C++ 中使用数组”的重复问题。无论如何,这个问题是如此广泛(措辞如此糟糕)。这个问题更具体(尽管需要对英语正确性进行一些编辑)。此外,即使该问题中涉及的某些内容与此处相关,但它们通常特定于 C++,而此问题应仅限于 C 并面向 C 习语。如果这是关于 SO 的另一个问题的重复,让我们在这里列出正确的问题。 【参考方案1】:

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

【讨论】:

【参考方案2】:

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

【讨论】:

【参考方案3】:

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

如果您可以拥有int a[][],然后通过int big[8][8]int small[2][2] 调用它,则函数内部的代码无法神奇地“适应”这些不同数组的正确地址计算。这就是它不起作用的原因。

您可以编写像int *matrix, size_t width 这样的通用函数并手动进行地址计算,即元素“matrix[i][j]”在matrix[i * width + j] 处为row-major ordering。

【讨论】:

【参考方案4】:

最近的(例如C2011,也许还有C99)C 标准启用了variable length array,所以下面的函数可以工作

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 []类型,它的大小是不确定的。

【讨论】:

【参考方案5】:

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”。为此,编译器必须知道行的长度(即第二维)。这意味着第二维是类型定义的一部分!

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

【讨论】:

以上是关于C语言中当二维数组和多维数组作为函数参数时[重复]的主要内容,如果未能解决你的问题,请参考以下文章

C语言函数传递二维数组

数组参数和指针参数

C 语言数组 ( 多维数组做函数形参退化为指针过程 | int array[2][3] -> int array[][3] -> int (*array)[3] )

c语言中怎么用二维数组作为函数参数

C语言二维数组作为函数的参数

C 语言数组 ( 一维数组形参退化 | 二维数组形参退化 | 函数形参等价关系 )