在这种情况下,为什么使用范围for循环会比使用常规for循环产生不同的输出?

Bal*_*sök 1 c++ loops for-loop vector output

我想实现的目标

我打算读取输入,然后使用cout按输入顺序写出数字,并用“,”分隔,最后一个数字除外,后者以“ \ n”结尾。如果未在其中插入整数/浮点字符,则读取结束形式为cin

工作代码

#include <iostream>
#include <vector>

int main()
{
    std::cout << "Please enter double values. Enter an alphabetic character to stop reading in values.\n";

    std::vector<double> val;
    for (auto cur_val{ 0 }; std::cin >> cur_val;) {
        val.push_back(cur_val);
    }

    std::cout<<"Your values were:";for(auto i{0};i<val.size();i++)
    {
        if(i!=val.size() && i!=val.size()-1)std::cout<<val[i]<<", ";
        if(i==val.size()-1)std::cout<<val[i]<<'\n';
    }

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

此代码的输出为3,4,5'\ n',这很好。

代码无法正常工作

#include <iostream>
#include <vector>

int main()
{
    std::cout << "Please enter double values. Enter an alphabetic character to stop reading in values.\n";

    std::vector<double> val;
    for (auto cur_val{ 0 }; std::cin >> cur_val;) {
        val.push_back(cur_val);

        std::cout << "Your values were:";

        for (unsigned int i : val) {
            if (i != val[val.size()] && i != val[val.size()] - 1)
                {std::cout << i << ", ";}
            if (i == val[val.size()]){std::cout << i << '\n';}
        }

        return 0;
    }
Run Code Online (Sandbox Code Playgroud)

此代码的输出是3,4,5,,这不好。

Vla*_*cow 6

i 声明为整数,因此此比较

if(i!=val[val.size()] ...
Run Code Online (Sandbox Code Playgroud)

没有意义,并且具有未定义的行为,因为向量在位置处不包含元素val.size()。有效索引范围是[ 0, size() )

向量存储双精度而不是整数。

通常,当您还需要索引时,基于范围的循环不适合。

因此,您需要再添加一个变量,该变量将发出信号,例如当前值是第一个还是最后一个值。

您可以通过以下方式编写循环

    bool first = true;        
    for ( const auto &item : val ) 
    {
        if ( !first ) std::cout << ", ";
        else first = false;

        std::cout << item;
    }
    std::cout << '\n';
Run Code Online (Sandbox Code Playgroud)

或者使用您的想法,只需编写像

    for ( const auto &item : v )
    {
        std::cout << item;
        std::cout << ( item == v[v.size() - 1] ? "\n" : ", " );
    }
Run Code Online (Sandbox Code Playgroud)

这是一个示范节目

#include <iostream>
#include <vector>

int main() 
{
    std::vector<double> v = { 1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9 };

    for ( const auto &item : v )
    {
        std::cout << item;
        std::cout << ( item == v[v.size() - 1] ? "\n" : ", " );
    }

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

它的输出是

1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9
Run Code Online (Sandbox Code Playgroud)

考虑到只要向量的最后一个元素不等于最后一个元素之前的任何其他元素,这种方法就可以工作。