如何在C函数中传递2D数组(矩阵)?


72

我需要执行此操作,以保持对矩阵的操作。这是否意味着它需要通过引用传递?

这样就足够了吗?

void operate_on_matrix(char matrix[][20]);

Answers:


124

C确实没有多维数组,但是有几种模拟它们的方法。将此类数组传递给函数的方式取决于模拟多维的方式:

1)使用数组数组。仅当在编译时完全确定了数组边界,或者您的编译器支持VLA时,才可以使用此方法:

2)使用(动态分配的)数组指针指向(动态分配的)数组。通常在运行时才知道数组范围时使用。

3)使用一维数组并固定索引。这可以与静态分配(固定大小)和动态分配的数组一起使用:

4)使用动态分配的VLA。相对于选项2而言,它的一个优点是只有一个内存分配。另一个是需要较少的内存,因为不需要指针数组。

(请参阅srand()-为什么只调用一次?。)


以上述第一种方式,代码将无法编译。第17和35行中的“行”和“列”必须分别更改为“行”和“ COLS”。
KZcoding 2015年

5
void func_vla(int array[rows][cols], int rows, int cols)应该是void func_vla(int rows, int cols, int array[rows][cols])
David Ranieri,2015年

@KZcoding:如果编译器支持C99,或者如果它支持C11并且未定义,则第17和35行中使用的VLA表示法正确__STDC_NO_VLA__。如果编译器不支持VLA,则当然不会编译。
乔纳森·莱夫勒

malloc返回一个void指针,您确定不需要在需要时将其转换为int *或int **吗?解决方案2
Liger

转换更像是C ++约定,明白了!感谢@BartvanIngenSchenau
Liger

12

我不知道您所说的“数据不丢失”是什么意思。这是将普通2D数组传递给函数的方法:


21
随机事实:需要N的原因是因为计算机需要知道为每个“行”增加指针的距离。实际上,除第一个尺寸外,所有尺寸都是必需的。C将数组存储为内存块,没有分隔符。
Christian Mann 2010年

不使用malloc,数据不会丢失。谢谢您的帮助。
Shweta 2010年

1
@克里斯蒂安·曼(Christian Mann):那是一个好事实。我正好写上今天:-)精心解释stackoverflow.com/questions/3906777/...
阿伦

今天似乎每个人都在使用多维数组时遇到问题。:)我写了另外一个问题了类似的解释太:stackoverflow.com/questions/3911244/...
卡萨布兰卡

2
@ChristianMann相反,数组语法完全起作用的原因是因为编译器将参数中的数组声明调整为指向第一个元素的指针(在本例中为)int (*)[N]。这就是为什么必须提供除最外层尺寸之外的所有尺寸的原因-阵列仅衰减一次。这绝对与“计算机需要知道的”无关-废话。将其与1D情况进行比较:void func (int [n]),它会进行调整,void func (int*)并且所有大小信息都会丢失-“计算机”一无所知,编译器也不会在意。
伦丁

9

传递可变长度2D数组的最简单方法

对于C和C ++,最干净的技术是:像2D数组一样传递1D数组,然后在函数内部用作2D。

在内部,无论数组有多少维,C / C ++始终维护一维数组。因此,我们可以像这样传递任何多维数组。


只是一个小查询:如果我们调用函数like func(2, 3, matrix),那么我们应该有void func(int row, int col, int** matrix)
Kartik Chhajed

@KartikChhajed您的代码需要从隐式转换int*[3]int**,大多数C / C ++编译器可能不允许这样做。
Minhas Kamal

@jwpol不幸的是,这不是一个好主意:stackoverflow.com/q/25303647/1606345
David Ranieri

@David Ranieri如果您知道数组的维数,那么我看不到为什么您不应该取消引用特定元素的任何原因。例如int matrix[2][2],占用4个“单元”的内存,因此从*(p)*(p+3)(其中p是第一个元素的地址)在分配的内存范围内。这个答案也一样。您发布的线程是关于取消引用数组中最后一个元素之后的元素,在此情况下并非如此。@Minhas Kamal提供的答案绝对安全,只要您在raw和中通过合法边界即可col
jwpol

1

2D阵列:

3D阵列:

4D阵列:

和nD数组:

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.