如何迭代通过c ++中的数字列表 [英] How to iterate through a list of numbers in c++
问题描述
如何迭代一个数字列表,有多少种不同的方法呢?
我认为会有效:
#include< cstdlib>
#include< iostream>
#include< list>
使用namespace std;
int main()
{
int numbers [] = {2,4,6,8}
int i = 0;
for(i = 0; i< numbers.size(); i ++)
cout< 当前数字是<数字[i];
系统(暂停);
return 0;
}
我在for循环行上遇到错误:在 'numbers'中为成员
'size'
请求
与许多现代语言不同,纯C ++数组没有 .size()
函数。
一些常见的存储选项包括:
//用于固定大小的存储。需要#include< array>
std :: array< type,size>采集;
//用于动态大小的存储。需要#include< vector>
std :: vector< type>采集;
//动态存储。一般来说:更慢的迭代,更快的插入
//需要#include< list>
std :: list< type>采集;
//旧式C数组
int myarray [size];
您的迭代选项将取决于您使用的类型。如果你使用一个普通的老C数组,你可以存储其他地方的大小或计算数组的大小基于它的类型的大小。 计算数组的大小具有DevSolar在此答案中概述的许多缺点
//将值存储为常量
int oldschool [10];
for(int i = 0; i <10; ++ i){
oldschool [i]; // Get
oldschool [i] = 5; // set
}
//计算数组的大小
int size = sizeof(oldschool)/ sizeof(int);
for(int i = 0; i oldschool [i]; // Get
oldschool [i] = 5; // Set
}
如果您使用任何类型提供 .begin()
和 .end()
函数可以使用这些函数来获得一个迭代器,基于索引的迭代:
//也可以是一个数组,列表或任何与begin $ b std :: vector< int>新学校;
//定期迭代器,非C ++ 11
for(std :: vector< int> :: iterator num = newschool.begin(); num!= newschool.end ); ++ num){
int current = * num; // *获取迭代器的数字
* num = 5; //设置数字。
}
//更好的语法,使用auto!自动获取正确的迭代器类型(C ++ 11)
for(auto num = newschool.begin(); num!= newschool.end(); ++ num){
int current = ; // As above above
* num = 5;
}
// std :: for_each也可用
std :: for_each(newschool.begin(),newschool.end(),function_taking_int);
// std :: for_each with lambdas(C ++ 11)
std :: for_each(newschool.begin(),newschool.end(),[]
//只需使用i,不能修改
});
向量也是特殊的,因为它们被设计为数组的替换。你可以用一个 .size()
函数来完成一个向量的迭代。但是这在C ++中被认为是不好的做法,你应该更喜欢在可能的地方使用迭代器:
std :: vector< int&坏习惯
for(int i = 0; i< badpractice.size(); ++ i){
badpractice [i]; // Get
badpractice [i] = 5; // Set
}
C ++ 11并且基于这个的花梢范围应该适用于提供 .begin()
和 .end()
的任何类型。但是:此功能的编译器支持可能有所不同。您还可以使用 begin(type)
和 end(type)
。
std :: array< int,10>花哨
for(int i:fancy){
//只是使用i,不能修改。
}
// begin / end requires #include< iterator>也包括在大多数容器头文件中。
for(auto num = std :: begin(fancy); num!= std :: end(fancy); ++ num){
int current = * num; // Get
* num = 131; // Set
}
std :: begin
也有另一个有趣的属性:它工作原始数组。这意味着你可以在数组和非数组之间使用相同的迭代语义(你应该仍然喜欢标准类型与原始数组):
int raw [10];
for(auto num = std :: begin(raw); num!= std :: end(raw); ++ num){
int current = * num; // Get
* num = 131; // Set
}
如果您要删除项目,因为调用 container.erase()
会使所有现有的迭代器无效:
std :: vector< int>数字;
for(auto num = numbers.begin(); num!= numbers.end(); / *故意为空* /){
...
if(someDeleteCondition ){
num = numbers.erase(num);
} else {
//没有删除,没有问题
++ num;
}
}
这份清单并不全面,有很多方法来迭代一个集合。一般来说,喜欢迭代器,除非你有很好的理由不这样做。
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:
request for member
'size'
in'numbers'
, which is of non-class type'int[4]'
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.
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
// 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:
// 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:
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.
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):
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:
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.
这篇关于如何迭代通过c ++中的数字列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!