- 内容提要
- 前言
- 第 1 章 预备知识
- 第 2 章 开始学习 C++
- 第 3 章 处理数据
- 第 4 章 复合类型
- 第 5 章 循环和关系表达式
- 第 6 章 分支语句和逻辑运算符
- 第 7 章 函数——C++的编程模块
- 第 8 章 函数探幽
- 第 9 章 内存模型和名称空间
- 第 10 章 对象和类
- 第 11 章 使用类
- 第 12 章 类和动态内存分配
- 第 13 章 类继承
- 第 14 章 C++中的代码重用
- 第 15 章 友元、异常和其他
- 第 16 章 string 类和标准模板库
- 第 17 章 输入、输出和文件
- 第 18 章 探讨 C++新标准
- 附录 A 计数系统
- 附录 B C++保留字
- 附录 C ASCII 字符集
- 附录 D 运算符优先级
- 附录 E 其他运算符
- 附录 F 模板类 string
- 附录 G 标准模板库方法和函数
- 附录 H 精选读物和网上资源
- 附录 I 转换为 ISO 标准 C++
- 附录 J 复习题答案
2.2 C++语句
C++程序是一组函数,而每个函数又是一组语句。C++有好几种语句,下面介绍其中的一些。程序清单 2.2 提供了两种新的语句。声明语句创建变量,赋值语句给该变量提供一个值。另外,该程序还演示了 cout 的新功能。
程序清单 2.2 carrot.cpp
空行将声明语句与程序的其他部分分开。这是 C 常用的方法,但在 C++中不那么常见。下面是该程序的输出:
下面探讨这个程序。
2.2.1 声明语句和变量
计算机是一种精确的、有条理的机器。要将信息项存储在计算机中,必须指出信息的存储位置和所需的内存空间。在 C++中,完成这种任务的一种相对简便的方法,是使用声明语句来指出存储类型并提供位置标签。例如,程序清单 2.2 中包含这样一条声明语句(注意其中的分号):
这条语句提供了两项信息:需要的内存以及该内存单元的名称。具体地说,这条语句指出程序需要足够的存储空间来存储一个整数,在 C++中用 int 表示整数。编译器负责分配和标记内存的细节。C++可以处理多种类型的数据,而 int 是最基本的数据类型。它表示整数—没有小数部分的数字。C++的 int 类型可以为正,也可以为负,但是大小范围取决于实现。第 3 章将详细介绍 int 和其他基本类型。
完成的第二项任务是给存储单元指定名称。在这里,该声明语句指出,此后程序将使用名称 carrots 来标识存储在该内存单元中的值。Carrots 被称为变量,因为它的值可以修改。在 C++中,所有变量都必须声明。如果省略了 carrots.cpp 中的声明,则当程序试图使用 carrots 时,编译器将指出错误。事实上,程序员尝试省略声明,可能只是为了看看编译器的反应。这样,以后看到这样的反应时,便知道应检查是否省略了声明。
为什么变量必须声明?
有些语言(最典型的是 BASIC)在使用新名称时创建新的变量,而不用显式地进行声明。这看上去对用户比较友好,事实上从短期上说确实如此。问题是,如果错误地拼写了变量名,将在不知情的情况下创建一个新的变量。在 BASIC 中,ss 程序员可能编写如下语句:
由于 CastleDank 是拼写错误(将 r 拼成了 n),因此所作的修改实际上并没有修改 CastleDark。这种错误很难发现,因为它没有违反 BASIC 中的任何规则。然而,在 C++中,将声明 CastleDark,但不会声明被错误拼写的 CastleDank,因此对应的 C++代码将违反“使用变量前必须声明它”的规则,因此编译器将捕获这种错误,发现潜在的问题。
因此,声明通常指出了要存储的数据类型和程序对存储在这里的数据使用的名称。在这个例子中,程序将创建一个名为 carrots 的变量,它可以存储整数(参见图 2.4)。
图 2.4 变量声明
程序中的声明语句叫做定义声明(defining declaration)语句,简称为定义(definition)。这意味着它将导致编译器为变量分配内存空间。在较为复杂的情况下,还可能有引用声明(reference declaration)。这些声明命令计算机使用在其他地方定义的变量。通常,声明不一定是定义,但在这个例子中,声明是定义。
如果您熟悉 C 语言或 Pascal,就一定熟悉变量声明。不过 C++中的变量声明也可能让人小吃一惊。在 C 和 Pascal 中,所有的变量声明通常都位于函数或过程的开始位置,但 C++没有这种限制。实际上,C++通常的做法是,在首次使用变量前声明它。这样,就不必在程序中到处查找,以了解变量的类型。本章后面将有一个这样的例子。这种风格也有缺点,它没有把所有的变量名放在一起,因此无法对函数使用了哪些变量一目了然(C99 标准使 C 声明规则与 C++非常相似)。
提示:
对于声明变量,C++的做法是尽可能在首次使用变量前声明它。
2.2.2 赋值语句
赋值语句将值赋给存储单元。例如,下面的语句将整数 25 赋给变量 carrots 表示的内存单元:
符号=叫做赋值运算符。C++(和 C)有一项不寻常的特性—可以连续使用赋值运算符。例如,下面的代码是合法的:
赋值将从右向左进行。首先,88 被赋给 steinway;然后,steinway 的值(现在是 88)被赋给 baldwin;然后 baldwin 的值 88 被赋给 yamaha(C++遵循 C 的爱好,允许外观奇怪的代码)。
程序清单 2.2 中的第二条赋值语句表明,可以对变量的值进行修改:
赋值运算符右边的表达式 carrots – 1 是一个算术表达式。计算机将变量 carrots 的值 25 减去 1,得到 24。然后,赋值运算符将这个新值存储到变量 carrots 对应的内存单元中。
2.2.3 cout 的新花样
到目前为止,本章的示例都使用 cout 来打印字符串,程序清单 2.2 使用 cout 来打印变量,该变量的值是一个整数:
程序没有打印“carrots”,而是打印存储在 carrots 中的整数值,即 25。实际上,这将两个操作合而为一了。首先,cout 将 carrots 替换为其当前值 25;然后,把值转换为合适的输出字符。
如上所示,cout 可用于数字和字符串。这似乎没有什么不同寻常的地方,但别忘了,整数 25 与字符串“25”有天壤之别。该字符串存储的是书写该数字时使用的字符,即字符 3 和 8。程序在内部存储的是字符 3 和字符 8 的编码。要打印字符串,cout 只需打印字符串中各个字符即可。但整数 25 被存储为数值,计算机不是单独存储每个数字,而是将 25 存储为二进制数(附录 A 讨论了这种表示法)。这里的要点是,在打印之前,cout 必须将整数形式的数字转换为字符串形式。另外,cout 很聪明,知道 carrots 是一个需要转换的整数。
与老式 C 语言的区别在于 cout 的聪明程度。在 C 语言中,要打印字符串“25”和整数 25,可以使用 C 语言的多功能输出函数 printf( ):
撇开 printf( ) 的复杂性不说,必须用特殊代码(%s 和%d)来指出是要打印字符串还是整数。如果让 printf( ) 打印字符串,但又错误地提供了一个整数,由于 printf( ) 不够精密,因此根本发现不了错误。它将继续处理,显示一堆乱码。
cout 的智能行为源自 C++的面向对象特性。实际上,C++插入运算符(<<)将根据其后的数据类型相应地调整其行为,这是一个运算符重载的例子。在后面的章节中学习函数重载和运算符重载时,将知道如何实现这种智能设计。
cout 和 printf( )
如果已经习惯了 C 语言和 printf( ),可能觉得 cout 看起来很奇怪。程序员甚至可能固执地坚持使用 printf( )。但与使用所有转换说明的 printf( ) 相比,cout 的外观一点也不奇怪。更重要的是,cout 还有明显的优点。它能够识别类型的功能表明,其设计更灵活、更好用。另外,它是可扩展的(extensible)。也就是说,可以重新定义<<运算符,使 cout 能够识别和显示所开发的新数据类型。如果喜欢 printf( ) 提供的细致的控制功能,可以使用更高级的 cout 来获得相同的效果(参见第 17 章)。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论