C primer習題筆記

2021-06-27 18:23:23 字數 4758 閱讀 2324

1、解釋下面每個函式模板的定義並指出是否有非法的,改正所發現的錯誤。

(e)typedef char ctype;

templatectype f5(ctype a);

【解答】

(e)合法,定義了乙個模板函式f5,該函式的返回型別與形參型別相同,均可繫結到任何型別(而不一定是char型別)。

2、何時必須使用typename?

【解答】

如果要在函式模板內部使用在類中定義的型別成員,必須在該成員名前加上關鍵字typename,以告知編譯器將該成員當作型別。

3、編寫乙個函式模板,接受表示未知型別迭代器的一對值,找出在序列中出現得最頻繁的值。

【解答】

template t::value_type mostfreq(  tfirst, t last  )

//  定義型別別名

typedef  std::vectorvectype;

//  建立vector物件,用於儲存輸入序列的副本

vectype vec(amount);

vectype::iterator  newfirst  = vec. begin();

vectype::iterator  newlast  = vec. end();

//  將輸入序列複製到vector物件

std::uninitialized_copy(  first, last , newfirst  );

std::sort  ( newfirst,  newlast );   //  對副本序列排序,使得相同的值出現在相鄰位置

std::size_t maxoccu  = 0, occu = 0; //  出現最頻繁的次數,當前值的出現次數

vectype::iterator  preiter = newfirst;  //指向當前值的前乙個值

vectype::iterator  maxoccuelement  = newfirst;  // 指向當前出現最頻繁的值

while(  newfirst  != newlast )

occu  = 0; 

}++occu;

preiter  =  newfirst;

++newfirst;

}//  最後乙個值的出現次數與目前的最大次數進行比較

if  ( occu  > maxoccu  )

4、所謂「例項化」,指的是產生模板的特定型別例項的過程。模板不能直接使用,必須在使用時進行例項化。類模板的例項化在引用實際模板類型別時進行,函式模板的例項化在呼叫它或用它對函式指標進行初始化或賦值時進行。

5、指出對模板實參推斷中涉及的函式實參允許的型別轉換。

【解答】

const 轉換:接受 const 引用或 const 指標的函式可以分別用非 const 物件的引用或指標來呼叫,無需產生新的例項化。如果函式接受非引用型別,形參型別和實參都忽略 cosnt,即無論傳遞 const 或非 const物件給接受非引用型別的函式,都使用相同的例項化。

陣列或函式到指標的轉換:如果模板形參不是引用型別,則對陣列或函式型別的實參應用常規指標轉換。陣列實參將當做指標其第乙個元素的指標,函式實參將當做指向函式型別的指標。

6、使用顯式模板實參,使得可以傳遞兩個字串面值呼叫compare。

【解答】

只需按如下方式使用顯式模板實參:

compare("mary","mac")

亦可採用如下強制型別轉換方式:

compare(static_cast("mary"),static_cast("mac"))

或compare(std::string("mary"),std::string("mac"))

7、對於下面的 sum 模板定義:

template t1 sum( t2, t3 );

解釋下面的每個呼叫,是否有錯?如果有,指出哪些是錯誤的,對每個錯誤,解釋錯在**。

double  dobj1,  dobj2;   float  fobj1,  fobj2;   char  cobj1, cobj2;

(a) sum ( dobj1, dobj2 );

(b) sum< double, double, double > ( fobj2, fobj2);

(c) sum( cobj1, cobj2 );

(d) sum < double, , double > (fobj2, dobj2);

【解答】

(a)錯誤,沒有顯示指定 t1 實參型別。

(b)正確,產生  double sum ( double, double)  的例項,並將兩個函式實參由 float 轉換為 double 型別來呼叫該例項。

(c)正確,產生 int sum( char, char )的例項。

(d)錯誤,只有最右邊形參的顯示模板實參可以省略,不能用空格代替被省略的顯示模板實參。

8、每個帶標號的語句,會導致例項化嗎?如果會,解釋導致什麼樣的例項化。

templateclass stack {};

void f1(stack);                          //(a)

class exercise;

template< int hi, int  wid > class screen ;

(a ) const int hi = 40, wi = 80; screen< hi, wi + 32> sobj; 

(b)  const  int  arr_size  =  1024;  array<  string, arr_size > a1;

(c) unsigned int  asize  = 255; array< int, assize  > a2;

(d)  const  double  db  =  3.1415;   array<  double,  db> a3;

【解答】

(a)  和  (b)  有效。

(c)  無效,因為非型別模板實參  必須是  編譯時常量表示式,不能用變數 asize 做模板實參。

(d)  無效,因為 db 是 double 型常量,與模板中的 int型模板實參不符。

10、定義函式模板count計算乙個vector中某些值的出現次數。

【解答】

template

size_t count( const vector&vec,const vector&sought)

size_t result = 0;

for( typename vector::const_iterator iter = sought.begin();iter != sought.end();++iter)

result +=std::count(vec.begin(),vec.end(),*iter);

return result;

利用標準庫中提供的泛型演算法count計算指定值在vector中的出現次數,sought也是乙個vector,用於存放要查詢的那些值。

11、對於定義的compare函式和變數,解釋下面每個函式呼叫中,哪個函式被呼叫以及為什麼。

templateint compare(const t&,const t&);

templateint compare(u , u , v);

int compare(const char*,const char*);

char ch_arr1 = "world",ch_arr2 = "hi";const char const_arr1 = "world",const_arr2 = "hi";

(a)compare(ch_arr1, const_arr1);

(b)compare(ch_arr2, const_arr2);

(c)compare( 0 , 0 );

【解答】

(a)和(b)呼叫比較c風格字串的普通函式,對於這兩個函式呼叫,候選函式只有比較c風格字串的普通函式,因為比較簡單物件的模板函式只能例項化為兩個形參型別相同的函式,而比較兩個序列元素的模板函式帶有三個形參。

(c)呼叫比較簡單物件的模板函式的例項(將t繫結到int)。對於這個函式呼叫,將t繫結到int的比較簡單物件的模板函式例項化以及比較c風格字串的普通函式均可作為候選函式,但前者是完全匹配,而後者需要從int到const char*的轉換,所以優先選擇前者。

12、對於下面的每個呼叫,列出候選函式和可行函式,指出呼叫是否有效,以及如果有效,呼叫哪個函式。

templatet calc(t,t);

double calc(double ,double);

template<> char calc(char,char);

float fd;

(a)calc(0,fd);

(b)calc(0 , 'j');

【解答】

(a)候選函式為:double calc(double,double);因為兩個實參乙個為int,乙個為float,均可轉換為double。

(b)候選函式為:double calc(double,double);因為兩個實參乙個為int,乙個為char,均可轉換為double。

13、exception *p = &r;

throw *p;

如果throw語句寫成throw p,會發生什麼情況?

【解答】

如果r是乙個區域性物件,則throw p丟擲的p是指向區域性物件的指標,那麼,在執行對應異常處理**時,有可能物件r已不再存在,從而導致程式不能正常執行。所以,通常throw語句不應該丟擲指標,尤其是不應該丟擲指向區域性物件的指標。

14、對於如下的基本c++程式

int main()catch(const exception &e){

cerr

C primer習題筆記第4章

1 解釋下列宣告語句,幵指出哪些是非法的,為什麼?d int ip,ip2 e const int i 0,p i 解答 d 合法。定義了 int 物件 ip2 和指向 int 型物件的指標 ip。e 合法。定義了 const int 型物件 i 和指向 const int 型物件的指標 p,i 初...

C primer習題筆記第7 9章

1 下面的程式雖然是合法的,但可用性還不夠好,指出並改正該程式的侷限。bool test string s 解答 其侷限在於 此處使用引用形參的唯一目的是避免複製實參,但沒有將形參定義為const引用,從而導致不能使用字串字面值呼叫該函式 因為非const引用形參只能與完全同型別的非const物件關...

C primer 習題筆記第13 15章

1 下面第二個初始化不能編譯。可以從 vector 的定義得出什麼推斷?vectorv1 42 vectorv2 42 解答 若能編譯成功說明,這是個複製初始化,建立 v2 時,首先呼叫接受乙個 int 型形參的 vector 建構函式,建立乙個臨時 vector 物件,然後再呼叫複製建構函式用這個...