C++习题整理(3)

习题4.1 
假设get_size 是一个没有参数并返回int 值的函数,下列哪些定义是非法的? 为什么? 

unsigned buf_size = 1024 

(a) int ia[buf_size]; (b) int ia[get_size()]; (c) int ia[4*7-14]; (d) char st[11] = "fundamental"  

【解答】 

(a)非法,buf_size 是一个变量,不能用于定义数组的维数(维长度)。 
(b)非法,get_size()是函数调用,不是常量表达式,不能用于定义数组的维数 (维长度)。 

(d)非法,存放字符串"fundamental"的数组必须有12 个元素,st 只有11 个元 素。

习题4.2

列数组的值是什么? 

string sa[10]; 
int ia[10]; int main(){ string sa2[10]; int ia2[10]; } 

【解答】 
sa 和sa2 为元素类型为string 的数组,自动调用string 类的默认构造函数将 
各元素初始化为空字符串;ia 为在函数体外定义的内置数组,各元素初始化为 
0;ia2 为在函数体内定义的内置数组,各元素未初始化,其值不确定。

习题4.3 
下列哪些定义是错误的? 

(a) int ia[7] = {0, 1, 1, 2, 3, 5, 8}; 
(b) vector<int> ivec = {0, 1, 1, 2, 3, 5, 8}; (c) int ia2[] = ia; (d) int ia3[] = ivec; 

【解答】 
(b)错误。vector 对象不能用这种方式进行初始化。 (c)错误。不能用一个数组来初始化另一个数组。 (d)错误。不能用vector 对象来初始化数组。


习题4.4 
如何初始化数组的一部分或全部元素? 

【解答】 
定义数组时可使用初始化列表(用花括号括住的一组以逗号分隔的元素初 
值)来初始化数组的部分或全部元素。如果是初始化全部元素,可以省略定义 
数组时方括号中给出的数组维数值。如果指定了数组维数,则初始化列表提供 
的元素个数不能超过维数值。如果数组维数大于列出的元素初值个数,则只初 

始化前面的数组元素,剩下的其他元素,若是内置类型则初始化为0,若是类类 
型则调用该类的默认构造函数进行初始化。字符数组既可以用一组由花括号括 
起来、逗号隔开的字符字面值进行初始化,也可以用一个字符串字面值进行初 始化。 


习题4.5 
列出使用数组而不是vector 的缺点。
 

【解答】 
与vector 类型相比,数组具有如下缺点:数组的长度是固定的,而且数组 
不提供获取其容量大小的size 操作,也不提供自动添加元素的push_back 操作。 
因此,程序员无法在程序运行时知道一个给定数组的长度,而且如果需要更改 
数组的长度,程序员只能创建一个更大的新数组,然后把原数组的所有元素复 
制到新数组的存储空间中去。与使用vector 类型的程序相比,使用内置数组的 程序更容易出错且难以调试。


习题4.6 
下面的程序段企图将下标值赋给数组的每个元素,其中在下标操作上有一些错 误,请指出这些错误。

 const size_t array_size = 10  int ia[array_size]; 
for (size_t ix = 1; ix <= array_size; ++ix) ia[ix] = ix  

【解答】 
该程序段的错误是:数组下标使用越界。 
根据数组ia 的定义,该数组的下标值应该是0~9(即array_size-1),而不是从 
1 到array_size,因此其中的for 语句出错,可更正如下: for (size_t ix = 0; ix < array_size; ++ix) ia[ix] = ix  


 

 习题4.10

下面提供了两种指针声明的形式,解释宁愿使用第一种形式的原因: 
int *ip; // good practice 

int* ip; // legal but misleading 

【解答】 
第一种形式强调了ip 是一个指针,这种形式在阅读时不易引起误解,尤其 
是当一个语句中同时定义了多个变量时

题4.11 
解释下列声明语句,并指出哪些是非法的,为什么?

 (a) int* ip; 

(b) string s, *sp = 0; (c) int i; double* dp = &i; (d) int* ip, ip2; 
(e) const int i = 0, *p = i; (f) string *p = NULL; 【解答】 
(a)合法。定义了一个指向int 型对象的指针ip。 
(b)合法。定义了string 对象s 和指向string 型对象的指针sp,sp 初始化为0 值。 
(c)非法。dp 为指向double 型对象的指针,不能用int 型对象i 的地址进行初 始化。 
(d)合法。定义了int 对象ip2 和指向int 型对象的指针ip。 (e)合法。定义了const int 型对象i 和指向const int 型对象的指针p,i 初 
始化为0,p 初始化为0。 
(f)合法。定义了指向string 型对象的指针p,并将其初始化为0 值。

习题4.12 
已知一指针p,你可以确定该指针是否指向一个有效的对象吗?如果可以,如何 
确定?如果不可以,请说明原因。 

【解答】 
无法确定某指针是否指向一个有效对象。因为,在C++语言中,无法检测指 
针是否未被初始化,也无法区分一个地址是有效地址,还是由指针所分配的存 
储空间中存放的不确定值的二进制位形成的地址。


习题4.13 
下列代码中,为什么第一个指针的初始化是合法的,而第二个则不合法? int i = 42; void *p = &i; long *lp = &i; 

【解答】 
具有void*类型的指针可以保存任意类型对象的地址,因此p 的初始化是合 
法的;而指向long 型对象的指针不能用int 型对象的地址来初始化,因此lp 的初始化不合法。


习题4.15 
解释指针和引用的主要区别。

【解答】 
使用引用(reference)和指针(pointer)都可间接访问另一个值,但它们之 
间存在两个重要区别:(1)引用总是指向某个确定对象(事实上,引用就是该对 
象的别名),定义引用时没有进行初始化会出现编译错误;(2) 赋值行为上存 
在差异:给引用赋值修改的是该引用所关联的对象的值,而不是使该引用与另 
一个对象关联。引用一经初始化,就始终指向同一个特定对象。给指针赋值修 
改的是指针对象本身,也就是使该指针指向另一对象,指针在不同时刻可指向 
不同的对象(只要保证类型匹配)。


习题4.19 
解释下列5 个定义的含义,指出其中哪些定义是非法的: 

(a) int i; (b) const int ic; (c) const int *pic; (d) int *const cpi; (e) const int *const cpic; 

【解答】 
(a) 合法:定义了int 型对象i。 
(b) 非法:定义const 对象时必须进行初始化,但ic 没有初始化。 
(c) 合法:定义了指向int 型const 对象的指针pic。 (d) 非法:因为cpi 被定义为指向int 型对象的const 指针,但该指针没有初 始化。 
(e) 非法:因为cpic 被定义为指向int 型const 对象的const 指针,但该指针 没有初始化。

列哪些初始化是合法的?为什么?

 (a) int i = -1; (b) const int ic = i  (c) const int *pic = &ic; (d) int *const cpi = &ic; (e) const int *const cpic = &ic;

【解答】 
(a) 合法:定义了一个int 型对象i,并用int 型字面值-1 对其进行初始化。 
(b) 合法:定义了一个int 型const 对象ic,并用int 型对象对其进行初始 化。 
(c) 合法:定义了一个指向int 型const 对象的指针pic,并用ic 的地址对 其进行初始化。 
(d) 不合法:cpi 是一个指向int 型对象的const 指针,不能用const int 
型对象ic 的地址对其进行初始化。 
(e) 合法:定义了一个指向int 型const 对象的const 指针cpic,并用ic 的地址对其进行初始化。 


题4.22 
解释下列两个while 循环的差别: 

const char *cp = "hello"; int cnt; 
while (cp) { ++cnt; ++cp; } while (*cp) { ++cnt; ++cp; } 

【解答】 
两个while 循环的差别为:前者的循环结束条件是cp 为0 值(即指针cp 为0 
值);后者的循环结束条件是cp 所指向的字符为0 值(即cp 所指向的字符为 
字符串结束符null(即'\0'))。因此后者能正确地计算出字符串"hello"中有 
效字符的数目(放在cnt 中),而前者的执行是不确定的。 注意,题目中的代码还有一个小问题,即cnt 没有初始化为0 值。


习题4.24 
解释strcpy 和strncpy 的差别在哪里,各自的优缺点是什么? 

【解答】 
strcpy 和strncpy 的差别在于:前者复制整个指定的字符串,后者只复制指定 字符串中指定数目的字符。 
strcpy 比较简单,而使用strncpy 可以适当地控制复制字符的数目,因此比 strcpy 更为安全。


















發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章