《C/C++程序員面試寶典》
1, 類型轉換通用的指導原則
1,爲防止精度損失,如果必要的話,類型總是被提升爲較寬的的類型;int和unsigned int因爲類型寬度一樣,則不符合這個規則,兩個變量均轉換爲unsigned int計算;
2,所有含有小於整型的有序類型的算術表達式在計算之前其類型都會被轉換成整型;
2,程序設計問題
1,main主函數執行完畢後,如何在執行一段代碼?
利用aexit()函數註冊一個函數,見P37
2,C++中“”頭文件從工作路徑開始搜索,而<>頭文件從標準庫路徑開始搜素
3,預處理,const和sizeof
1, 用宏表示一年有多少秒:
#define SECONDS_PER_YEAR (60*60*24*365)UL
2,const 和#define的區別:
1)const有數據類型,而宏常量沒有;
2)有些集成化的調試工具可以對const常量調試,但是不能對宏常量調試,C++中只用const而不用宏常量說明前者可以取代後者;
3,結構體對齊問題:
struct A{short a1; short a2; short int a3;}; struct B{long b1; short int b2};
sizeof(A) sizeof(B)分別爲6,8。 我認爲是按照結構體中最寬的類型對齊,文中解釋有問題。
空類的sizeof()爲1, 靜態變量存儲在全局區,所以計算sizeof時忽略它, double的長度爲8,float,int爲4,char爲1
4,sizeof和strlen()函數的區別見 P49
5,sizeof的使用場合
1)主要用途是與存儲分配和I/O系統那樣的例程進行通信。如Malloc, fread函數
...
6,空類和多重繼承的空類都佔空間1,但是空類虛繼承空類的話子空類佔空間爲4
4,指針和引用
1,兩者的區別:
1)非空區別:任何時候都不能指向空值的引用, 不存在指向空值的引用這個事實意味着引用的代碼效率比指針要高;
2)合法性測試:引用在使用之前不需要測試其合法性,而指針總是該被測試,防止其爲空;
3)可修改區別:指針可以被重新賦值以指向另一個不同的對象。而引用總是指向在初始化時被指定的對象,以後不能改變,但是其指向的對象內容可以改變;
4)應用區別:在以下情況應該使用指針,一是存在不指向任何對象的可能性;二是需要在不同的時刻指向不同的對象。如果指向一個對象後不會再改變指向,就應該使用引用。
2,類的this 指針:
1) this只能在成員函數中使用,而不能在全局函數、靜態函數中使用;使用時如同將this指針作爲第一個參數傳入;
2) this在成員函數的開始前構造,在成員函數的結束後清除;
3)this指針根據編譯器的不同存放在不同的位置;
3,函數內用指針實施內存分配:
注意要用指針的指針才能讓函數外的指針指向函數內指針副本分配的空間地址
4,c++中有malloc/free,還引進new/delete的目的:
malloc/free是庫函數而不是運算符,不能把構造函數和析構函數的任務強加給malloc/free,於是引進new/delete來完成內存分配、初始化工作和內存清理、釋放工作。
5,面向對象
1,面向對象編程的基本概念:
面嚮對象語言必須提供類,對象,繼承;
2,空類產生哪些成員函數:
默認構造函數,析構函數,拷貝構造函數和賦值函數;
3,類中的靜態成員記得賦初值。
4,類中,常量const必須在構造函數的初始化列表裏賦值,或者設置爲static;
5,析構函數可以是內聯函數;在有派生類出現時,定義爲虛函數是必要的,這樣保證了在任何繼承情況下不會出現派生類的析構函數未被調用而出現內存泄露的情形;
6,構造函數不能爲虛函數:自己理解的原因:保證語言的邏輯正確性,父類的構造函數若能調用派生類的構造函數,可能初始化派生類中存在而父類不存在的成員變量,出現錯誤。
7,所有需要分配系統資源的用戶自定義類型都需要定義拷貝構造函數;有一個默認的拷貝構造函數
8,多態,可以看成是一個接口,多個方法; 繼承的目的是代碼重用(以前的說法),而多態的目的是接口重用。
重載overload(函數同名函數表不同的函數), 覆蓋override:虛函數在派生類中被改寫。
6,繼承與接口
1,私有繼承與保護繼承的區別:在無繼承的類中,兩者是沒有區別的;在有繼承的類中,基類的Private成員對所有外界都屏蔽,基類的protected控制符對應用程序是屏蔽的,對其直接派生類是可訪問的,但同樣不能往下繼承。
2,C++中如何阻止一個類被實例化? 使用抽象類,或者構造函數被聲明爲Private
3,構造函數在什麼情況下聲明成private?比如要阻止編譯器生成默認的拷貝構造函數
7,COM組件對象模型
COM不是接口,不是對象,也不是標準,符合COM標準的對象就是COM對象。其實COM對象無非是實現了很多接口的對象而已
8,位運算
1,printf("%f",3); 整數3以0000 0000 0000 0000 0000 0000 0000 0011的形式壓入棧
printf函數輸出的應該是內存爲0000 0000 0000 0000 0000 0000 0000 0011 **** **** **** **** **** **** **** ****的double型數據,double的第一位爲符號位,後11位爲指數位(全0 表示-1023),後52位爲尾數位。
所以,這個double型數據應該等於一個大於1小於2的數乘上2^(-1023),是一個非常小的數,輸出取六位小數,所以爲0.000000
2,十進制=8進制/10*8+8進制%10
8進制=10進制/8*10+10進制%8
3,C++中的4種運算符轉化:
const_cast:消除const屬性的轉換;
static_cast:強制隱性轉換,類似於C-style的轉換,如int轉換爲double,也可以non-const轉換爲const,也可以用來反向轉換,如void*轉換爲有類型的指針;
dynamic_cast:安全的向下轉型,涉及到繼承類型的轉換;
reinterpret_cast:底層的強制轉換,如指針轉換爲整型;
4,一個字節取的最大整數是255,兩個字節(如short int)取的最大整數是65535
5,