如何在 C++ 中遍历数字列表
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14350886/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to iterate through a list of numbers in c++
提问by Dbz
How do I iterate through a list of numbers, and how many different ways are there to do it?
如何遍历数字列表,有多少种不同的方法可以做到这一点?
What I thought would work:
我认为会起作用的:
#include <cstdlib>
#include <iostream>
#include <list>
using namespace std;
int main()
{
int numbers[] = {2, 4, 6, 8};
int i = 0;
for(i=0; i< numbers.size();i++)
cout << "the current number is " << numbers[i];
system("pause");
return 0;
}
I get an error on the for loop line:
我在 for 循环行上收到错误消息:
request for member
'size'
in'numbers'
, which is of non-class type'int[4]'
请求成员
'size'
in'numbers'
,这是非类类型'int[4]'
回答by Jake Woods
Unlike a lot of modern languages plain C++ arrays don't have a .size()
function. You have a number of options to iterate through a list depending on the storage type.
与许多现代语言不同,普通的 C++ 数组没有.size()
函数。根据存储类型,您有多种选项可以遍历列表。
Some common options for storage include:
一些常见的存储选项包括:
// used for fixed size storage. Requires #include <array>
std::array<type, size> collection;
// used for dynamic sized storage. Requires #include <vector>
std::vector<type> collection;
// Dynamic storage. In general: slower iteration, faster insert
// Requires #include <list>
std::list<type> collection;
// Old style C arrays
int myarray[size];
Your options for iteration will depend on the type you're using. If you're using a plain old C array you can either store the size somewhere else or calculate the size of the array based on the size of it's types. Calculating the size of an array has a number of drawbacks outlined in this answer by DevSolar
您的迭代选项将取决于您使用的类型。如果您使用的是普通的旧 C 数组,则可以将大小存储在其他地方,也可以根据数组类型的大小计算数组的大小。DevSolar 在这个答案中概述了计算数组的大小有许多缺点
// Store the value as a constant
int oldschool[10];
for(int i = 0; i < 10; ++i) {
oldschool[i]; // Get
oldschool[i] = 5; // Set
}
// Calculate the size of the array
int size = sizeof(oldschool)/sizeof(int);
for(int i = 0; i < size; ++i) {
oldschool[i]; // Get
oldschool[i] = 5; // Set
}
If you're using any type that provides a .begin()
and .end()
function you can use those to get an iterator which is considered good style in C++ compared to index based iteration:
如果您使用任何提供 a.begin()
和.end()
函数的类型,您可以使用它们来获取迭代器,与基于索引的迭代相比,该迭代器在 C++ 中被认为是良好的风格:
// Could also be an array, list, or anything with begin()/end()
std::vector<int> newschool;
// Regular iterator, non-C++11
for(std::vector<int>::iterator num = newschool.begin(); num != newschool.end(); ++num) {
int current = *num; // * gets the number out of the iterator
*num = 5; // Sets the number.
}
// Better syntax, use auto! automatically gets the right iterator type (C++11)
for(auto num = newschool.begin(); num != newschool.end(); ++num) {
int current = *num; // As above
*num = 5;
}
// std::for_each also available
std::for_each(newschool.begin(), newschool.end(), function_taking_int);
// std::for_each with lambdas (C++11)
std::for_each(newschool.begin(), newschool.end(), [](int i) {
// Just use i, can't modify though.
});
Vectors are also special because they are designed to be drop-in replacements for arrays. You can iterate over a vector exactly how you would over an array with a .size()
function. However this is considered bad practice in C++ and you should prefer to use iterators where possible:
向量也很特别,因为它们被设计为阵列的直接替代品。您可以完全按照使用.size()
函数遍历数组的方式遍历向量。然而,这在 C++ 中被认为是不好的做法,你应该尽可能使用迭代器:
std::vector<int> badpractice;
for(int i = 0; i < badpractice.size(); ++i) {
badpractice[i]; // Get
badpractice[i] = 5; // Set
}
C++11 (the new standard) also brings the new and fancy range based for that should work on any type that provides a .begin()
and .end()
. However: Compiler support can vary for this feature. You can also use begin(type)
and end(type)
as an alternative.
C++11(新标准)还带来了新的和奇特的范围,它应该适用于提供 a.begin()
和 的任何类型.end()
。但是:此功能的编译器支持可能会有所不同。您也可以使用begin(type)
和end(type)
作为替代方案。
std::array<int, 10> fancy;
for(int i : fancy) {
// Just use i, can't modify though.
}
// begin/end requires #include <iterator> also included in most container headers.
for(auto num = std::begin(fancy); num != std::end(fancy); ++num) {
int current = *num; // Get
*num = 131; // Set
}
std::begin
also has another interesting property: it works on raw arrays. This means you can use the same iteration semantics between arrays and non-arrays (you should still prefer standard types over raw arrays):
std::begin
还有另一个有趣的特性:它适用于原始数组。这意味着您可以在数组和非数组之间使用相同的迭代语义(您仍然应该更喜欢标准类型而不是原始数组):
int raw[10];
for(auto num = std::begin(raw); num != std::end(raw); ++num) {
int current = *num; // Get
*num = 131; // Set
}
You also need to be careful if you want to delete items from a collection while in a loop because calling container.erase()
makes all existing iterators invalid:
如果您想在循环中从集合中删除项目,您还需要小心,因为调用container.erase()
会使所有现有的迭代器无效:
std::vector<int> numbers;
for(auto num = numbers.begin(); num != numbers.end(); /* Intentionally empty */) {
...
if(someDeleteCondition) {
num = numbers.erase(num);
} else {
// No deletition, no problem
++num;
}
}
This list is far from comprehensive but as you can see there's a lot of ways of iterating over a collection. In general prefer iterators unless you have a good reason to do otherwise.
这个列表并不全面,但正如您所看到的,有很多迭代集合的方法。一般来说,除非您有充分的理由不这样做,否则更喜欢迭代器。
回答by Robin Chander
Change you for loop to
将您的 for 循环更改为
for(i=0; i< sizeof(numbers)/sizeof(int);i++){
In simple words,
sizeof(numbers)
mean number of elements in your array * size of primitive type int, so you divide by sizeof(int)
to get the number of elements
简单来说,
sizeof(numbers)
意思是数组中的元素数 * 原始类型 int 的大小,因此您除以sizeof(int)
得到元素数
回答by Yuushi
If you fix it so that it's list<int> numbers = {1,2,3,4}
:
如果你修复它,它是list<int> numbers = {1,2,3,4}
:
Iterating through using iterators:
通过使用迭代器进行迭代:
#include <iterator>
for(auto it = std::begin(numbers); it != std::end(numbers); ++it) { ... }
Iterating through using std::for_each
:
迭代使用std::for_each
:
#include <algorithm>
#include <iterator>
std::for_each(numbers.begin(), numbers.end(), some_func);
Utilizing a for-each loop (C++11):
使用 for-each 循环 (C++11):
for(int i : numbers) { ... }
回答by dasblinkenlight
There is no size
function on "plain" C-style arrays. You need to use std::vector
if you want to use size
, or calculate size through sizeof
.
size
“普通”C 样式数组没有函数。您需要使用std::vector
,如果你想使用size
经过,或计算大小sizeof
。
In C++11 you can use array initialization syntax to initialize your vectors, like this:
在 C++11 中,您可以使用数组初始化语法来初始化您的向量,如下所示:
vector<int> numbers = {2, 4, 6, 8};
Everything else stays the same (see demo here).
其他一切都保持不变(请参阅此处的演示)。
回答by user1346466
You can also use the plain old C containers anduse the iterator syntax for the loop:
您还可以使用普通的旧 C 容器并为循环使用迭代器语法:
#include <iostream>
int main()
{
int numbers[] = {2, 4, 6, 8};
int *numbers_end = numbers + sizeof(numbers)/sizeof(numbers[0]);
for (int *it = numbers; it != numbers_end; ++it)
std::cout << "the current number is " << *it << std::endl;
return 0;
}
回答by einpoklum
The easiest way to do it, in my opinion, would be to use a span.
在我看来,最简单的方法是使用span。
#include <cstdlib>
#include <iostream>
#include <gsl/span>
int main() {
int numbers[] = {2, 4, 6, 8};
for(auto& num : gsl::span(numbers)) {
cout << "the current number is " << num;
}
system("pause");
}
Notes:
笔记:
- Spans are part of the GSL library. To use them, download the library from here, and add the download path to the compilation command, e.g.
g++ -o foo foo.cpp -I/path/to/gsl
- In C++20,
span
will be part of the standard, so you would just usestd::span
and#include <span>
.
- Span 是 GSL 库的一部分。要使用它们,请从这里下载库,并将下载路径添加到编译命令中,例如
g++ -o foo foo.cpp -I/path/to/gsl
- 在 C++20 中,
span
将成为标准的一部分,因此您只需使用std::span
和#include <span>
。
回答by Antonin GAVREL
I didn't see it among the answers but this is imo the best way to do it: Range-based for loop
我没有在答案中看到它,但这是最好的方法:Range-based for loop
It is safe, and in fact, preferable in generic code, to use deduction to forwarding reference:
for (auto&& var : sequence).
使用推导来转发引用是安全的,事实上,在泛型代码中更可取:
for (auto&& var : sequence)。
Minimalist and working example :
极简主义和工作示例:
#include <list>
#include <iostream>
int main()
{
std::list<int> numbers = {2, 4, 6, 8};
for (const int & num : numbers)
std::cout << num << " ";
std::cout << '\n';
return 0;
}
回答by KamikazeCZ
There is no member function "size" because "numbers" isn't a class. You can not get the array's size this way, you must either know it (or compute it) or use some class to store your numbers.
没有成员函数“size”,因为“numbers”不是一个类。您无法通过这种方式获得数组的大小,您必须知道它(或计算它)或使用某个类来存储您的数字。