繁体   English   中英

在C中传递2D数组

[英]Passing 2D arrays in C

我从C中断了一次,只是又重新回到了C。

如果我想创建一个2D的双精度数组,我可以通过两种方式做到这一点:

double** m_array = (double**) malloc(2*sizeof(double*));
double*  m_array = (double*)  malloc(2*sizeof(double));

要么

double array[2][2];

但是,当我希望传递malloc数组而不是传递另一个数组时,似乎有两个约定:

//allowed for passing in malloc'd array, but not for other array
func_m(m_array) //allowed
func_m(array) //disallowed
func_m(double** m_array)

//allowed for passing in either array; required for passing in non-malloc'd array
func(m_array) //allowed
func(array) //allowed
func(double array[][2])

首先,我不需要任何信息,它是指向指针数组的指针。 但是它只能是一个malloc数组。

在第二个中,我需要传递double *数组所指向的每个数组的长度。 这似乎很愚蠢。

我想念什么吗? 提前致谢。

第一个根本不创建二维数组。 它创建一个指针数组,该指针显然没有指向。 如果确实将每个指针初始化为一个数组,则该指针仍将是数组的数组,而不是二维数组。

为什么不创建二维数组呢?

double* dynamicArray = malloc(rows * columns * sizeof (double));

要么

double autoArray[rows][columns];

然后您可以使用以下任一功能:

void func(double* array, size_t rows, size_t columns);

为了澄清起见,假设您声明:

int my_static_array[row][col];

在pmg的答案中,my_static_array与malloc'd数组(称为my_malloc数组)的类型是什么? my_static_array是内存中连续的row * col * sizeof(int)个字节,并带有指向其开头的int *指针。 在计算my_static_array [x] [y]时,编译器会知道这样做(因为它们以行优先顺序存储):

*(addr(my_static_array) + [sizeof(int)*col*x] + [sizeof(int)*y])

这就是为什么我需要传递C的col值的原因:

(1) func(int my_static_array[][col])
(2) func(int my_static_array[][])

在(1)中,编译器知道如何为静态数组正确计算地址。 在(2)中,编译器没有足够的信息。 这就是为什么(1)编译而(2)不会编译的原因。

如果是malloc数组,则可以通过:

func(int** my_malloc_array)

由于它是指向一维数组的连续数组的指针,因此编译器不需要帮助。 my_malloc_array [x] [y]很简单:

*(*(addr(my_malloc_array)+x)+y)

编译器不需要其他有关其维数的信息即可进行计算。

那么,这是什么教训? 二维阵列是一样的指针数组至1D阵列。 前者的类型为int(* my_static_array)[row * col]-指向行* col元素数组的指针,后者的类型为int **-指向指针数组的指针。

您对2D阵列的分配是错误的。 通常的2D方法是

double **m_array = malloc(NROWS * sizeof *m_array);
for (i = 0; i < NROWS; i++) {
  m_array[i] = malloc(NCOLS * sizeof *m_array[i]);
}

将数组或指针(任何维)传递给函数时,必须让函数知道维:它们未在数组或指针本身内编码。

一方面,您具有指向某些对象的指针(指向指针(至指针(...))),另一方面,您具有某种类型的数组(数组(属于数组(...)))。

当您将指针传递给函数时,就是这样。 当您“传递数组”时,发生的事情是该数组衰减为指向其第一个元素的指针。 所以

foo(array); // is the same as foo(&(array[0]));

array是多维数组时,衰减指针的类型是pointer to array[size] of SOMETHING (但您不能使用该大小!)。

最简单的方法是使用简单的指针编写函数并传递所有维的乘法

double array[3][4][5];
foo(&(array[0][0][0]), 3*4*5);

假设计算机存储器是一个充满按顺序编号的框的仓库。 当你做

int matrix[10][3];

您保留30个用于保存矩阵值的框(例如,框131至160)。

现在,假设您要对函数中矩阵中的所有值求和:

int matrix_sum(int matrix[10][3]) { /* ... */ }

但是接收到的所有函数(由标准规定)都是指向矩阵第一个元素的指针:指向3个int数组的指针。 因此,该函数知道框131、132和133属于矩阵,但它不知道矩阵实际有多长时间。

使用简单的typedef:

typedef double Twodouble_t[2];

void func(Twodouble_t *ptr)
{
  size_t i, numelements = sizeof*ptr/sizeof**ptr;
  puts("first array");
  for( i=0; i<numelements; ++i )
    printf("\n%f",ptr[0][i]);
}
...
Twodouble_t array[]={ {1., 1.},{2., 2.},{3.,3.} };
func(array);
...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM