传递数组,指向C中的int
经过多年与Matlab合作,我是C的新成员。 我有一个构造数组的函数,我需要将它返回到main()。 我有arrays与指针的常见问题,并且通过摆弄想出如何做到这一点。 但是这个小提琴给我留下了一个基于以下代码的概念性问题。
#include void array_set(int y_out[2][2]); void int_set_wrong(int y); void int_set_right(int *y); int main (int argc, const char * argv[]) { int y_array[2][2]={{0,0},{0,0}}; int y_int_1 = 0; int y_int_2 = 0; array_set(y_array); int_set_wrong( y_int_1 ); int_set_right( &y_int_2 ); printf("\nValue array: %d \n",y_array[0][0]); printf("Value int wrong: %d \n",y_int_1); printf("Value int right: %d \n",y_int_2); return 0; } void array_set(int y_out[2][2]){ y_out[0][0] = 10; y_out[1][0] = 20; y_out[0][1] = 1; y_out[1][1] = 2; } void int_set_wrong(int y){ y = 10; } void int_set_right(int * y){ *y = 10; }
上面的代码段返回:值数组:10值int错误:0值int right:10
我的问题在几个部分,
首先,为什么函数’array_set’有效? 我希望它以’int_set_wrong’所做的相同方式失败。
int和int数组如何在传递中区别对待?
此外,在’int_set_wrong’的情况下,是否有本地版本的y?
如果是这样,为什么在设置数组的情况下没有本地版本的y_out?
谢谢您的帮助。 顺便说一句,如果有任何事情会导致我的array_set实现出现问题,请加入。
– 安德鲁
在int_set_right()
您通过运算符&
传递了变量y_int_2
的地址(您在main()
声明和定义)。
int_set_right( &y_int_2 );
由于函数可以通过指针y
访问实际变量y_int_2
(设置为来自&y_int_2
的y_int_2
地址的值), y_int_2
在指定*y = 10
时为y_int_2
指定了值*y = 10
。
您可以将*y = 10
读作:
地址存储在
y
中的变量的值现在设置为10
但对于y_int_1
,您只是传递了该值 。 因此,当您调用int_set_wrong()
时,会创建一个临时变量,该变量已使用int_set_wrong()
的值进行y_int_1
。 所以你所做的就是改变局部变量临时值(本地变为int_set_wrong()
)。
这就是为什么在main()
声明的y_int_1
不受int_set_wrong()
影响。
array_set
有效,因为你通过y_out
变量(在int_set_right
像y
一样指针)将y_out
的地址y_array
给函数。
使用指针传递数组,而不是通过堆栈上的值复制整个数组。 你的二维数组解释了这个棘手,但考虑一维版本:
void f(int x[]){ x[0] = 1; x[1] = 2; }
您可以将其写为:
void f(int *x){ x[0] = 1; x[1] = 2; }
这两个声明是相同的,但我相信你可以看到在第二个版本中进行的修改会传播回调用者。
函数array_set有效,因为当您将数组传递给函数时,您实际上是在传递指针。 然后,在函数内部,您使用“y_out [0] [0] = 10”等取消引用数组。当您使用数组表示法时,它会自动取消引用数组指针,以便您可以在其中设置值数组。
Ints与int数组完全不同。 几乎在每种情况下都可以将数组视为指针,在本例中是指向int的指针。 int是实际数值。 因此,当你将int传递给你的int_set_wrong函数时,它会被复制(这正是C / C ++所做的),并且你设置的是局部变量y,而不是你传入的int。
您的第三个问题也在第一段中得到了回答。 希望这可以解决问题。
你的函数是有效的,因为在C中,函数参数中最内部的[]
(只有!)相当于一个指针参数。 你的声明相当于
void array_set(int (*y_out)[2]){ .. }
那就是y_out
是指向int[2]
的指针。
你已经创建了3个function。
array_set(y_array);
在此之前,您已使用该行创建了一个数字数组。
int y_array[2][2]={{0,0},{0,0}};
在C中,当您声明一个数组时,您在代码中创建了一个名为y_array
的指针,该数组存储在内存中的某个位置,指针指向该位置的位置。
所以基本上它是一个正常的指针,后面分配了大量的内存。
当您传递数组以节省内存时,默认情况下,时间C传递指针。
void int_set_wrong(int y);
当你传递一个int
它会将值复制到一个局部变量,你不会在该函数之外保存该变量的任何地址。
传递int
的引用时,为函数提供int
变量的地址。 结果,该function可以在那里进行更改。
由于第一个和第三个调用是共享主变量的位置,您可以看到主变量的变化。 对于第二个,没有共享地址。 因此该函数创建了自己的变量,无法从外部访问。