用range for 改变字符串中的字符,为啥循环变量一定要用引用形式
用range for 改变字符串中的字符,为什么循环变量一定要用引用形式?
C++ Primer 上给的例题是这样,目的是把字符串中的字母都变成大写输出:
输出结果:

但为什么一定要用引用形式,为什么不能这样:
编译后运行的结果是:

输出的结果是各个字母的数字值。
H e l l o W o r l d !
72 69 76 76 79 32 87 79 82 76 68 33
或者把原码改成这样:
编译运行输出原字符串,根本没有变大写:

我不理解,引用是用另一个名字来操作变量,用变量本来的名字也可以操作变量啊,为什么在这里就不行呢?怎么解释后两次输出的结果呢?
------解决方案--------------------
先说第三种情况,你是依次把字符串s中的每个字符复制一个,并把复制得到的副本变成了大写,但你选择输出的是原来的字符串s,当然还是小写。
第二种情况,由于 C++ 是继承于 C 语言的原因,char 还是可以被当作 int 使用的,明显你这里的 auto 把类型推导成了整型。
------解决方案--------------------
auto c 推导为 char 无异议。但是 toupper 的返回值是 int 类型,cout << toupper 的时候,调用 operator<<(int) 的重载,所以当整形输出了。c=toupper; cout<<c; 的时候,因为 c 是 char,所以从 toupper 的返回类型 (int) 经类型转换又变回 char 了,后面仍然调用 operator<<(char) 的重载。
C++ Primer 上给的例题是这样,目的是把字符串中的字母都变成大写输出:
string s("Hello World!!!");
for (auto &c : s)
c = toupper(c);
cout << s << endl;
输出结果:
但为什么一定要用引用形式,为什么不能这样:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s("Hello World!");
for (auto c : s)
cout << toupper(c);
return 0;
}
编译后运行的结果是:
输出的结果是各个字母的数字值。
H e l l o W o r l d !
72 69 76 76 79 32 87 79 82 76 68 33
或者把原码改成这样:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s("Hello World!");
for (auto c : s)
c = toupper(c);
cout << s << endl;
return 0;
}
编译运行输出原字符串,根本没有变大写:
我不理解,引用是用另一个名字来操作变量,用变量本来的名字也可以操作变量啊,为什么在这里就不行呢?怎么解释后两次输出的结果呢?
c++
range for
reference
------解决方案--------------------
先说第三种情况,你是依次把字符串s中的每个字符复制一个,并把复制得到的副本变成了大写,但你选择输出的是原来的字符串s,当然还是小写。
第二种情况,由于 C++ 是继承于 C 语言的原因,char 还是可以被当作 int 使用的,明显你这里的 auto 把类型推导成了整型。
------解决方案--------------------
auto c 推导为 char 无异议。但是 toupper 的返回值是 int 类型,cout << toupper 的时候,调用 operator<<(int) 的重载,所以当整形输出了。c=toupper; cout<<c; 的时候,因为 c 是 char,所以从 toupper 的返回类型 (int) 经类型转换又变回 char 了,后面仍然调用 operator<<(char) 的重载。