16 C十十实用幡的教程 7 char slash sbort month =3 9 int year -1991 0: long population 308700000: 123 1 o pi=3.14159: 5.88e12 4 15 cout <<"Date =<month <slash <year <<' cout <<Population of the U.S.A.<<population<<' 51118180 cout <<"One light year5<light Year <mi.<<' 21 当运行VARIABLE时,它显示了定义在7-13行上的每一个变量.15一20行的输出流 语句使用适用于这些变量的数据类型的形式显示这些值: Date=3/1991 Population'of the U.S.A=308700000 Pi=3.14159 Velocity of light=186281.7 mi./sec One light year=5.88e+012 mi. 1.2.2用赋值预量变量 另一种预置变量的方法是在定义变量后使用分离赋值语句。例如,替换程序清单1.4中 的第7行,可以用下列定义创建变量: char slash 然后,在程序最后使用一个赋值语句在slash中存储一个值 slash='/ 编译器把等号解释为一个指令:等号右边的值赋给等号左边的变量。亦即,编译器生成 代码,在存储器为slash变量保留的存储单元中存储了用ASCI斜线字符表示的一个值(参 见图1.2). Anoot kmg IOI 图1.2赋值语句shsh=''在为ah变量保留的存储单元中存储了一个ASCI斜线字符 读者也可以给程序清单1.4中的其他变量赋值。例如,在第14行后增加语句: 运行这个修改过的程序时,它显示了美国的人口为一500.虽然这个值是错误的,但它说
第一来C++搬述 17 明了赋值语句可以替换变量的初值。这是变量的一个特点。通常在必要时,程序可以政变变 最的值,并且每次程序只赋一个值给一个变量,新值替换了旧值。一个变量一次只接受一个 值。 无论读者采用哪一种方法给变量赋值,在程序中预置变量是很重要的。如果忘记了给变 量赋初值,变量将使用内存为它们保留的存储单元中的任一值,未预置变量是造成各种程序 错误的原因,从错误的银行差额到失败的卫星轨道。为避免用户程序出现这类问题,应确保 对所有变量赋初值。 1.2.3变量的作用域 语句可以引用变量,但仅当与变量在同一作用城中或在同一层上。变量的作用域可扩大 到它的定义块界。 图1,3给出了一个样本程序(不包含在磁盘中),它含有在mai函数中的嵌套块。这个 程序是模拟程序,实践中是不能以这个方式写程序的。然而,它却是正确的C十十程序(它可 编译),并且它说明了可见变量的作用域范围。 Global scope nt Ar 、=123: Local o main First sublevel in main 图1,3变量的作用城仅可扩展到定义它的块界 图1.3例示了几个关于作用域的重要事实。第一,整数Q拥有全局使用域,包括整个程 序。这意味着所有语句可访问,不管它们出现在程序中何处。Q是全局变量,它的作用域是 整个程序。 在mai括号中的定义,如整数A,是局部于main的。所以,只有main内的语句可以使 用A,也即在由括号限制的main块中(同一作用域中)的语句可以使用A(在图1.3给出的 程序中没有这种语句)。事实上,在A的定义块之外,A根本不出现在存储器中。 离main再远一些的块是嵌套块,在图l.3中标为“main中的第一子层”。由于嵌套块是 嵌套在mai的主块中的,所以嵌套块可以使用它自己定义的B和在外层定义的整数A,也 可以使用全局变量Q。嵌套块总是可以“看到”在它们的外层块中的定义。然而外层的块不 可以“看到”嵌在内层块中的定义。这表示,如果在A=123后插人一条语句,则程序编译会 出错:
18 C十十实用棒制教程 B=456: 由于B只出现在它的定义块中,所以上述语句不在“局部于main”的块内工作,main的 主块不可以访问B,因为B的作用域被嵌在外层块中,类似地,在main的第一子层中的语句 不可以使用在下一层和图1.3中标有“main中最内子层”的最内层中的定义。在最内层中定 义了整数C。正如图中所示,最内层块中的语句可以使用所有在该程序中定义的变量,但仪 这个块可以使用C。在最内层块外部的语句不可以看到main中深层嵌套块内。 程序清单1.5给出了另一个作用域限制访问变量的例子。 程序清单1.5SC0PE.CPP onsrate nested sope 3:#include <stream.hpp> 4 5:int outer =100 ∥Global variable 8.main() int inner =200: lri、ariable 10. 11 cout <<"outer -<outer <<'V' 12 cout <"inner -<inner <<'V' 6 ="<<noseeum<<八n' 17:cout <<"noseeum =<nosccum <<'Vn' 18: SCOPE定义了三个变量:outer,inner和noseeum,第5行的第一个定义是全局于程序 的。在所有作用蜮中的所有语句,无论怎样被深层嵌套,都可以读取和写这个全局变量。第 9行不同,它仅被定义在main块内(在第8行和第18行括号之间)。它是局部变量的例子 即一个定义在内块中的变量。第14行的第三个变量也是局部的,只是它被嵌套在由第13和 第16行括号所限定的小块中。只有在这种块的作用域内的语句可以读取和写noseeum。 读者可自行验证这一点,只需将第17行程序前的注释符∥去掉即可。虽然去掉注释的 第17行程序与第15行程序完全一样,但编译去掉注释后的程序时将会出错,这是因为第 17行不在变量noseeum定义的作用域中,因而在inner这一层不能访问noseeum。 1.2.4初始化全局变量和局部变量 虽然全局变量与局部变量定义的方式有些类似,但它们在内存里存放的方式是不同的 编译器为所有的全局变量在内存的数据段里分配空间。只要程序开始运行,全局变量就一定 将其值保存在内存地址里。例如,若某条语句将全局变量x赋值为100,若没有语句再次改 变x的值,那么无论程序怎样运行,x都将以100存放在内存里。 局部峦量与会局变量不同,它不是存放在数据段里,而是由编释器为所有的局部变量分 配临时空间。这个空间是栈段的一部分,它根据变量的进栈和出栈而变化。当局部变量在有
第一章C十十概笔 19 效作用域内时,C+十在栈里为其分配空间:若局部变量不在作用域中,则C+十不为其分配 栈空间,即内存里根本没有该变量。 下面的程序说明了全局变量和局部变量的重要区别。请读者编译并运行该程序 程序清单1.6 GLOBAL.CPP 1://global.cpp-Demonstrate global and local variables 2: 3:#include <stream.hpp> 4: 5:int global =100 6 int globalDefault main() 12. 1 cout <"lobal ="<global <<"\n' 14 cout <"local =<local <<' 15 16: cout<"globalDefault ="globalDefault<'n' 17 cout <<"localDefault =<localDefault <<Vn' 18:3 程序第5行和第6行定义了两个全局变量,第一个全局变量global与读者前面所见到 的全局变量类似。由于global是全局变量,因而它存放在数据段里的某一固定位置,而且可 以在程序的任何地方访问它。第6行也定义了一个全局变量,但没有为它置初值。 由定义可知,所有的全局变量(如第6行中的globalDefault)在程序运行时都被置为0. 因此读者可以放心,在没有其他语句改变globalDefault时,它的值将为0.而第5行中定义的 全局变量global在程序运行时,其值被置为100。 在程序的第10行和第11行定义了两个局部变量,并在第10行里置locl的值为200 而第l1行中定义的局部变量localDefault没有为其指定任何值,但程序运行时将以某个值 这一点恰好说明了全局变量与局部变量之间最大的区别。 在C+十中,未被赋值的全局变量,在程序运行时将被初始化为0。由于局部变量是临 时存放在栈里,因而没有初始化的局部变量可能以其他方式出现(可能为0,也可能不为0), 所以读者在使用局部变量时,要注意到局部变量的这一特性。 1.3输人和输出 将信息放人内存,经过某些运算后再将信息传到其他地方,这些就是程序最主要的工 作.程序的输入输出(I/O)语句就是负责信息进出的端口,例如,在终端上显示文本,打印报 表,提示用户执行某些动作,以及通过电话线与其他远程系统通信
20 C十十实用培斜教程 1.3.1输出流 前面的程序利用输出流语句显示字符串和变量的值,程序清单1.7(DT.CPP)说明了如 何使用输出流显示日期和时间。 程序清单1.7 DT,CPP 1:dt.pp-Display the date and time 3:#include <stre m.hpp d.tinclude 5dos.h 5: dos-getdate(&today 121314 dos-gettime(&theTime cout <"The time is "<(int)theTime.hour<<":" if (theTime.minute<10) t0时 21 cout<<(int )the Time.minute< 22: if(theTime. ond <10) Time.second<< 26: 在DT,CPP中有些语句可能读者不太熟悉。例如第8一9行定义了两个struct变量: today和theTime.第11和16行使用了函数将日期和时间读人所定义的变量里。还有在19 和23行里用了if语句决定程序的运行,以及第3和4行用include语句说明了STREAM, HPP和DOS.H两个头文件。 读者可以先不考虑DT.CPP中陌生的语句,重点在于DT,CPP是如何使用输出流语句 显示文本、字符以及表示时间和日期的值。这些语句与从前给出的例子中的语句类似,但也 有例外,如第25行的语句: cout<<(int)theTime.second<<'n' (int)theTime.second这种方式被称为类型转换。其中theTime,.second是定义在头文件 DOS.H中的占一个字节长度的char型变量,它用于存放一个较小的整数。由于显示时我们 望显示秒的数值,而不是ASCI字符,因此我们在theTime.second前面加上(int)使之由 Char 型转换为int型 读者可以将DT.CPP中所有的(nt)到去,然后重新编译并运行程序。通过这样的例子