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