在C ++中增强了FOR循环
我正在从Java切换到C ++,我想知道C ++是否包含我在java中使用的增强for循环,例如:
int[] numbers = {1,2,3,4,5,6,7,8,9,10}; for (int item : numbers) { System.out.println("Count is: " + item); }
这是相同的“捷径”可能在C + +?
在C ++ 11中,如果你的编译器支持它,是的。 这就是所谓的基于范围的。
std::vector<int> v; // fill vector for (const int& i : v) { std::cout << i << "\n"; }
它适用于C风格的数组和任何具有返回迭代器的函数begin()
和end()
。 例:
class test { int* array; size_t size; public: test(size_t n) : array(new int[n]), size(n) { for (int i = 0; i < n; i++) { array[i] = i; } } ~test() { delete [] array; } int* begin() { return array; } int* end() { return array + size; } }; int main() { test T(10); for (auto& i : T) { std::cout << i; // prints 0123456789 } }
C ++ 11呢。 他们被称为基于范围的fors。 请记住,您应该将该types限定为对const的引用或引用。
C ++ 03的解决方法是BOOST_FOR_EACH或boost :: bind与std :: for_each结合使用。 Boost.Lambda可能更多花哨的东西。 如果你有心情挫败自己或你的同事,我build议不推荐的粘合剂std::bind1st
和std::bind2nd
。
以下是一些示例代码:
#include <iostream> #include <vector> #include <algorithm> #include <iterator> #include <boost/lambda/lambda.hpp> #include <functional> int main() { int i = 0; std::vector<int> v; std::generate_n(std::back_inserter(v), 10, [&]() {return i++;}); // range-based for // keep it simple for(auto a : v) std::cout << a << " "; std::cout << std::endl; // lambda // i don't like loops std::for_each(v.begin(), v.end(), [](int x) { std::cout << x << " "; }); std::cout << std::endl; // hardcore // i know my lib std::copy(v.begin(), v.end(), std::ostream_iterator<int>(std::cout, " ")); std::cout << std::endl; // boost lambda // this is what google came up with // using for the placeholder, otherwise this looks weird using namespace boost::lambda; std::for_each(v.begin(), v.end(), std::cout << _1 << " "); std::cout << std::endl; // fold // i want to be a haskell programmer std::accumulate(v.begin(), v.end(), std::ref(std::cout), [](std::ostream& o, int i) -> std::ostream& { return o << i << " "; }); return 0; }
在C ++ 03中没有这种可能性。 然而新的标准(C ++ 11)确实有它。 看例子(摘自维基百科 ):
int my_array[5] = {1, 2, 3, 4, 5}; for (int &x : my_array) { x *= 2; }
考虑也使用std::vector<int>
而不是普通的数组。 这是C数据types的C ++类比,这使得生活更轻松。
是和不是。
1.本地数组:不,但您可以轻松find大小
如果你有一个本地数组( int numbers[4] = {1, 2, 3, 4];
那么你可以做size = sizeof(numbers) / sizeof(int)
。
2.指向数组的指针:完全不需要,你必须单独传递大小
如果你有一个指向数组的指针( int* numbers = new int[4];
),那么除非你自己跟踪它,否则你不能确定它的大小。 (或者如果它在空string的情况下终止,但你必须遍历它是线性运行时间…)
请注意,我不相信指向数组的指针是正确的术语,实际上你只是有一个指向数组的第一个元素的指针,但是已经分配了多个值的空间。 不知道这是叫什么。 也许只是一个指针?
3. STL容器:是的,你可以使用迭代器做一些循环魔术,或者通过获取大小来使用索引
如果你有一个向量( std::vector<int> v(3, 0);
),你可以通过下面的方法遍历它:
C ++ 11:
auto it = v.begin(); for (auto it = v.begin(); it != v.end(); it++) { UseElement(*it); }
或者显然(也是C ++ 11,谢谢jrok):
for (const int& i : v) { UseElement(i); }
C ++(pre-11):
std::vector<int>::iterator it; for (it = v.begin(); it != v.end(); it++) { UseElement(*it); }
或者使用索引:
for (int i = 0; i < v.size(); i++) { UseElement(v[i]); }
此外,你可以使用stdalgorithm的for_each( #include <algorithm>
)来使用STL容器的函数指针或函子,如下所示:
void foo(int i) { std::cout << i; } { std::for_each(myvector.begin(), myvector.end(), foo); }
其他人已经提到,这个循环风格是在C ++ 11中添加的。 但是,C ++ 11更好:
for (auto const& item: numbers) { std::cout << "Count is: " << item << '\n'; }
这样,如果以后将numbers
的元素types从int
更改为long
,或者甚至更改为您自己编写的某个bigint
类,则根本不需要更改该循环。
在旧标准C ++ 03(从2003年开始)中,该语言没有内置的对这种for-loop的支持。 有一些你可以使用Boost,但是这是不值得包括一个全新的图书馆这个小便利function。
在新标准C ++ 11(去年夏天发布)中,这是可能的。 语法如下所示:
MyType array[] = { ... } for (MyType& x : array) { ... }
请注意,我正在使用MyType& x
,而不是MyType x
。 在Java中,一切都是参考。 在C ++中,引用必须是明确的,并且使用&
声明它们。 如果你不使用引用,for循环会将数组的每个元素复制到x
(这可能是昂贵的)。
但是,大多数编译器还没有完全支持C ++ 11。 我认为微软的Visual C ++支持这个function,但我不确定。
我发现这个简单的macros非常有用。 我for
循环的绝大多数涉及遍历一个STL容器:
#define For(it, container) for( typeof((container).begin()) it = (container).begin(); it != (container).end(); ++it)
一个例子:
vector<int> vector_of_ints; ... // initialize it somehow For(integer, vector_of_ints) { cout << *integer << endl; }
有两点需要注意:首先,它是一个迭代器,因此您必须对其进行解引用。 其次, For
的第二个参数将被多次评估。 我已经玩过其他的方法,但我一直回到简单的这个。