26 C十十实用培制最程 当读者运行NUMN,键入浮点数3.14159并键人<Enter>后,再健人一个整数值100 和<Eter>。程序似乎完全正常运行,可等待输人,然后显示输人的值。 再次运行NUMN,但这一次键人一些非数值型字符,例如ABCDEFG或XQ45当读 者键入<Enter>时,与上次运行NUMIN不一样,这时程序不是显示第二条提示信息并等 待第二个输人,而是随机显示某些结果并终止程序。 ·以上现象的发生是由于输入流只接受正确格式的信息。因此任何微小的输入错误都可 能导致严重出错。例如,NUMIN在接收到非数值型字符时就显示随机数并终止程序。 解决这类错误的好办法是把输人读人到一个字符申中,然后再将该字符串转换为整数、 浮点数,或二进制数形式,因为字符申能够接收任何字符,然后就可以检验输人是否有错,并 做出相应的处理。例如,读者键人了ABC而不是123,但程序能够接收不正确的输人,至少 不会因为错输了某些数而造成死机现象。程序清单1.11(ATONUMS.CPP)说明了怎样把 输人值读到一个字符串中,并把这个字符串转换为其他数据类型。 程序清单1.1 ATONUMS.CPP 1.atonums.cpp-Demonstrate safe way to input numbers 28 t:。d。 4: 6:main() 7:{ 8: double fp A floating point value long k ∥A long int val char s[80] /80-character string for inpu 1 cout<Enter a floating point value." 13 in 14, cout<<"Original entry<<<<'n' 15: fp -atof(s); 16: cout<<"After converting to double"<<fp<<'n': 17: 18 cout<"Enter an integer value" 19 cin > "Original entry:" k atol(s): 22 cout <<After converting to long<<k<< : 运行ATONUMS与NUMIN类似,提示后并等待输人一个浮点数和一个整数值。但与 NUMIN不同,当键人非法字符时,如ABCDEFG,它不会死机,而是将O赋给变量。更好的 程序是检查出错误的输人,并再次执行输入语句,以便改正上次的输人错误。 这个程序与以前的程序略有不同,它说明了头文件STDLIB.H和STREAM.HPP。另 外还有在第15行和21行中的赋值语句。这些语句用到了STDLIB.H中定义的两个函数 atof(ASCII到浮点数)和atol(ASCII到长整数)。正如它们的名称一样,这两个函数分别将 字符串中的ASCI字符转换为浮点数和长整数型数值
第一本C十十瓶连 27 函数atof和at0l对括号内的字符串进行处理,并分别返回等价的浮点数和长整数型数 值。通常我们使用了与下面类似的语句将返回值赋给某个变量: fp=atof(s) 这条语句调用函数atof,将字符串s转换为浮点数,并把值f给p。这里赋值语句(=)是 将该浮点数的地址传给浮点指针变量p。 1.3.7十进制到十六进制和八进制的简单转换 下面我们给出一个将榆入和输出流以及格式化函数结合在一起的C++程序,程序清 单1.12(CONVERT.CPP)提示输人,并将输人的十进制数转换为十六进制和八进制数 程序清单1.12 CONVERT.CPP :∥convert.cepp Conver:integers to hex and oct 2. 3:#include <stream.hpp 4:#include <stdlib.h> 6, main() /80-character string for inpu 10 11 cout <<"Value?" 12 cin>>: value =atol(s); 4156 cout< <<dec(value) hex(va )<< 7:1 1.4常数 常数是指那些在程序运行时值不再改变的数。读者将发现本书给出的程序很多都有常 数,我们应该学会如何在自己的程序中正确地使用常数 由于常数的值不能改变,因此使用常数可以使程序的质量更加可靠。例如,将P设置成 一个变量就很危险,如果一旦将P1的值3.14159变动,程序中所有用P1进行计算的公式都 将出现错误 注:C和C十十中的常数名称通常都大写。虽然这并不是绝对的,但将常数名称大写会 使程序更清楚,可读性也更好 在定义常数时,取合理的名称和值会使程序逻辑更清楚,再以PI为例,即使不加说明通 常人们也了解PI代表什么,以及它的值是多少。 另一方面,将某些偶尔变动的数设置为常数,这在编程时也十分有用。如开始我们将常
28 C十十实用话州教框 数MAX-SCORES的值设置为1O。当情况有变动时,例如需要把MAX-SCORES的值改为 15,则我们只须改变一条语句,并重新编译程序即可。否则,就要把程序中凡是用到MAX SCORES值的地方都要修改。 1.4.1常数类型 在C+十中共有四种类型的常数: ·文字型常数 ·定义型常数 ·说明型常数 ·枚举常数 文字型常数是最常见的常数,例如它们取值为123,3.14159,或“nter your name'”,即编 程人员其键人在程序的文本文件中,定义型常数有自己的名称,它们的值为文字型常数。说 明型常数和变量类似,它们的值放在内存里,但这些值是不允许在程序运行时变更的。枚举 型常数是一种命名常数的集合。它指定该类型变量可拥有的全部合法值。例如coor可以取 Red,Blue和Green. 1.4.1.1文字型常数 当碰到一个文字型常数,如100,编译器可以从它们的形式得知它是何种数据类型。也 就是说C++知道100是一个整数值,同样C++能知道5.5是一个浮点数指针的值,以及 “Bees make honey“是一个字符串。文字型常数的形式决定了它们数字类型,它们可以为表 1.1中列出的变量类型的任意一种 由于编译器是根据常数的形式决定其类型,因此常数值一定要以正确的形式键人。 1.4.1.1.1字符常数 char类型的常数(或变量)有两种用途,一方面char中可以存放一个用单引号括起来的 ASCIⅡ字符。例如,“$”Z'和?'都是字符常数。由于这些字符的ACI内码的值是在0到 255之间,因而char同样能存放0到255之间的某个数。通常对那些只需1个字节存放的 值,我们都用char来存放。 在编程中还有一个问题需要解决,即数据类型如何处理有符号的值或无符号的值,有符 号的值表示正或负数:无符号值则表示正数。四种整数类型,即char,short,int和long缺省 时为有符号的。为了让它们表示无符号值只需在名字前加上关键字unsigned即可。下面给 出几个这方面的实例: char s 10, ned short us =65535; iats=-12345: unsigned int 999999
第一章C十十瓶述 29 在上面的例子中,读者可以将char sc改写为signed char sc,对于其他几种类型也可以 这样改写,因为缺省方式就是有符号的值。需要指出的还有,从表1.1中可以看出,在 Zortech编译器里,short型与int型实际上是完全一样的(并不是所有的C十+都是这样) 无符号字符常数能表示的值是从0到255,有符号的字符常数(char类型的缺省方式) 能表示的值则是从一128到+127.同样无符号整数常数的取值范围是0到65535,有符号整 数常数则为一32768到+32767。图1.4形象化地说明了这一问题。无符号整数的取值范围 是0到65535,而有符号数则因为向左位移一半,因而它的取值范围是一32768到+32767。 ←一6)习 HHH1HHHH 32-101232.707 65.5 图1.4无符号和有符号数的存储范围是一样大,但取值范围却不相同, 而且只是有符号数才能取负值 正如开始说明的那样,有些字符不能直接通过键盘,键人字符给char类型。读者可以 用'来表示重开一新行的字符(实际上在P℃中是两个字符:一个回车、一个换行),表1.2 给出了C+十中的控制字符。读者可以在char类型常量中使用它们(用单引号括起来),也 可以在字符串中使用它们(用双引号括起来).由于控制字符的前面有斜杠,因而斜杠的表示 为、'。同样若要表示引号字符,前面也需加斜线 表1,2控制字符 控制码 含义 ASCI值 Dec Hex Symbol(s) Bell 07 BEL Backspace Form feed n New line 1310 OD 0A CRLF Carriage return 13 OD CR t Horizontal tab 909 HT Vertical tab 110B VT Backslash 925C 八 Single a 399 八 Il hexa decimal all all all 在表1.2的最后两行有两个特殊的控制串,000和x00。 这里的0代表数字,它们可用来表示任何ASCII字符。例如B的ASC码为E1(十六进 制),341(八进制).字符申Version V7.54xE1“和Version V7.54341"在屏幕上显示时都 为:
0 C十十宾用话料表程 "Version V7.54 1.4.1.1.2字符串常数 读者现在应该对字符串较为了解了。在C十十中,对字符串的长度是没有任何限制的, 即在两个双引号之间可以健人任意多个字符,同样字符串中也能使用表1,.2中列出的任何 控制字符。 在内存中,字符串是由一组ASCI字符的值并加上一个O或NULL组成。NULL字符 是作为一个字符串的结束,它是由C十十自动加在字符串的尾部。NULL是一个常数,在 STDDEF.H,STDIO.H,STDLIB.H和STRING.H四个头文件中都有定义。在程序里使用 符号NULL时,最好在程序里包括一个或多个上面提及的头文件而不是以下语句来定义 #define NULL 0 虽然这样定义也可以,但C++编译器头文件中定义的ULL可能与此略有不同,因 此我们建议读者还是采用包括头文件的方式来定义NULL。 因为字符串总是以NULL结束,因此不要用字符串来表达单独一个字符,这样做会浪 费空间。例如“J”是一个字符串,它要占两个字节,J占一个,NULL也要占一个。而J是表 示一个字符,它只占一个字节 注:第四章中将说明如何在指针中使用NULL。无论在字符事结束时或代表一个指针 的值时都是同样的用NULL。可以认为NULL是O,但决不要在用NULL的地方用 1.4.1.1.3全数字型常数 在键人Short,int和long的值时,读者无须考虑它是什么类型。如果健人的是1024 C++把这个值按nt类型处理,如果键人999999,C++将按log类型处理.然而全数字型 常数还是有些具体细节需要记住: ·不要在数字中使用逗号或其他分隔符。例如,键人123456,而不要键入123,456。 为强制一个值为long可以用大写L结尾。例如,1024是int类型,但1024L是long 类型的。通常在一个表达式有几种类型的数字时,而最终结果又必须是某种类型时 则必须这样做】 为了让一个值为无符号的,可以用大写字母U结尾。可以一起使用U和L去产生 个无符号的long常数,如3452UL. 在Zortech C+十编译器中,short和int都是占两个字节,因此以后我们都统一用int,而 不再用short了.log类型长数占4个字节(32位),可用于存放大的整数值 注:编程时,程序不应依赖数据类型所占的字节,否则用其他C十十编译器编译时,程序 将出错。 1.4.1.1.4浮点常数 就像全数字型常数一样,浮点型常数表示固定数的值(见表1,1)可是,浮点值是被标