C++的范围for和python的迭代for

C++的范围for和python的for

python使用for对可迭代对象进行遍历的时候会对原对象进行拷贝,从而当你在循环过程中更改原对象是无法更改循环的行为的,但最后你可以成功地修改原对象

>>>s = "string"
>>>for c in s:
...		print(c)
...		s = "klllwe"
s
t
r
i
n
g
>>> s
'klllwe'

当然,修改每一步的元素是无法修改原对象的,因为这是拷贝对象中的元素

>>>s = list('string')
>>>for c in s:
		print(c)
		c = 'd'
s
t
r
i
n
g
>>> s
['s', 't', 'r', 'i', 'n', 'g']

c++中却有些不同,对于string对象,当修改对象时,会影响到循环的输出

#include<iostream>
#include<string>

using namespace std;

int main(int argc, char const *argv[])
{
  string s;
  cin >> s;
  for(auto &c:s){
    cout << "next char:";
    cout << c<< endl;
    s = "a";
  }
  cout << "string:" << endl;
  cout << s << endl;
  return 0;
}
werty
next char:w
next char:
next char:r
next char:t
next char:y
string:
a

但有趣的是,即便原对象被改变了,终止条件还是不变的,循环总是会在输出原字符串长度个字符后结束

#include<iostream>
#include<string>

using namespace std;

int main(int argc, char const *argv[])
{
  string s;
  cin >> s;
  for(auto &c:s){
    cout << "next char:";
    cout << c<< endl;
    s = "aaaaaaaaaaaa";
  }
  cout << "string:" << endl;
  cout << s << endl;
  return 0;
}
wwk
next char:w
next char:a
next char:a
string:
aaaaaaaaaaaa

奇怪的是当修改后的字符串长度超过16后,除了第一个字符外,其他输出均为空

#include<iostream>
#include<string>

using namespace std;

int main(int argc, char const *argv[])
{
  string s;
  cin >> s;
  for(auto &c:s){
    cout << "next char:";
    cout << c<< endl;
    s = "adwwwwwwwwwwwwwd";
  }
  cout << "string:" << endl;
  cout << s << endl;
  return 0;
}
kkkkk
next char:k
next char:
next char:
next char:
next char:
string:
adwwwwwwwwwwwwwd

当初始输入的字符串较长的时候,发现中间断层

abcdefghijk
next char:a
next char:
next char:
next char:
next char:
next char:
next char:
next char:
next char:i
next char:j
next char:k
string:
adwwwwwwwwwwwwwd

输入再长一点,问题就消失了

kkkkkkkkkkkkkkkkk    
next char:k
next char:d
next char:w
next char:w
next char:w
next char:w
next char:w
next char:w
next char:w
next char:w
next char:w
next char:w
next char:w
next char:w
next char:w
next char:d
next char:
string:
adwwwwwwwwwwwwwd

真是比女朋友还难以琢磨(虽然我没有)

这个故事告诉我们,在循环中更改被迭代的对象(尤其是其长度)会产生无法预料(按照c++ primer的常用说法)的结果,这是因为,范围for的等价语句为

for(auto beg=v.begin(),end=v.end();beg!=end;++beg){
;
}

,不过c++中可以通过更改c的方式来更改s

#include<iostream>
#include<string>

using namespace std;

int main(int argc, char const *argv[])
{
  string s;
  cin >> s;
  for(auto &c:s){
    c = 'X';
  }
  cout << s << endl;
  return 0;
}
asdasd
XXXXX

只要声明c为引用即可,如果没有声明c是引用,结果就和python中试图修改迭代对象的元素一样,修改的只是复制的元素,最后原对象是不变的

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值