首页 > 解决方案 > 我可以在 C++ 的 for 循环中使用指针吗?

问题描述

我知道我可以在 for 循环中使用任何类型来迭代:

#include <fstream>
#include <iostream>

using namespace std;

int main()
{
    int ar[] ={ 1, 2, 3 };
    for (int i:ar)
    {
        cout << i << endl;
    }
}

但我不能有一个指针类型:

#include <fstream>
#include <iostream>
#include <string>

using namespace std;

int main(int argc, char const *argv[])
{
    for (char *p:argv) //or better char const *p
    // using auto keyword expands to error-type in vscode
    {
        ifstream in(p);
    }

    return 0;
}

会给:

error: ‘begin’ was not declared in this scope
     for (char *p:argv)
error: ‘end’ was not declared in this scope
     for (char *p:argv)
                  ^~~~

所以我假设,c++ for loop 的语法(auto var : vector/array)c-style, old-fashion loop不同for(int i=0; i<size; i++)?因为我需要(在使用 c++ 风格的循环的情况下)提供一个具有有效迭代器的结构(因此错误,寻找 begin() 和 end() 迭代器。但是为什么第一种情况有效?第一种情况,一个带有整数的数组,也是一个没有任何迭代器的结构,但是旧指针(访问)。那么为什么第一个可以,但第二个不行?

标签: c++arraysfor-loopiterator

解决方案


这些样本的差异隐藏在将参数传递给函数的规则中。

在第一个示例中,当您编写 时int ar[] = {1, 2, 3};,类型arint[3]- “一个 3 个整数的数组”。std::begin是为数组定义的,因此代码可以编译并工作。

在第二个示例中,char const *argv[]实际上与 相同 char const **argv,因为在函数参数中,您不能按值传递数组,并且语法[]的编译方式与您使用的完全一样*。显然,没有std::beginfor指针,所以代码不起作用。

要遍历参数,您必须使用普通的 for 循环。例如,

for (int i = 0; i < argc; ++i) {
  char const* arg = argv[i];
};

编辑:只是为了澄清 - 使用基于范围的 for 循环,std::begin(a)并且std::end(a)应该是可调用的并返回一个迭代器。(由于 C++17 并不完全正确 -std::end可以返回与迭代器相当的任何东西,这在 C++20 工作草案中称为哨兵)

如果是具有已知边界的数组(例如int[3]),std::begin则返回指向第一个元素的指针,并std::end返回结束后的指针。C++ 中的 aniterator不必是某个特殊基类的派生类,它只需要具有正确的语义即可。指针也是迭代器


推荐阅读