这给我带来了很大的困惑。
如果我有以下数组:
int arr[6];
// I then fill indices 0-5 with ints
我想把它传递给一个使用数组作为参数的函数,函数头是什么样的?
是void saveArray(int *arr)
还是void saveArray (int arr)
?然后我将如何调用该函数? saveArray(arr)
或saveArray(&arr)
?
据我了解,虽然初始数组不是指针,但它有效地作为一个指针,因为它衰变成指向第一个元素的指针。所以我的直觉是我应该像saveArray(arr)
那样传递它,标题应该是void saveArray(int *arr)
。那是对的吗?
为什么我需要一个指向初始数组的指针而不仅仅是数组本身? &arr
甚至代表什么?
答案 0 :(得分:3)
在C中,函数中传递的参数只能通过值传递。
除此之外,在C中,您不能将数组作为参数传递给函数。但是,您可以通过值传递指向数组的第一个单元格的指针。
因此,您的功能原型将是:
void saveArray(int *arr)
你打电话
saveArray(arr);
答案 1 :(得分:1)
是
void saveArray(int * arr)
但是为了它有用,也传递数组长度。
void saveArray(int *arr, int len)
否则你怎么知道它有多长?
然后像这样打电话:
saveArray(arr, 6);
答案 2 :(得分:1)
为什么我需要一个指向初始数组的指针而不仅仅是数组 本身?
那是因为你无法将数组传递给函数。与int
,float
,struct
等不同,数组不是C中的第一类对象。这意味着数组不会复制到函数参数中。实际传递的是指向数组第一个元素的指针。因此,函数参数应该是指向数组元素类型的指针。此外,您必须传递数组的长度才能起作用,因为函数中的信息不能从传递给它的指针中获得。
数组与指针的类型不同。在某些情况下,它会衰减或隐式转换为指向其第一个元素的指针。因此,您的函数应该具有原型
void saveArray(int *arr, int len);
// or
void saveArray(int arr[], int len);
// in main, for example
int arr[6];
saveArray(arr, sizeof arr);
// equivalent to
saveArray(&arr[0], sizeof arr);
&arr
甚至代表什么?
address of
运算符&
计算其操作数的地址,该地址必须是lvalue
。此处arr
的类型为int[6]
,即6
整数数组。因此&arr
的类型为int (*)[6]
,即指向6
整数数组的指针。请注意,值&arr
等于数组的基址,但其类型不是int *
。它是一种不同的类型,具有不同的指针算法。实际上,这是数组不会衰减成指向其第一个元素的指针的情况之一。
答案 3 :(得分:0)
问题"它是否无效saveArray(int *arr)
或void saveArray (int arr)
?"已经回答了。我将回答问题" &arr
甚至代表什么?"
在您的情况下,&arr
与&arr[0]
具有相同的数值。但是,如果你做了一些不同的事情,
int* arr = malloc(sizeof(int)*6);
然后,&arr
的数值将与&arr[0]
的数值不同,即使您可以调用saveArray(arr)
,但两种情况的含义没有任何差异。
在第一种情况下,&arr
和&arr[0]
都是堆栈中的地址。
在第二种情况下,&arr
是堆栈上的地址,而&arr[0]
是堆中的地址。
希望有所帮助。
答案 4 :(得分:0)
如果你使用这个原型:
void saveArray(int *arr)
您丢失了有关数组长度的信息(例如元素数量)。
除非您的函数应该在固定长度的数组上运行(例如,某些执行3D数学计算的函数可能只考虑3D矢量,固定大小为3 double
个元素),应指定数组长度(例如元素计数)作为附加参数:
void saveArray(int * arr, int count);
如果您的函数只是观察输入数组的内容并且不修改它,您可以使用const
使您的代码保持正确并且更精确:
void saveArray(const int * arr, int count);
有时size_t
用作指定长度/计数参数的类型:
void saveArray(const int * arr, size_t count);
关于您在问题中列出的其他选项:
void saveArray(int arr)
这是错误的,因为在这种情况下arr
只是一个整数(不是数组)。
相反,在传递[const] int*
的第一个(正确)情况下,您传递了数组中第一个项的地址,并且由于数组元素存储在连续的内存位置,只有第一个的地址item 和 item count 定义整个数组。
在通话网站,你可以这样调用你的功能:
int arr[<<some size here>>];
...
saveArray(arr, <<same size as above>>);
或者如果你已经有一个指针(例如,因为你使用malloc()
分配了数组),你可以只指定指针本身:
int* arr;
arr = malloc( numberOfElements * sizeof(int) );
...
saveArray(arr, numberOfElements);