提问者:小点点

经典数组与标准数组


我尝试了这个简单的程序:

int* getElement(int arrayy[], int index) {
     return &arrayy[index];
}

int main() {

    int arrayy[4]{};

    *getElement(arrayy, 2)=50;

    std::cout << arrayy[2] << '\n';// here it prints 50 !

    return 0;
 }

getElement()将通过指针返回返回我的数组的一个元素的地址,在main中取消引用它,然后更改值。

我想用std::array代替经典数组来做同样的事情。

int* getElement(std::array<int, 4> arrayy, int index) {
    return &arrayy[index];
}

int main() {


    std::array<int, 4> arrayy{};

    *getElement(arrayy, 2)=50;

    std::cout << arrayy[2] << '\n';//here it prints 0 !

    return 0;
}

第一个印50,第二个印0!

std::array是否在调用中按值传递?


共3个答案

匿名用户

在通过复制传递指针的情况下,指向的at值在函数和调用站点中是相同的。 所以第一个程序做了您期望的事情。

在第二个程序中,它是不同的,因为std::array具有值语义,因此通过副本传递它意味着您也传递了所有底层内存的副本。 如果想要获得与第一个程序相同的效果,则需要通过引用传递std::array:

int* getElement(std::array<int, 4> &arrayy, int index) {
                                // ^  reference
    return &arrayy[index];
}

注意,在您的第二个程序中的代码中,0的结果是不保证的。 您正在返回一个指针,该指针指向复制的std::array中的一个值,当函数返回时,该值将终止。 这将调用未定义的行为。

匿名用户

缺省情况下,C++中的所有内容都按值传递。 即使是传统的数组示例也会按值传递指针。 当然你可以用指针来改变它所指向的东西。

您的代码实际上具有未定义的行为,因为您返回的指针指向已被销毁的对象的内部,即GetElementarrayy参数,该参数在退出函数时被销毁。

如果要按引用传递,则必须请求引用

int* getElement(std::array<int, 4>& arrayy, int index) {
    return &arrayy[index];
}

参数类型名称后面的&起到了很大的作用。

匿名用户

std::array在调用中是否通过值传递?

是的。 这样做(传递并返回对象)的能力本质上是std::array存在的原因。

因此,函数参数是函数的本地参数,您返回一个指向这个本地对象的指针,一旦函数返回,这个指针就变成了无效指针。