for循环:if语句中将指针变量作为条件的必要性

时间:2019-08-06 15:51:36

标签: c++ for-loop if-statement

我不明白为什么if语句的条件需要成为一个指针。我假设正常的变量调用不会引起任何投诉。

试图从cppreference了解std :: vector :: erase,对此示例很感兴趣(https://en.cppreference.com/w/cpp/container/vector/erase

#include <vector>
#include <iostream>

int main( )
{
    std::vector<int> c{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    for (auto &i : c) {
        std::cout << i << " ";
    }
    std::cout << '\n';
    // Erase all even numbers (C++11 and later)
    for (auto it = c.begin(); it != c.end(); ) {
        if (*it % 2 == 0) {
            it = c.erase(it); // THE LINE ABOVE THIS
        } else {
            ++it;
        }
    }
    for (auto &i : c) {
        std::cout << i << " ";
    }
    std::cout << '\n';
}

输出

0 1 2 3 4 5 6 7 8 9 
1 3 5 7 9 

希望任何人都可以分享一个解释或将我定向到可用资源。

2 个答案:

答案 0 :(得分:3)

在经典循环中:

auto it = c.begin()-it迭代器。要访问它所引用的内容,您需要取消引用,就像使用*it一样。 *并不表示 pointer ,它的意思是 dereference (从技术上讲,在迭代器上,它是对operator*的调用)。

另请参阅https://en.cppreference.com/w/cpp/iterator

在基于范围的循环中:

for (auto &i : c)-在这里,您直接获得对容器中元素的引用。不涉及迭代器。

答案 1 :(得分:1)

  

基于范围的for循环:将指针变量作为条件的必要性   if语句

我认为困惑在于您错误地考虑了普通的for循环

for (auto it = c.begin(); it != c.end(); )

作为远程循环。

在您的程序中,基于范围的for循环仅用于输出向量。

for (auto &i : c) {
    std::cout << i << " ";
}

迭代器充当指针。例如,为它们定义了operator *operator ++

考虑一个处理数组的类似程序。当然,您不能从数组中删除元素,但可以将“已删除”的元素移到数组的末尾。

这是一个演示程序。

#include <iostream>

int main() 
{
    int a[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    const size_t N = sizeof( a ) / sizeof( *a );

    for ( const int *p = a; p != a + N; ++p )
    {
        std::cout << *p << ' ';
    }
    std::cout << '\n';

    int *q = a;

    for ( const int *p = a; p != a + N; ++p )
    {
        if ( not ( *p % 2 == 0  ) )
        {
            if ( p != q ) *q = *p;
            ++q;
        }
    }

    for ( const int *p = a; p != q; ++p )
    {
        std::cout << *p << ' ';
    }
    std::cout << '\n';

    return 0;
} 

其输出为

0 1 2 3 4 5 6 7 8 9 
1 3 5 7 9 

如您在此if语句中所见

if ( not ( *p % 2 == 0  ) )

您必须取消引用指针才能获得指针所指向的值。

现在使用通用函数std::beginstd::cbeginstd::cend,以以下方式重写程序。

#include <iostream>
#include <iterator>

int main() 
{
    int a[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

    for ( auto p = std::cbegin( a ); p != std::cend( a ); ++p )
    {
        std::cout << *p << ' ';
    }
    std::cout << '\n';

    auto q = std::begin( a );

    for ( auto p = std::cbegin( a ); p != std::end( a ); ++p )
    {
        if ( not ( *p % 2 == 0  ) )
        {
            if ( p != q ) *q = *p;
            ++q;
        }
    }

    for (  auto p = std::begin( a ); p != q; ++p )
    {
        std::cout << *p << ' ';
    }
    std::cout << '\n';

    return 0;
}

现在指针看起来像迭代器,并且if语句中没有任何变化

if ( not ( *p % 2 == 0  ) )