考虑到VLA自c99
以来的兴起,将未知大小的多维数组传递给函数变得更加容易。但是关于使用vla存在相当多的争议。有些人欣然赞同:"它通常更好要使用动态内存,可以使用alloca()或VLAs。1其他人嘲笑他们。我问自己的问题是什么标准的方式是在c90
天传递一个多维数组到一个函数。下面是一小段代码:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int arr[2][4];
int i;
int j;
for(i = 0; i < 2; i++) {
for(j = 0; j < 4; j++) {
arr[i][j] = j;
}
}
exit(EXIT_SUCCESS);
}
我能想到一种方法:把一个指针传递给另一个指针:
void foo_a(int m, int n, int **ptr_arr)
{
int i, j;
for (i = 0; i < m; i++) {
for (j = 0; j < n; j++) {
ptr_arr[i][j] += 1;
}
printf("n");
}
}
但是这需要首先通过在main中插入一些类似的东西来使数组平坦化(这并不美观)。
int *unidim_arr[ROW];
for (i = 0; i < ROW; i++) {
unidim_arr[i] = &(arr[i][0]);
}
另一种可能是使用单个指针并手动计算偏移量,这很容易出错:
void foo_b(int m, int n, int *ptr_arr)
{
int i, j;
for (i = 0; i < m; i++) {
for (j = 0; j < n; j++) {
*((ptr_arr + i * n) + j) += 1;
}
}
}
我觉得最好的解决方案是使用像
这样的东西void foo_c(int m, int n, int (*ptr_arr)[])
{
int i, j;
for (i = 0; i < m; i++) {
for (j = 0; j < n; j++) {
ptr_arr[i][j] += 1;
}
}
}
但据我所知,这只适用于vla,我可以在函数参数列表中简单地指定(*ptr_arr)[n]
?在c90
中是否有另一种方法可以特别注意foo_c()
?
<子>1. 请不要抨击系统。 子>
一种方法是将指向数组第一个元素的指针与数组维度一起传递,然后在函数中将该指针视为一维数组。
的例子:
void foo( int *arr, size_t r, size_t c ) // process a 2D array defined as int arr[r][c]
{
for ( size_t i = 0; i < r; i++ )
for ( size_t j = 0; j < c; j++ )
arr[i * r + j] = some_value(); // calculate index manually
}
int main( void )
{
int arr[4][5];
foo( &arr[0][0], 4, 5 );
}
这很容易扩展到高维数组。当然,这只适用于真正的多维数组,其中行在内存中都是相邻的。对于每次动态分配一行的数组,例如
,这将不起作用。int **arr = malloc( sizeof *arr * rows );
for ( size_t i = 0; i < rows; i++ )
arr[i] = malloc( sizeof *arr[i] * cols );
,因为不能保证行相邻,但在这种情况下,您只需按原样使用arr
指针:
void bar( int **arr, size_t r, size_t c ) // process a 2D array defined as int **arr
{
for ( size_t i = 0; i < r; i++ )
for ( size_t j = 0; j < c; j++ )
arr[i][j] = some_value();
}