知识点:
1、C++中规定了每个算术类型的最小存储空间:
bool | - |
char | 8位 |
wchar_t | 16位 |
short | 16位 |
int | 16位 |
long | 32位 |
float | 6位有效数字 |
double | 10位有效数字 |
long double | 10位有效数字 |
2、对于8位的unsigned char,其取值范围是从0到255。如果付给其超出这个范围的值,那么编译器将会取值对256求模后的值。例如,如果试图将336存储到8位的unsigned char中,则实际值为80,因为80是336对256求模后的值。如果把-1付给8位的unsigned char,那么结果是255。
3、两个相邻的仅由空格、制表符、换行符分开的字符串字面值,可连接成一个新的字符串字面值。例如:
std::cout << "a multi-line"
" string literal"
" using concatenation"
<< std::endl;
输出结果为:a multi-line string literal using concatenation
4、处理长字符串时,反斜线符号必须是该行的尾字符——不允许其后面有注释或空格。后继行行首的任何空格和制表符都是字符串字面值的一部分。
5、左值和右值:
- 左值:可以出现在赋值语句的左边或右边
- 右值:只能出现在赋值语句的右边
6、声明和定义:
- 定义用于为变量分配存储空间,还可以为变量指定初始值。在一个程序中,变量有且仅有一个定义。声明用于向程序表明变量的类型和名字。
7、C++中的作用域:局部作用域和全局作用域、累作用域、命名空间作用域。
8、const常量定以后必须要初始化。与其他变量不同,除非特殊说明,在全局作用域声明的const变量是定义该对象的文件的局部变量,此变量只存在于那个文件中,不能被其他文件访问。要使const变量能在其他文件中访问,必须显示的指定它为extern。
9、引用:定义引用时必须初始化,初始化是指明引用指向那个对象的唯一方法;const引用是指向const对象的引用;非const引用只能绑定到与该引用同类型的对象;const引用则可以绑定到不同但相关的对象或绑定到右值。
部分习题:
-
习题2.1
int、long 和short 类型之间有什么差别?
【解答】
它们的最小存储空间不同,分别为16 位、32 位和16 位。一般而言,short 类型为半个机器字(word)长,int 类型为一个机器字长,而long 类型为一个或两个机器字长(在32 位机器中,int 类型和long 类型的字长通常是相同的),因此,它们的表示范围不同。
-
习题2.2
unsigned 和signed 类型有什么差别?
【解答】
前者为无符号类型,只能表示大于或等于0 的数。后者为带符号类型,可以表示正数、负数和0。
-
习题2.3
如果在某机器上short 类型占16 位,那么可以赋给short 类型的最大数是什么?unsigned short 类型的最大数又是什么?
【解答】
若在某机器上short 类型占16 位,那么可以赋给short 类型的最大数是2^15-1,即32767;而unsigned short 类型的最大数为2^16-1,即65535。
-
习题2.4
当给16 位的unsigned short 对象赋值100000 时,赋的值是什么?
【解答】
34464。100000 超过了16 位的unsigned short 类型的表示范围,编译器对其二进制表示截取低16 位,相当于对65536 求余(求模,%),得34464。
-
习题2.5
float 类型和double 类型有什么差别?
【解答】
二者的存储位数不同(一般而言,float 类型为32 个二进制位,double 类型为64 个二进制位),因而取值范围不同,精度也不同(float 类型只能保证6 位有效数字,而double 类型至少能保证10 位有效数字)。
-
习题2.7
解释下列字面值常量的不同之处。
(a) 'a',L'a',"a",L"a"
(b) 10,10u,10L,10uL,012,0xC
(c) 3.14,3.14f,3.14L
【解答】
(a) 'a',L'a',"a",L"a"
'a'为char 型字面值,L'a'为wchar_t 型字面值,"a"为字符串字面值,L"a"为宽字符串字面值。
(b) 10,10u,10L,10uL,012,0xC
10 为int 型字面值,10u 为unsigned 型字面值,10L 为long 型字面值,10uL为unsigned long 型字面值,012 为八进制表示的int 型字面值,0xC 为十六进制表示的int 型字面值。
(c) 3.14,3.14f,3.14L
3.14 为double 型字面值,3.14f 为float 型字面值,3.14L 为long double 型字面值。
-
习题2.9
下列哪些(如果有)是非法的?
(a) "Who goes with F\145rgus?\012"
(b) 3.14e1L (c) "two" L"some"
(d) 1024f (e) 3.14UL
(f) "multiple line
comment"
【解答】
(c) 非法。因为字符串字面值与宽字符串字面值的连接是未定义的。
(d) 非法。因为整数1024 后面不能带后缀f。
(e) 非法。因为浮点字面值不能带后缀U。
(f)非法。因为分两行书写的字符串字面值必须在第一行的末尾加上反斜线。
-
习题2.16
假设calc 是一个返回double 对象的函数。下面哪些是非法定义?改正所有的非法定义。
(a) int car = 1024, auto = 2048;
(b) int ival = ival;
(c) std::cin >> int input_value;
(d) double salary = wage = 9999.99;
(e) double calc = calc();
【解答】
(a) 非法:auto 是关键字,不能用作变量名。使用另一变量名,如aut 即可更正。
(c) 非法:>>运算符后面不能进行变量定义。改为:int input_value;std::cin >> input_value;
(d) 非法:同一定义语句中不同变量的初始化应分别进行。改为:double salary = 9999.99, wage = 9999.99;
注意,(b)虽然语法上没有错误,但这个初始化没有实际意义,ival 仍是未初始化的。
-
习题2.18
解释下列例子中name 的意义:
extern std::string name;
std::string name("exercise 3.5a");
extern std::string name("exercise 3.5a");
【解答】
第一条语句是一个声明,说明std::string 变量name 在程序的其他地方定义。第二条语句是一个定义,定义了std::string 变量name,并将name 初始化为"exercise 3.5a"。第三条语句也是一个定义,定义了std::string 变量name,并将name 初始化为"exercise 3.5a",但这个语句只能出现在函数外部(即,name 是一个全局变量)。
-
习题2.22
下列程序段虽然合法,但是风格很糟糕。有什么问题呢?怎样改善?for (int i = 0; i < 100; ++i)// process i
【解答】
问题主要在于使用了具体值100 作为循环上界:100 的意义在上下文中没有体现出来,导致程序的可读性差;若100 这个值在程序中出现多次,则当程序的需求发生变化(如将100 改变为200)时,对程序代码的修改复杂且易出错,导致程序的可维护性差。
改善方法:设置一个const 变量(常量)取代100 作为循环上界使用,并为该变量选择有意义的名字。
-
习题2.24
下列哪些定义是非法的?为什么?如何改正?
(a) int ival = 1.01; (b) int &rval1 = 1.01;
(c) int &rval2 = ival; (d) const int &rval3 = 1;
【解答】
(b)非法。因为rval1 是一个非const 引用,非const 引用不能绑定到右值,而1.01 是一个右值。可改正为:int &rval1 = ival;(假设ival 是一个已定义的int 变量)。
-
习题2.32
下列声明和定义哪些应该放在头文件中?哪些应该放在源文件中?请解释原因。
(a) int var ;
(b) const double pi = 3.1416;
(c) extern int total = 255 ;
(d) const double sq2 = squt (2.0) ;
【解答】(a)、(c)、(d)应放在源文件中,因为(a)和(c)是变量定义,定义通常应放在源文件中。(d)中的const 变量sq2 不是用常量表达式初始化的,所以也应该放在源文件中。
(b)中的const 变量pi 是用常量表达式初始化的,应该放在头文件中。