我需要一个将二维数组传递给 C 函数的简单示例
I need a straightforward example of passing an 2D array to a function in C
我想创建一个 C 函数,它将一个双精度的二维数组作为参数并通过索引对该数组进行操作,例如printf("%f ", array[i][j])
.
我从各种示例和 SO 问题中拼凑出来的内容是这样的:
void printArray(double **array, int m, int n)
{
int i, j;
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
{
printf("%f ", array[i][j]);
}
printf("\n");
}
}
在 main
中,我能够像这样成功打印数组:
int i, j, k = 0, m = 5, n = 6;
double **a = malloc(m * sizeof(*a));
//Initialize the arrays
for (i = 0; i < m; i++)
{
a[i] = malloc(n * sizeof(*(a[i])));
}
for (i = 0; i < m; i++)
{
for (j = 0; j<n; j++)
{
k++;
a[i][j] = k;
}
}
printArray(a, m, n);
但是,当我尝试将数组初始化为某些给定值然后调用时:
double a[5][6] = { { 1, 2, 3, 4, 5 ,6},
{ 1, 2, 3, 4, 5, 6},
{ 1, 2, 3, 4, 5, 6},
{ 1, 2, 3, 4, 5, 6},
{ 1, 2, 3, 4, 5, 6} };
printArray(a, 5, 6);
我遇到了以下错误:
Unhandled exception at 0x011514D3 in Example.exe: 0xC0000005:
Access violation reading location 0xA1F8E3AC.
有人可以解释我的错误是什么以及如何解决吗? 已编辑
请注意,出于函数定义的目的,我将在 运行 时而不是编译时知道数组的大小。此外,我正在使用 VisualStudio 2013 Windows 进行编译。
double a[5][6]
的类型为 double[][6]
,与 double**
不同。 double**
是指向双精度指针的指针。 double[][6]
是一种编译器管理的数据类型,表示二维数组。
这里发生的事情是,在调用 printArray
.
时,您创建的 double[][6]
被静默转换为 double**
如果您的函数要使用 double**
,您需要将其传递给 double**
。您可以通过单独填充每个成员数组来初始化数组内容:
double row1[3] = {3, 4, 5};
a[1] = row1;
这解决了这个问题;因为 double[]
由编译器存储为 double
值的连续数组,所以如上所述将其隐式转换为 double*
是安全的。
另一种解决方案是将函数更改为采用 "real" double[][6]
,而不是指针指针。如何使用非固定大小的数组执行此操作取决于您的特定非品牌 C;据我所知,它不是 C 标准的一部分。
第三种解决方案是用 malloc
逐行构建数组,然后用 a[0][0] = 1
逐个单元格地填充它,依此类推。您的问题中已经有了这个,并且它可以正常工作。
最后要注意的是,您正在堆栈上分配 a
:当您的 main
函数退出时,访问它会导致未定义的行为。
我想创建一个 C 函数,它将一个双精度的二维数组作为参数并通过索引对该数组进行操作,例如printf("%f ", array[i][j])
.
我从各种示例和 SO 问题中拼凑出来的内容是这样的:
void printArray(double **array, int m, int n)
{
int i, j;
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
{
printf("%f ", array[i][j]);
}
printf("\n");
}
}
在 main
中,我能够像这样成功打印数组:
int i, j, k = 0, m = 5, n = 6;
double **a = malloc(m * sizeof(*a));
//Initialize the arrays
for (i = 0; i < m; i++)
{
a[i] = malloc(n * sizeof(*(a[i])));
}
for (i = 0; i < m; i++)
{
for (j = 0; j<n; j++)
{
k++;
a[i][j] = k;
}
}
printArray(a, m, n);
但是,当我尝试将数组初始化为某些给定值然后调用时:
double a[5][6] = { { 1, 2, 3, 4, 5 ,6},
{ 1, 2, 3, 4, 5, 6},
{ 1, 2, 3, 4, 5, 6},
{ 1, 2, 3, 4, 5, 6},
{ 1, 2, 3, 4, 5, 6} };
printArray(a, 5, 6);
我遇到了以下错误:
Unhandled exception at 0x011514D3 in Example.exe: 0xC0000005:
Access violation reading location 0xA1F8E3AC.
有人可以解释我的错误是什么以及如何解决吗? 已编辑
请注意,出于函数定义的目的,我将在 运行 时而不是编译时知道数组的大小。此外,我正在使用 VisualStudio 2013 Windows 进行编译。
double a[5][6]
的类型为 double[][6]
,与 double**
不同。 double**
是指向双精度指针的指针。 double[][6]
是一种编译器管理的数据类型,表示二维数组。
这里发生的事情是,在调用 printArray
.
double[][6]
被静默转换为 double**
如果您的函数要使用 double**
,您需要将其传递给 double**
。您可以通过单独填充每个成员数组来初始化数组内容:
double row1[3] = {3, 4, 5}; a[1] = row1;
这解决了这个问题;因为 double[]
由编译器存储为 double
值的连续数组,所以如上所述将其隐式转换为 double*
是安全的。
另一种解决方案是将函数更改为采用 "real" double[][6]
,而不是指针指针。如何使用非固定大小的数组执行此操作取决于您的特定非品牌 C;据我所知,它不是 C 标准的一部分。
第三种解决方案是用 malloc
逐行构建数组,然后用 a[0][0] = 1
逐个单元格地填充它,依此类推。您的问题中已经有了这个,并且它可以正常工作。
最后要注意的是,您正在堆栈上分配 a
:当您的 main
函数退出时,访问它会导致未定义的行为。