2.3 变量
如果要计算2的10次方,我们首先想到的可能是:
#include int main() { // a first, not very good, solution std::cout << "2 raised to the power of 10: "; std::cout << 2*2*2*2*2*2*2*2*2*2; std::cout << std::endl; return 0; } |
这个程序确实解决了问题,尽管我们可能要一而再、再而三地检查确保恰好有10个字面值常量2相乘。这个程序产生正确的答案1024。
接下来要计算2的17次方,然后是23次方。而每次都要改变程序是很麻烦的事。更糟的是,这样做还容易引起错误。修改后的程序常常会产生多乘或少乘2的结果。
替代这种蛮力型计算的方法包括两部分内容:
(1) 使用有名字的对象执行运算并输出每个计算。
(2) 使用控制流结构,当某个条件为真时重复执行一系列程序语句。
以下是计算2的10次方的替代方法:
#include int main() { // local objects of type int int value = 2; int pow = 10; int result = 1; // repeat calculation of result until cnt is equal to pow for (int cnt = 0; cnt != pow; ++cnt) result *= value; // result = result * value; std::cout << value << " raised to the power of " << pow << ": \t" << result << std::endl; return 0; } |
value、pow、result和cnt都是变量,可以对数值进行存储、修改和查询。for循环使得计算过程重复执行pow次。
习题
习题2.11 编写程序要求用户输入两个数,底数(base)和指数(exponent),输出底数的指数次方的结果。
关键概念:强静态类型
C++(www.cppentry.com)是一门静态类型语言,在编译时会作类型检查。
在大多数语言中,对象的类型限制了对象可以执行的操作。如果某种类型不支持某种操作,那么这种类型的对象也就不能执行该操作。
在C++(www.cppentry.com)中,操作是否合法是在编译时检查的。当编写表达式时,编译器检查表达式中的对象是否按该对象的类型定义的使用方式使用。如果不是的话,那么编译器会提示错误,而不产生可执行文件。
随着程序和使用的类型变得越来越复杂,我们将看到静态类型检查能帮助我们更早地发现错误。静态类型检查使得编译器必须能识别程序中的每个实体的类型。因此,程序中使用变量前必须先定义变量的类型。
2.3.1 什么是变量
变量提供了程序可以操作的有名字的存储区。C++(www.cppentry.com)中的每一个变量都有特定的类型,该类型决定了变量的内存大小和布局、能够存储于该内存中的值的取值范围以及可应用在该变量上的操作集。C++(www.cppentry.com)程序员常常把变量称为“变量”或“对象(object)”。
1. 左值和右值
我们在第5章再详细探讨表达式,现在先介绍C++(www.cppentry.com)的两种表达式:
(1) 左值(lvalue,发音为ell-value):左值可以出现在赋值语句的左边或右边。
(2) 右值(rvalue,发音为are-value):右值只能出现在赋值的右边,不能出现在赋值语句的左边。
变量是左值,因此可以出现在赋值语句的左边。数字字面值是右值,因此不能被赋值。给定以下变量:
int units_sold = 0; double sales_price = 0, total_revenue = 0; |
下列两条语句都会产生编译错误:
// error: arithmetic expression is not an lvalue units_sold * sales_price = total_revenue; // error: literal constant is not an lvalue 0 = 1;
|
有些操作符,比如赋值,要求其中的一个操作数必须是左值。结果,可以使用左值的上下文比右值更广。左值出现的上下文决定了左值是如何使用的。例如,
units_sold = units_sold + 1;
|
表达式中,units_sold变量被用作两种不同操作符的操作数。+操作符仅关心其操作数的值。变量的值是当前存储在和该变量相关联的内存中的值。加法操作符的作用是取得变量的值并加1。
变量units_sold也被用作=操作符的左操作数。=操作符读取右操作数并写到左操作数。在这个表达式中,加法运算的结果被保存到与units_sold相关联的存储单元中,而units_sold之前的值则被覆盖。
在本书中,我们将看到在许多情形中左值或右值的使用影响程序的操作和/或性能——特别是在向函数传递值或从函数中返回值的时候。
习题
习题2.12 区分左值和右值,并举例说明。
习题2.13 举出一个需要左值的例子。
术语:什么是对象?
C++(www.cppentry.com)程序员经常随意地使用术语对象。一般而言,对象就是内存中具有类型的区域。具体而言,计算左值表达式会产生对象。
严格地说,有些人只把术语对象用于描述变量或类类型的值。有些人还区别有名字的对象和没名字的对象,当谈到有名字的对象时一般指变量。还有一些人区分对象和值,用术语对象描述可被程序改变的数据,用术语值描述只读数据。
在本书中,我们遵循更为通用的用法,即对象是内存中具有类型的区域。我们可以自由地使用对象描述程序中可操作的大部分数据,而不管这些数据是内置类型还是类类型,是有名字的还是没名字的,是可读的还是可写的。
【责任编辑:
董书 TEL:(010)68476606】