我们什么时候需要将数组的大小作为参数传递

2021-12-29 00:00:00 arrays c parameters c++

我对在 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.

相关文章