前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >范围for语句的整理

范围for语句的整理

作者头像
Enterprise_
发布2019-02-21 17:18:19
7950
发布2019-02-21 17:18:19
举报
文章被收录于专栏:小L的魔法馆

1.如何处理stirng中的每个字符?(来自C++Primer中文版5th中P83)

使用基于范围的for语句,比如下面的例子,输出每个字符

代码语言:javascript
复制
#include<iostream>
#include<string>
using namespace std;
int main(void)
{
    string s("Hello world!!!");
    for (auto c : s)
        cout<<c<<endl;
    return 0;
}

2.修改序列中的元素,必须将循环变量申明为引用类型(来自C++Primer中文版5th中P83)

下面将整个string字符改写成大写,然后输出。

代码语言:javascript
复制
#include<iostream>
#include<string>
#include<cctype>
using namespace std;
int main(void)
{
    string s("Hello world!!!");
    for (auto &c : s)
        c=toupper(c);
    cout<<s<<endl;
    return 0;
}

3.处理多维数组(来自C++Primer中文版5th中P116的练习题目)

由于编译器初始化时会将这些数组形式的元素转换成指向该数组内首元素的指针,这样得到的row类型就是int*,这样原来的for语句就是在一个int*中遍历,这是不合法的。而如果改成引用类型,就不会发生上述转换。 所以使用范围for语句处理多维数组的时候,除了最内层的循环外,其他所有循环的控制变量都应该是引用类型

代码语言:javascript
复制
#include<iostream>
#include<cctype>
#include<string>
#include<vector>
#include<iterator>
#include"Sales_item.h"
using namespace std;
int main(void)
{
    //练习3.43
    int ia[3][4] = {    //三个元素,每个元素都是大小为4的数组
        {0,1,2,3},      //第1行的初始值
        {4,5,6,7},      //第2行的初始值
        {8,9,10,11}     //第3行的初始值
    };
    //使用范围for语句管理迭代过程
    for (auto &row : ia)
        for (int &col : row)
            cout << col << endl;
    cout << endl;
    //使用普通for语句,使用下标运算符
    for (size_t row = 0; row < 3; row++)
        for (size_t col = 0; col < 4; col++)
            cout << ia[row][col] << endl;
    cout << endl;
    //使用普通for语句,使用指针
    int(*p)[4] = ia;   //p指向含有4个整数的数组
    for (; p != ia + 3; p++)        
        for (int *q = *p; q != *p + 4; q++)   
        //q指向含有4个整数数组的首元素,也就是说,q指向一个整数
            cout << *q << endl;
    cout << endl;
    //vector<int>::difference_type atp;  
    //声明difference_type的时候需要指定具体类型,和迭代器类似
    //difference_type是带符号类型的

    //练习3.44
    using int_array = int[4];   //新标准下类型别名是声明,参见2.5.1节P60
                                //此时将类型是"4个整数的数组"命名成了int_array
    typedef int int_array[4];   //与上一语句等价的typedef声明,参见2.5.1节P60
    //输出ia中每个元素的值,每个内层数组各占一行
    for (int_array *p = ia; p != ia + 3; p++)
        for (int *q = *p; q != *p + 4; q++)
            cout << *q << endl;
    cout << endl;

    //练习3.45
    //使用范围for语句管理迭代过程
    for (auto &row : ia)
        for (int &col : row)
            cout << col << endl;
    cout << endl;
    return 0;
}

4.为什么不能通过范围dor语句向vector(或者其他容器)中添加元素

范围for语句的语法形式为

代码语言:javascript
复制
for(declaration:expression)
    statement

其中expression必须为一个序列,为什么呢? 范围for语句的定于来源与等价的传统for语句:比如下面这个让vector中元素翻倍的循环,范围for语句还是依赖于迭代器实现的。

代码语言:javascript
复制
vector<int>v = { 1,23,56 };
for (auto &r : v)   //范围for
    r *= 2;
for (auto beg = v.begin(), end = v.end(); beg != end; ++beg){       //传统for
    auto &r = *beg;
    r *= 2;
}

这就是说,其实在范围for语句中,预存了end()的值。一旦向序列中增加或者删除元素,end函数有可能变得无效,循环就可能不是预期中的了。 因为这个时候对容器的增删操作使得保存在end中的迭代器失效了,不再指向任何元素,或者是尾元素的后一个位置。

5.为什么需要对序列中的元素执行写操作的时候,循环变量必须声明成引用类型?

  • 当传入的迭代参数类型为非引用时,做的是值传递,值传递的特点是被调函数对形式参数的任何操作都是作为局部变量进行,不会影响主调函数的实参变量的值,所以才修改无效。
  • 而在引用传递过程中,被调函数的形式参数虽然也作为局部变量在栈中开辟了内存空间,但是这时存放的是由主调函数放进来的实参变量的地址。被调函数对形参的任何操作都被处理成间接寻址,即通过栈中存放的地址访问主调函数中的实参变量。正因为如此,被调函数对形参做的任何操作都影响了主调函数中的实参变量,所以修改有效。
  • 这里讲解了几种关于参数传递的区别http://xinklabi.iteye.com/blog/653643
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018年03月11日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.如何处理stirng中的每个字符?(来自C++Primer中文版5th中P83)
  • 2.修改序列中的元素,必须将循环变量申明为引用类型(来自C++Primer中文版5th中P83)
  • 3.处理多维数组(来自C++Primer中文版5th中P116的练习题目)
  • 4.为什么不能通过范围dor语句向vector(或者其他容器)中添加元素
  • 5.为什么需要对序列中的元素执行写操作的时候,循环变量必须声明成引用类型?
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档