13-cout的新花样
2.2.3 cout的新花样
到目前为止,本章的示例都使用cout来打印字符串,程序清单2.2使用cout来打印变量,该变量的值是一个整数:
cout << carrots;
程序没有打印“carrots”,而是打印存储在carrots中的整数值,即25。实际上,这将两个操作合而为一了。首先,cout将carrots替换为其当前值25;然后,把值转换为合适的输出字符。
如上所示,cout可用于数字和字符串。这似乎没有什么不同寻常的地方,但别忘了,整数25与字符串“25”有天壤之别。该字符串存储的是书写该数字时使用的字符,即字符2和5。程序在内部存储的是字符2和字符5的编码。要打印字符串,cout只需打印字符串中各个字符即可。但整数25被存储为数值,计算机不是单独存储每个数字,而是将25存储为二进制数(附录A讨论了这种表示法)。这里的要点是,在打印之前,cout必须将整数形式的数字转换为字符串形式。另外,cout很聪明,知道carrots是一个需要转换的整数。
与老式C语言的区别在于cout的聪明程度。在C语言中,要打印字符串“25”和整数25,可以使用C语言的多功能输出函数printf():
printf("Printing a string: %s\n", "25");
printf("Printing an integer: %d\n", 25);
撇开printf()的复杂性不说,必须用特殊代码(%s和%d)来指出是要打印字符串还是整数。如果让printf()打印字符串,但又错误地提供了一个整数,由于printf()不够精密,因此根本发现不了错误。它将继续处理,显示一堆乱码。
cout的智能行为源自C++的面向对象特性。实际上,C++插入运算符(<<)将根据其后的数据类型相应地调整其行为,这是一个运算符重载的例子。在后面的章节中学习函数重载和运算符重载时,将知道如何实现这种智能设计。
cout和printf()
如果已经习惯了C语言和printf(),可能觉得cout看起来很奇怪。程序员甚至可能固执地坚持使用printf()。但与使用所有转换说明的printf()相比,cout的外观一点也不奇怪。更重要的是,cout还有明显的优点。它能够识别类型的功能表明,其设计更灵活、更好用。另外,它是可扩展的(extensible)。也就是说,可以重新定义<<运算符,使cout能够识别和显示所开发的新数据类型。如果喜欢printf()提供的细致的控制功能,可以使用更高级的cout来获得相同的效果(参见第17章)。