我们什么时候需要将数组的大小作为参数传递
我对在 C/C++ 中传递数组有点困惑.我看到了一些签名是这样的情况
I am a little bit confused about pass an array in C/C++. I saw some cases in which the signature is like this
void f(int arr[])
有些是这样的
void f(int arr[], int size)
谁能详细说明有什么区别以及何时以及如何使用它?
Could anybody elaborate what's the difference and when and how to use it?
推荐答案
首先,传递给函数的数组实际上传递的是指向数组第一个元素的指针,例如,如果你有
First, an array passed to a function actually passes a pointer to the first element of the array, e.g., if you have
int a[] = { 1, 2, 3 };
f(a);
然后,f()
将 &a[0]
传递给它.因此,在编写函数原型时,以下内容是等效的:
Then, f()
gets &a[0]
passed to it. So, when writing your function prototypes, the following are equivalent:
void f(int arr[]);
void f(int *arr);
这意味着数组的大小丢失了,而f()
,一般情况下是无法确定大小的.(这就是我更喜欢 void f(int *arr)
形式而不是 void f(int arr[])
的原因.)
This means that the size of the array is lost, and f()
, in general, can't determine the size. (This is the reason I prefer void f(int *arr)
form over void f(int arr[])
.)
f()
有两种情况不需要信息,在这两种情况下,不需要额外的参数就可以了.
There are two cases where f()
doesn't need the information, and in those two cases, it is OK to not have an extra parameter to it.
首先,arr
中有一些特殊的、商定的值,调用者和 f()
都认为这意味着结束".例如,人们可以同意值 0
表示完成".
First, there is some special, agreed value in arr
that both the caller and f()
take to mean "the end". For example, one can agree that a value 0
means "Done".
然后可以写:
int a[] = { 1, 2, 3, 0 }; /* make sure there is a 0 at the end */
int result = f(a);
并定义 f()
类似:
int f(int *a)
{
size_t i;
int result = 0;
for (i=0; a[i]; ++i) /* loop until we see a 0 */
result += a[i];
return result;
}
显然,上述方案只有在调用方和被调用方都同意并遵守约定时才有效.一个例子是 C 库中的 strlen()
函数.它通过查找 0
来计算字符串的长度.如果您传递的内容最后没有 0
,则所有赌注都将关闭,您将处于未定义的行为领域.
Obviously, the above scheme works only if both the caller and the callee agree to a convention, and follow it. An example is strlen()
function in the C library. It calculates the length of a string by finding a 0
. If you pass it something that doesn't have a 0
at the end, all bets are off, and you are in the undefined behavior territory.
第二种情况是当您实际上没有数组时.在这种情况下, f()
接受一个指向对象的指针(在您的示例中为 int
).所以:
The second case is when you don't really have an array. In this case, f()
takes a pointer to an object (int
in your example). So:
int change_me = 10;
f(&change_me);
printf("%d
", change_me);
与
void f(int *a)
{
*a = 42;
}
很好:f()
无论如何都不会对数组进行操作.
is fine: f()
is not operating on an array anyway.
相关文章