题目16Whenisitvalidtoreturnareference?
Aconstreference?
什么时候返回引用是正确的?
而什么时候返回const引用是正确的?
【解答】返回指向在函数调用之前已存在的对象的引用是正确的。
当不希望返回的对象被修改时,返回const引用是正确的。
题目17Whatpotentialrun-timeproblemdoesthefollowingfunctionhave?
下面函数存在什么潜在的运行时问题?
string&processText(){stringtext;while(cin>>text){/*...*/}//....returntext;}
【解答】该函数返回了局部对象test的引用。
当函数执行完毕时,将释放分配给局部对象的存储空间,这样,对局部对象的引用就会指向不确定的内存,因此函数会在运行时出错。
题目18判断下面程序是否合法;如果合法,解释其功能;如果不合法,更正它并解释原因。
int&get(int*arry,intindex){returnarry[index];}intmain(){intia[10];for(inti=0;i!
=10;++i)get(ia,i)=0;}
【解答】该程序段合法。
其功能为:
将数组ia的各个元素赋值为0.
题目19
将函数factorial重写为迭代函数(即非递归函数)。
【解答】函数如下:
Intfactorial(intval){Intresult=1;For(inti=1;i<=val;++i)Resulet*=I;Returnresult;}
题目20如是函数factorial的终止条件为:
if(val!
=0)会出现什么问题?
【解答】会出现这样的问题:
如果实参为负数x,则理论上该函数会求得x*(x-1)*…*(int型能表示的最小负数)*(int型能表示的最大整数)*(int型能表示的最大正数-1)*…*1这样的结果,但是实际运行时会因递归函数调用次数过多而发生程序栈溢出,似的程序无法继续执行。
而当实参为负数时,元factorial函数球的的结果应该为1。
题目21Writetheprototypesforeachofthefollowingfunctions:
编写下面函数的原型:
a.函数名为compare,有两个形参,都是名为matrix的类的引用,返回bool类型的值。
b.函数名为change_val,返回vector类型的迭代器,有两个形参:
一个是int型形参,另一个是vector类型的迭代器。
提示:
写函数原型时,函数名应当暗示函数的功能。
考虑这个提示会如何影响你用的类型?
【解答】函数原型如下:
Boolcompare(matrix&,matrix&);
Vector:
:
iteratorchange_val(int,vector:
:
iterator);
题目22给出下面函数,判断哪些调用是合法的,哪些是不合法的。
对于那些不合法的调用,解释原因。
doublecalc(double);intcount(conststring&,char);intsum(vector:
:
iterator,vector:
:
iterator,int);vectorvec(10);(a)calc(23.4,55.1);(b)count("abcda",'a');(c)calc(66);(d)sum(vec.begin(),vec.end(),3.8);
【解答】(b)(c)(d)合法。
(a)不合法。
因为calc函数只有一个形参,调用该函数时却传递了两个实参。
题目23Which,ifany,ofthefollowingdeclarationsareerrors?
Why?
如果有的话,指出下面哪些函数声明是错误的?
为什么?
(a)intff(inta,intb=0,intc=0);
(b)char*init(intht=24,intwd,charbckgrnd);
【解答】(b)是错误的。
因为在形参表中,具有默认实参的形参应该出现在形参表的末尾(此处ht应出现在没有指定默认实参的形参wd和bckgrnd的后面)。
题目24Giventhefollowingfunctiondeclarationsandcalls,which,ifany,ofthecallsareillegal?
Why?
Which,ifany,arelegalbutunlikelytomatchtheprogrammer'sintent?
Why?
假设有如下函数声明和调用,指出哪些调用是不合法的?
为什么?
哪些是合法的但可能不符合程序员的原意?
为什么?
//declarations
char*init(intht,intwd=80,charbckgrnd='');(a)init();(b)init(24,10);(c)init(14,'*');
【解答】(a)不合法。
因为调用init函数时必须显式指定至少一个实参。
(c)合法,但可能不符合程序员的原意。
因为这里是将char型实参’*’转换为int型再传递给形参wd。
题目25用字符's'作为默认实参重写函数make_plural。
利用这个版本的函数输出单词“success”和“failure”的单数和复数形式。
【解答】
//用字符’s’作为默认实参实现函数make_plural。
//利用个这个版本的函数输出单词”successs”和”failure”的单数和复数形式#include
#include
Usingnamespacestd;
//如果ctr不为1则返回word的复数版本
Stringmake_plural(size_tctr,conststring&word,conststring&ending{Return(ctr==1)?
word:
word+ending}
Intmain(){Cout<<”singularversion:
”<”<”<”<题目26Explainthedifferencesbetweenaparameter,alocalvariableandastaticlocalvariable.Giveanexampleofaprograminwhicheachmightbeuseful.解释形参、局部变量和静态局部变量的差别。
并给出一个有效使用了这三种变量的程序例子。
【解答】从本质上说,三者均都属于局部作用域中的变量,其中局部变量又可区分为普通(非静态)局部变量和静态局部点亮。
他们的差别在于:
(1)形参的作用域为整个函数体,而普通(非静态)局部变量和静态局部变量的作用域为:
从定义处到包含该变量定义的块的结束处。
(2)形参由调用函数时所传递的实参初始化;而普通(非静态)局部变量和静态局部变量通常用初始化式进行初始化,且均在程序执行流程第一次经过该对象的定义语句时进行初始化。
静态局部变量的初始化在整个程序执行过程中进行一次。
(3)形参和普通(非静态)局部变量均属自动变量,在每次调用函数时创建,并在函数结束时撤销;而静态局部变量的生命期却跨越了函数的多次调用,它在创建后直到程序结束时才撤销。
例如:
如果需要连续输出1…x之间的所有数的阶乘,可用如下程序:
//读入上限值upLmt,输出(1…upLmt)之间所有整数的阶乘
#include
Usingnamespacestd;
//用于辅助求阶乘的函数
Inttac(intx)//x为形参
{Staticresult=1;//result为静态局部变量
Result*=x;Returnresult;}
Intmain(){IntupLmt;//upLmt为普通(非静态)局部变量
Cout<<”entervalueofupperlimit:
”<>upLmt;
//依次输出(1…upLmt)之间的所有整数的阶乘
For(inti=1;i<=upLmt;++i)
Cout<
=”<Return0;}
题目27Writeafunctionthatreturns0whenitisfirstcalledandthengeneratesnumbersinsequenceeachtimeitis