首先,我对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并且......它有效!值正确更改(我不知道为什么因为它应该完全错误),但是如果我在程序的其他部分使用此函数,则数组的值保持不变。 怎么可能?有关成功更改数组值的任何建议吗? 非常感谢你!
答案 0 :(得分:1)
您可以尝试这样做:
#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个维度构建吸气剂/设定器。这个解决方案可以在这个答案中找到:Correct way to allocate and free arrays of pointers to arrays
答案 1 :(得分:0)
您的代码会将某些内容传递给change_array
,该内容与为change_array
声明的参数不同。
在代码change_array(&a[0])
中,a
是包含两个int
的两个数组的数组。所以a[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_array
在main
中未使用事先声明时使用change_array
。您应该有一个事先声明,以便编译器在使用之前知道change_array
的完整类型。有了这个,编译器就会看到传递了错误的类型,它会警告你。
虽然以上内容会纠正您的代码,但大多数人会使用不同的解决方案。他们会使用void change_array(int *array)
声明change_array(a[0])
,他们会将其称为change_array(a[0])
。
在a[0]
中,int
是两个a[0]
的第一个数组。但是,在C语言中有一条规则,即数组表达式转换为指向其第一个元素的指针。因此&a[0][0]
会自动变为&
。 (只要数组不是sizeof
,_Alignof
或int
的操作数,并且不是用于初始化数组的字符串文字,就会发生此转换。)因此调用正在传递指针到int
,它与作为array
指针的参数匹配。然后参数array[i]
可以用作array[0] = -1
来访问数组元素,因此您可以使用更简单的语法(*array)[0] = -1
而不是{{1}}。
答案 2 :(得分:-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);
然后始终执行此绑定的访问检查。