第9章:statements

来源:互联网 发布:开挂软件 编辑:程序博客网 时间:2024/05/20 09:47

相比于c++98的老标准,c++11新标准增加了范围for语句(range for statement)。
范围for语句的语法形式为:

for (declaration:expression)    statement

expression表示的必须是一个序列,比如用花括号括起来的初始值列表,数组,或者vector和string等类型的对象。这些类型共有的一个特点是拥有能返回迭代器的begin()和end()成员

declaration定义一个变量,序列中的每个元素都得转换成该变量的类型。确保类型相容的最简单办法是使用auto类型说明符,这个关键字可以令编译器帮助我们找到指定合适的类型。如果对元素执行写操作,必须要定义成引用,当然如果对于一个类型来说,元素的复制太昂贵的话,也要定义成引用,以节省运行时间。

每次迭代都会重新定义循环控制变量,并将其初始化为序列中的一个值,之后才会执行statement,所有元素处理完毕后循环终止。

以下面的代码为例,其目的是输出一个vector类型元素的值

vector<int> v1={1,2,3,4,5,6,7,8,9};for(auto x:v1)    cout<<x<<" ";cout<<endl;

在这个例子中,v1是一个序列,因为vector有begin()和end()成员,auto x 代表declaration,定义了一个变量,每次执行时都会用v1中的元素来给变量x赋值。当v1中所有元素都输出完之后循环终止,再执行语句cout<<endl。其实上述的代码等价成如下代码:

vector<int> v1={1,2,3,4,5,6,7,8,9};for(auto beg=v1.begin(),end=v1.end();beg!=end;++beg){    auto x=*beg;    cout<<x<<" ";}cout<<endl;

从上面的等价代码中我们可以得出另外一个结论:不能通过范围for循环语句给容器增减元素,因为在范围for循环语句中预存了该序列end()的值,一旦我们给容器增减元素,就可能会导致该序列中end()函数的值发生改变,这就导致范围for循环语句中之前预存的end()函数的值就失效了。

如果我们想要改变序列中元素的值,我们要给变量定义成引用,如下面的代码例子所示:

vector<int> v1={1,2,3,4,5,6,7,8,9};for(auto& x:v1)    x*=2;

当然如果我们不想改变一个序列中元素的值,但元素的复制太昂贵,这样我们也可以定义成引用,如下面代码例子所示:

//假设vector<string> v1中存储的字符串很长for(const auto&x: v1)    cout<<x<<" ";cout<<endl;
0 0
原创粉丝点击