繁体   English   中英

函数参数中的 C++ 数组指针

[英]C++ Array Pointer in Function Parameters

有人可以向我解释这些功能如何/为什么相同吗?

void doubleArray(int* values, int length)

void doubleArray(int values[], int length)

我无需更改任何内容即可使我的代码仍然完全相同,但我不确定逻辑。 我希望至少必须更改函数中写入的内容。 如果需要,完整代码如下;

  #include <iostream>

    using std::cout;
    using std::endl;

void doubleArray(int* values, int length);

int main() {

    int length = 10;
    int values[length];

    for (int i = 0; i < length; i++){
        values[i] = i;
    }

    doubleArray(values, length);

    for (int i = 0; i < length; i++) {
      cout << values[i] << endl;
   }

}

void doubleArray(int* values, int length) {
    for(int i = 0; i < length; i++){
        values[i] = values[i] * 2;
    }
}

https://en.cppreference.com/w/cpp/language/function#Parameter_list

参数列表中每个函数参数的类型根据以下规则确定:

[..]

2) 如果类型是“T 的数组”或“T 的未知边界数组”,则替换为“指向 T 的指针”类型

[..]

由于这些规则,以下函数声明声明了完全相同的函数:

 int f(char[]); int f(char* s); int f(char* const); int f(char* volatile s);

为什么它们是一样的? 因为那是 C++ 的规则(它继承自 C)。

C 的设计者认为能够将数组传递给函数是一个坏主意。 他们认为最好将指针传递给数组的第一个元素。 有问题(在我看来)。

但他们也决定不想取消函数参数声明中的数组语法。 因此他们决定,当用作函数参数时,数组形式T param[]只是编写指针形式T* param的另一种方式。 如果您为数组指定大小(被忽略),它甚至是相同的, T param[10]也是一个指针。 更值得怀疑(在我看来)。

在 C++ 中,您可以通过使用std::vectorstd::array来避免这一切。 在 C 中,你就没有那么幸运了。

假设我们声明了一个int数组:

int values[10];

堆栈上分配了 10 个整数的内存块,变量values包含该内存块开头的地址,或者换句话说,数组的第零个元素的地址,它们是相同的事物。

因此

&values[0] == values

永远是真的。

类似地,这两个语句正在处理相同的元素

cout << values[5];
cout << *(values + 5);

因此,如果我们有一个函数参数(或任何其他变量),它可以声明为int*int[]并且两者都将接受values ,因为这两种声明都只是声明同一事物的替代方法 - 一个指针。 .

这可能会引起混淆,因为这两个对foo()调用都是有效的:

void foo (int[] vals);

int values[10];
foo (values); // Passing an array

int x = 0;
int* px = &x:
foo (px);     // Passing a single object by address

所以作为一个风格问题,如果一个函数需要一个数组,它应该使用( int[] )的数组和一个长度。 如果它需要一个单一的对象,它应该采用一个指针( int* )。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM