14.4 输出流
C++将输入输出都抽象为字节流,输出流ostream类的任务便是将数值类型转换为以字符字节为单位的输出,这些是通过ostream类的公共方法(接口)来实现的,本节以标准输出流对象cout为例来进行讨论。
14.4.1 操作符<<
在流类库中,<<称为插入操作符(Insertion Operator),ostream类中已预先以成员函数的形式重载了C++基本类型(如char、int、long和double等)的<<操作符处理函数,其基本类型如下所示。
ostream&operator<<(基本类型);在前面很多的示例中都使用了<<进行输出,如下例所示。 cout<<5;上述输出整数5的操作实际上等价以下示例代码。 cout.operator<<(5);//对应的原型为cout.operator<<(int)<<操作符的返回类型都为ostream&,这是为了实现链式输出,如下所示。 cout<<5<<","<<6.2;<<的结合顺序为从左到右,上述代码等价于下述代码。 ((cout.operatoer<<(5)).operator<<(".")).operator<<(6.2);
即对cout对象调用成员函数operator<<(int),返回ostream类对象的引用,查询ostream类的定义可知,“return this”语句说明返回对象仍旧为cout,再调用operator<<(char*)用于","的输出,依旧返回cout,再次调用operator<<(double)输出6.2,这称为链式输出,有的教材中也称为“拼接输出”。通过返回ostream类对象的引用,使得不同的输出类型可以直观地拼接起来,按从左到右的顺序复制到输出流中。
特别强调下字符串的输出,用指向字符串的指针来表示字符串,关于字符串的输出在第3章中已经进行了介绍,在此不再赘述,看以下示例代码14.6所示。
代码14.6 C风格字符串输出C-StringOutput
<———————————-文件名:example1406.cpp———————————————-> 01 #include<iostream> 02 using namespace std; 03 int main() 04 { 05 char*pC="Hello";//指向只读字符串的指针pC 06 char sz[]="China";//字符数组sz 07 cout<<pC<<endl;//输出char型指针指向的字符串 08 cout<<&pC<<endl;//输出指针在内存中的地址 09 cout<<(void*)pC<<endl;//输出指针指向的字符串在内存中的地址 10 cout<<sz<<endl;//输出字符数组 11 cout<<&sz<<endl;//输出字符数组名在内存的地址 12 cout<<(void*)sz<<endl;//输出字符数组在内存中的首地址 13 cout<<"China"<<endl;//输出只读字符串 14 cout<<(void*)"China"<<endl;//输出只读字符串在内存中的地址 15 return 0; 16 }
输出结果如下所示。
Hello 0012FF7C//栈区 0046E024//只读数据区 China 0012FF74//栈区 0012FF74//栈区 China 0046E01C//只读数据区
【代码解析】代码的输出结果直观体现了3种用法的不同,对代码第5行的“charpC="Hello";”而言,字符串"Hello"将被存储在只读数据区,pC只是个char型指针,指向这块不能被修改的内存,对pC的输出操作“cout<<pC<<end1;”实际上是输出pC指针指向的字符串,而“cout<<&pC<<end1”用以输出pC指针这个变量在内存中的地址,“cout<<(void)pC<<end1;”用以输出pC指向的字符串在内存中的首地址,这两个地址是不同的。
对代码第6行的字符数组来说,情况略有不同,“char sz[]="China";”,编译时,字符串"China"仍将被放置到只读数据区,但程序执行时会在栈区也开辟了和"China"相同大小的内存空间,用sz来标记,并用存储在只读数据区的字符串"China"为其初始化,此处的数组名sz可以看成是指向在栈区开辟的这块内存的指针,因此,“cout<<sz<<end1;”实际上是对sz指向的字符串(位于栈区的字符串)进行输出,“cout<<&sz<<endl;”和“cout<<(void*)sz<<endl;”等价,都是输出栈区字符串在内存中的首地址。
对于代码第13行的“cout<<"China"<<endl;”这样的操作,实际上是直接对存储在只读数据区的字符串进行输出,而“cout<<(void*)"China"<<end1;”则是输出只读字符串"China"在内存中的首地址,此外,程序中出现的3个“China”是当成不同的实体存储在只读数据区的。