-2

首先,我对 C 没有信心,但我有一个 int 的二维数组,我想要一个函数来写入该数组单行的所有值。

例如:

int main(int argc, char *argv[])
{ 
    int a[2][2];
    a[0][0] = 1;
    a[0][1] = 2;
    a[1][0] = 3;
    a[1][1] = 4;
    change_array(&a[0]);
}

void change_array(int* array[])
{
    (*array)[0] = -1; 
    (*array)[1] = -1;        
}

程序立即崩溃。我试图将 change_array 函数更改为 array[0] = -1 并且......它有效!值已正确更改(我不知道为什么,因为它应该是完全错误的),但是如果我在程序的其他部分使用此函数,则数组的值保持不变。怎么可能?有什么建议可以成功更改我的数组的值吗?非常感谢!

4

3 回答 3

2

您可以尝试这样做:

#include <stdio.h>

void change_array(int array[2][2])
{
    array[0][0] = -1;
    array[0][1] = -1;
}

int main(int argc, char *argv[])
{
    int a[2][2];
    a[0][0] = 1;
    a[0][1] = 2;
    a[1][0] = 3;
    a[1][1] = 4;
    printf("%d %d\n%d %d\n\n", a[0][0], a[0][1], a[1][0], a[1][1]);
    change_array(a);
    printf("%d %d\n%d %d\n\n", a[0][0], a[0][1], a[1][0], a[1][1]);
}

这取决于您的需求,但在某些情况下,我发现最好使用单维度数组并为 2 维度构建 getter/setter。这样的解决方案可以在这个答案中找到:Correct way to allocate and free arrays of pointers to arrays

于 2013-06-24T12:14:04.257 回答
0

您的代码传递的东西与change_arraychange_array.

在代码中change_array(&a[0])a两个数组是两个数组inta[0]两个数组的第一个数组也是如此int&a[0]两个数组的第一个地址也是如此int。将此与 的声明进行比较change_array。在void change_array(int* array[]),array是指向 的指针数组int。所以这是一种不同的类型。

相反,您可以change_array使用void change_array(int (*array)[]). 然后array是一个指向数组的指针int,并且您的代码可以工作(使用(*array)[0] = -1)。

注意:您应该在启用警告的情况下进行编译,最好使用严格或迂腐的语言语义。那么编译器应该已经警告你change_arraymain没有事先声明的情况下使用它。您应该有一个事先声明,以便编译器在change_array使用之前知道它的完整类型。这样,编译器就会看到传递了错误的类型,并且会警告您。

尽管以上内容会更正您的代码,但大多数人会使用不同的解决方案。他们会change_array用声明void change_array(int *array),他们会用 来调用它change_array(a[0])

change_array(a[0])中,a[0]是第一个包含两个 的数组int。但是,C 语言中有一条规则,即数组表达式被转换为指向其第一个元素的指针。所以a[0]自动成为&a[0][0]. (只要数组不是 , 或 的操作数并且不是用于初始化数组的字符串文字,就会发生这种转换&sizeof_Alignof因此,调用传递了一个指向 的指针int,该指针与指向 的参数相匹配int。然后该参数array可以用作array[i]访问数组元素,因此您可以使用更简单的语法array[0] = -1来代替(*array)[0] = -1.

于 2013-06-24T13:20:01.100 回答
-3

C中,当将数组变量作为参数传递给函数时,数组变量衰减为指向包含数组第一个元素的内存地址的指针。这与它的所有元素都放置在连续内存中的事实相结合。所以C只需要保存数组的第一个位置(不管它有多少维),然后就可以根据索引计算它应该访问的指向内存的偏移量。

因此,在您的特定代码段上,变量a指向第一个元素,即a[0][0]. 所以,基本上这样做:

change_array(&a[0]);

大致(但不完全)与以下操作相同:

change_array(a);

现在,知道了数组是如何在 C 中传递的,您应该能够推断出,实际上,二维数组在作为参数传递时,实际上在访问它们的第一个坐标时包含一个指向第二个坐标的第一个元素所在位置的指针. 所以,当你这样做时,array[0]你将一个指针传递给第一个坐标下数组的第一个元素。然后当你这样做时,*(array[0])你实际上是在访问第二个坐标的第一个元素。

在这里补充一点也很重要;由于数组变量衰减为指针,因此 C 中的所有数组都是通过引用传递的,因为您正在传递一个指针。因此,所有修改传递给它们的数组的函数调用都会进行实际修改。

知道了这一点,那么你的功能应该是:

void change_array(int *array)
{
    array[0] = -1;
    array[1] = -1;
}

然后您可以执行如下调用:

change_array(a[0]);

为了修改第一个数组的元素a

现在,作为 中的良好实践C,并且为了避免分段错误,可以将指针与表示数组大小的整数一起传递给函数:

void change_array(int *array, int size);

然后总是执行访问检查这个边界。

于 2013-06-24T12:15:24.223 回答