c++ 数组长度的箭头运算符?打印时无输出,如何?

g9icjywg  于 2023-06-25  发布在  其他
关注(0)|答案(2)|浏览(141)

我有这样一段代码来迭代数组,而不是使用sizeof(array)/sizeof(*array),我使用了箭头运算符(我不太明白它是如何工作的)。
我不明白为什么当我打印出array->length()时,它只是一个空白输出,以及for循环如何工作并在i < array->length()的设置条件下正确终止。

#include <iostream>

using namespace std;

int main() {

    string cars[] = {"Corvette", "Ford", "Mustang"};

    cars[1] = "Camaro", "Ford";
    for (int i = 0; i < cars->length(); i++)
    {
        cout << cars[i] << '\n';
    }

    cout << cars->length();
    return 0;
}
thigvfpy

thigvfpy1#

cars->length()中,数组std::string cars[3]衰减为指向第一个元素的指针。在该指针上使用->可以解除引用,并在第一个元素上调用length()将返回元素的长度(对于“Corvette”是8),而不是数组的大小。
因为你的循环等价于:

for (int i = 0; i < 8; i++)

并且在循环中解引用cars[i],你访问数组越界。数组只有3个元素。这会导致“未定义的行为”,你的程序可能会做任何事情,或者什么都不做,或者崩溃。
这个程序中的另一个问题是逗号运算符的使用:

cars[1] = "Camaro", "Ford";

这将"Camaro"赋给cars[1],但完整表达式的结果是"Ford"。示例:

auto x = (cars[1] = "Camaro", "Ford");

x现在是"Ford",而cars[1]"Camaro"

q5iwbnjs

q5iwbnjs2#

@TedLyngmo已经介绍了这里的问题,以及为什么代码不像看起来那样工作。
我将尝试介绍一些使代码工作的方法。首选的可能是基于range的for循环,如下所示:

for (auto const &car : cars)
    {
        cout << car << '\n';
    }

使用sizeof(array)/sizeof(array[0])的另一个替代方法是这样的:

template <class T, size_t N>
size_t length(T (&array)[N]) {
    return N;
}

有了这个,你可以做一些更像你的原始代码:

for (int i=0; i<length(cars); i++) {
    std::cout << cars[i] << '\n';
}

sizeof(array)/sizeof(array[0])相比,这种方法的最大优势是,如果你有一个指针而不是一个实际的数组,sizeof代码将产生错误的结果,但这根本就不会编译。但是,您通常不希望自己实际定义它--标准库提供了一个std::size,它可以为您完成这项工作,而不必记住通过引用传递数组的语法。
如果我没有提到通常首选的方式是使用std::vector,那我就太失职了:

std::vector<std::string> cars = {"Corvette", "Ford", "Mustang"};

有了这个,你可以使用基于范围的for循环(我上面展示的第一个)或cars.length()--现在可以正常工作了,因为cars是一个vector,它有一个length()成员,返回vector中元素的数量。

相关问题