當前位置:吉日网官网 - 傳統節日 - C++語法高手進

C++語法高手進

C 基本語法(上)

0. 編譯C 程序時,編譯器自動定義了壹個預處理名字__cplusplus,而編譯標準C時,自動定義名字__STDC__。另外幾個比較有用的預定義名字是__LINE__(文件的當前編譯行數),__FILE__(當前被編譯的文件名字),__DATE__(編譯日期)和__TIME__(編譯時間)。

1. C庫頭文件的C 名字總是以字母C開頭,後面去掉後綴.h的C名字,如在C 庫中的名字是。兩種使用方法:

#include 或者

#include

using namespace std;

2. 靜態與動態內存分配的兩個主要區別:(1)靜態對象是有名字的變量,可以直接進行操作,動態對象是沒有名字的變量,可以通過指針間接進行操作;(2)靜態對象的分配和釋放由編譯器自動處理,而動態對象必須由程序員顯式的管理,通過new和delete兩個表達式來完成。

3. 類的缺省構造函數是不需要用戶提供任何參數的構造函數。

4. STL中標準數組-vector(文件),兩種遍歷方式:(1)通過下標操作符;(2)使用叠代器,如vector<int>::iterator iter;可以通過對iterator解引用來直接訪問實際的元素*iter;STL提供了作用於容器類型的泛型算法,頭文件。

5. 文字常量是不可尋址的。

6. 常用的幾個轉義序列:

newline(換行符) \n \14

horizontal tab(水平制表符) \t

vertical tab(垂直制表符) \v

backspace(退格符) \b

carriage return(回車鍵) \r

formfeed(進紙鍵) \f

alert (bell)(響鈴符) \a \7

7. 變量和文字常量都有存儲區,區別在於變量是可尋址的,對於每個變量,都有兩個值與之關聯:數據值,稱為對象的右值,是被讀取的值,文字常量和變量都可以用作右值;地址值,被稱為變量的左值,是位置值,文字變量不用被用作左值。

8. 每個指針都有壹個相關的類型。不同數據類型的指針之間的區別在於指針所指的對象的類型上。如果我們需要的僅僅是持有地址值,C 提供了壹種特殊的指針類型:空(void *)類型指針,它可以被任何數據指針類型的地址值賦值,除了函數指針。不能操作空類型指針所指向的對象,只能傳送該地址值或將它與其他地址值做比較。

9. C風格的算法循環:

while(*p ){…}

10. 正確定義引用,如下:

const int ival = 1024;

const int *&pi_ref = &ival; // 錯誤,pi_ref是壹個引用,它指向定義為const的int型對象的壹個指針,引用不是指向常量,而是指向了壹個非常量指針

const int *const &pi_ref = &ival; // OK

11. 指針和引用有兩個主要區別,引用必須總是指向壹個變量;如果壹個引用給另外壹個引用賦值,那麽改變的是被引用對象而不是引用本身。

12. 布爾類型對象雖然也被看作整數類型的對象,但是它不能被聲明為signed,unsigned,short或long。

13. 壹個數組不能被另外壹個數組初始化,也不能被賦值給另外壹個數組,而且,C 不容許聲明壹個引用數組。

14. 數組標誌符代表數組中的第壹個元素的地址。它的類型是數組元素類型的指針。

int ia[10];

第壹個元素的地址: ia或者是&ia[0]

第二個元素的地址: ia 1或者是&ia[1]

15. STL中vector有兩種不同的使用形式:數組習慣,即使用下標操作符,註意只能操作已經存在的成員;STL習慣,使用iterator來操作,對其解引用可以訪問實際的對象,也可以通過加減來移動位置。雷同與5。

16. typedef用來為內置的或用戶定義的數據類型引入助記符號。

typedef char *cstring;

extern const cstring cstr;

其中cstr的類型是 char *const cstr;

17. 當壹個對象的值可能會在編譯器的控制或監制之外被改變時,那麽該變量應該聲明為volatile,編譯器執行的某些例行優化不能應用在已經指定為volatile的對象上。

18. pair類可以在單個對象內部把相同類型或不同類型的兩個值關聯起來。我們可以使用成員訪問符號來訪問pair中的單個元素,他們的名字為first和second。

19. 在類體外定義的內聯成員函數,應該被包含在含有該類定義的頭文件中。

20. setw()是壹個預定義的iostream操作符,它讀入的字符數最多為傳遞給它的參數減壹。如setw(1024),則最多讀入1023個字符。

21. 標準C 頭文件提供了與內置類型表示有關的信息,另外,還有標準C頭文件和。

22. 對於二元操作符<或者>,左右操作數的計算順序在標準C和C 中是都是未定義的,因此計算過程必須是與順序無關的。如ia[index ]就是未定義的。

23. 初始化過程為對象提供初值,而賦值是用壹個新值覆蓋對象的當前值,壹個對象只能被初始化壹次,也就是在它被定義的時候,而賦值可以多次。如初始化int ival = 1024;賦值 ival = 1025;賦值操作符的左操作數必須是左值。

24. sizeof操作符的作用是返回壹個對象或者類型名的字節長度,返回值類型是size_t,這是壹種與機器有關的typedef定義,可以在文件中找到它的定義。

25. 按位非操作符(~)翻轉操作數的每壹位。移位操作符(<<和>>)將其左邊操作數的位向左或者向右移動某些位,移到外面的位被丟棄,左移操作符從右邊開始用0填充空位。右移操作符,如果是無符號數從左邊開始插入0,否則它或者插入符號位的拷貝或者插入0,這由具體實現定義。按位與(&)對兩個操作數的每壹位進行與操作(只有兩位同時為1時值才為1)。按位異或(^)操作符對兩個操作數的每壹位進行異或操作(只有兩個含有壹個1時值才為1,即兩位不同值為1)。按位或(|)操作符對兩個操作數的每壹為進行或操作(只有兩位同時為0時值才為0)。如將整數a的第27位設為1:a |= 1 << 27;將第27為設為0:a &= ~(1 << 27) ;測試第27位是否為1:a & (1 << 27)。

26. bitset類,頭文件為,支持三種構造方式,第壹是直接指定向量長度,如bitset <32> bs;第二是顯式提供壹個無符號參數,如bitset<32> bs(012);將第1和第3位設置為1。第三是傳遞壹個代表1和0集合的字符串參數,還可以標記字符串的範圍,如string bitval(“1111110101100011010101”);bitset<32> bs(bitval, 6, 4);則bs的第1和第5位被初始化為1;如果去掉指定字符串範圍的第三個參數,則範圍是指定的位置開始壹直到字符串的末尾。而函數to_string和to_ulong則把bitset對象轉換為字符串和整型表示。

27. 操作符優先級表

28. 隱式轉換發生在下列情況下:1.混合類型的算術表達式,即算術轉換;2.用壹種類型的表達式賦值給另壹種類型的對象;3.把壹個表達式傳遞給壹個函數調用,表達式的類型和形式參數的類型不相同;4.從壹個函數返回壹個表達式。

29. 算術轉換的兩個原則:1.如果必要的話,類型總是提升為較寬的類型;2.所有含有小於整型的整值類型的算術表達式,在計算之前,其類型都會被轉換為整型。

30. const_cast轉換掉表達式的常量性以及volatile對象的volatile性;如const_cast<char *>ptr;編譯器隱式執行的任何類型轉換都可以由static_cast顯式完成。reinterpret_cast通常對操作數的位模式執行壹個比較低層次的重新解釋。dynamic_cast支持在運行時刻識別由指針或引用指向的類對象。

31. typename是標準C 中新引入的關鍵字,用於template中。

32. 兩個主要的順序容器是list和vector,另外壹個順序容器是deque;兩個主要的關聯容器是map和set。

33. 選擇順序容器類型的壹些準則:(1)隨機訪問,vector比list好得多;(2)已知道元素的個數,則vector比list強;(3)如果不只是在容器兩端插入和刪除元素,則list比vector強很多;(4)除非需要在容器首部插入和刪除元素,則vector比deque好。對於小的數據類型,vector的插入大批量數據的性能比list好很多,而大型數據時則相反,解決方案是只保留大型數據的指針。Reserve函數容許將容器的容量設置成壹個顯式指定的值,resize函數重新設置容器的長度;每個容器支持壹組關系操作符;用戶定義的類類型必須支持等於操作符,必須支持小於操作符,元素類型必須支持壹個缺省值(對類類型,指缺省構造函數)。

34. 除了iterator類型,每個容器還定義了壹個const_iterator類型,對遍歷const容器是必需的,const_iterator容許以只讀方式訪問容器的底層元素。Iterator算術運算(是指加法或者減法等算術運算,而不是重載的 操作符)只適用vector或deque,而不適用於list因為list在內存中不是連續存儲的。

35. string類的find函數返回壹個索引類型string::size_type或者返回string::npos;find_first_of提供了被搜索字符串中任意壹個字符相匹配的第壹次出現,並返回它的索引位置,substr函數生成現有string對象的子串的壹個拷貝,第壹個參數指明開始的位置,第二個可選的參數指明子串的長度。rfind,查找最後的指定子串的出現;find_first_not_of查找第壹個不與要搜索字符串的任意字符相匹配的字符;find_last_of查找與搜索字符串任意元素相匹配的最後壹個字符;find_last_not_of查找字符串中的與搜索字符串任意字符全不匹配的最後壹個字符。

36. tolower函數接受壹個大寫字符,並返回與之等價的小寫字母,必須包含頭文件,另外壹些該文件中的函數,isalpha, isdigit, ispunct, isspace, toupper等。

37. assign對把字符串進行賦值;append則類似於 =操作符;swap交換兩個string的值;進行越界檢查的at類似於[]操作符;compare函數提供了兩個字符串的字典序比較;replace函數提供了十種方式,可以用壹個或者多個字符替換字符串中的壹個或多個現有的字符。

38. map定義了壹個類型value_type,表示相關的鍵值對,用於insert函數。

39. 關聯容器支持以下兩個函數:find查找指定key,不存在則返回end();count返回指定key值的出現的次數。

40. set定義了壹個類型difference_type,是兩個iterator相減的結果類型;inserter類用來執行插入操作。如:copy(in, eos, inserter(set1, set1.begin());因為copy執行的是賦值操作,所以使用inserter使用插入操作取代賦值操作。

41. multiset和multimap的特殊操作equal_range返回iterator對值,如:pair pos; pos = mp.equal_range(tst);

42. stack類,頭文件,函數top和pop分別是訪問棧頂元素和刪除棧頂元素。棧類型是容器適配器,因為它把棧抽象施加到底層容器上,缺省情況下棧使用deque實現,可以自定義缺省的底層容器,如使用list構建stack:stack<int, list<int> > intStack;

43. C 中,數組永遠不會按值傳遞,它總是傳遞第壹個元素(準確的說是第0個)的指針。多維數組被傳遞為指向第0個元素的指針。如matrix[][10]等同於int (*matrix)[10],都表示matrix是個二維數組,每行10列。而int *matrix[10]表示壹個含有10指向int的指針的數組。

44. UNIX系統函數chmod改變文件的保護級別,它的函數聲明在系統頭文件中。

45. 鏈接指示符的第壹種形式由關鍵字extern後跟壹個字符串常量以及壹個普通的函數聲明構成,如extern “C” void exit();第二種形式是是多個函數聲明用大括號包含再鏈接指示符復合語句中。鏈接指示符不能出現在函數中,而且放在頭文件中更合適。

46. 支持命令行格式的主函數:int main(int argc, char *argv[]);

47. 指向函數的指針,如int (*pFunc)(int, int);將取地址符作用於函數名上也能產生指向該類型的指針。如已經存在函數定義int f1(int); int (*pf1)(int)=f1; int (*pf2)(int)=&f1;函數調用可以使用pf1(1)格式或者(*pf1)(1)格式。當壹個函數名沒有被調用操作符修飾時,會被解釋為該類型函數的指針,如存在函數定義int f(int);表達式f被解釋為int (*)(int)。

48. 函數指針數組的定義:int (*testCases[10])();使用typedef可以使聲明更易讀。如typedef int (*PFV)(); PFV testCases[10];聲明壹個“指向函數指針數組的指針”,如PFV (*pArray)[10];調用其中函數(*pArray)[2]();

49. 函數參數的類型不能是函數類型,函數類型的參數將被自動轉換為該函數類型的指針。如存在函數類型typedef int funtype(int);void sort(int, funtype);與函數定義sort(int, int(*)(int));等價。函數指針也可以作為函數返回值的類型,如int (*ff(int))(int *, int);該聲明將ff聲明壹個函數,它有壹個int的參數,它的返回值為壹個指向函數的指針,類型為int (*)(int *,int);

50. 指向C函數的指針與指向C 的函數指針類型不同,也就是:int (*fcpp)(int)與extern “C” int (*fpc)(int)類型不同。並且,當鏈接指示符作用壹個聲明上時,所有被它聲明的函數都受影響,如extern “C” void f1(void (*pfParm)(int));其中pfParm也是C函數指針。因此,要實現壹個含有C函數指針作為參數的C 函數,可以使用typedef,如extern “C” typedef void FC(int); C 函數 void f2(FC *pfParam);

51. 關鍵字extern為聲明但不定義提供了壹種方法,extern聲明不會引起內存被分配。

52. 設計頭文件時不應該含有非inline函數和對象的定義。符號常量的定義和inline函數可以被重復定義多次,在編譯期間,在可能的情況下,符號常量的值會取代該名字的出現,這個過程為常量折疊。符號常量是任何const類型的對象。但是如下定義不符合 char *const buf = new char[10];因為它的值不能在編譯時確定,不能定義在頭文件;const char *msg =”Error”;因為msg不是常量,它是指向常量值的非常量指針,必須修改為const char *const msg=””;

53. 有三種局部對象:自動對象,寄存器對象和局部靜態對象。在函數中頻繁使用的變量可以使用關鍵字register聲明為寄存器對象。

54. delete表達式只能作用於由new表達式從空閑存儲區分配的指針上,如果作用於其他內存指針上,可能導致問題,但是作用於值為0的指針上,delete不會指向任何操作。

55. auto_ptr是STL提供的類模板,可以幫助程序員自動管理用new表達式動態分配的單個對象。頭文件為,只有擁有底層對象所有權的對象負責釋放內存,但使用Copy constructor和Assignment進行操作時,左邊的對象得到所有權,而右邊的則被撤銷所有權。使用get來測試是否指向壹個底層對象,使用reset來重新設置壹個底層對象,assignment操作符不支持內存指針。

56. 可以創建動態的const對象,如const int *pci = new const int(1024);不能創建const對象數組,創建的const對象必須初始化。

57. 定位new表達式容許程序員要求將對象創建在已經被分配好的內存中。如:char *buf=new char [1024];Foo *pb = new (buf) Foo;

58. 可以使用未命名的namespace來聲明壹個局部於某壹文件的實體,即該函數只在當前文件中可見。通常在實現文件中使用,這種方法是用來替換C語言中的static函數聲明。

59. 重載函數,兩個函數的函數名相同,但函數參數表必須不同,參數個數或參數類型不同;識別函數聲明並不考慮傳值參數類型是const或者volatile,即void f(int)和函數void f(const int)是同壹個函數。但是如果是傳地址或者傳引用時,則需要考慮這兩個修飾符。void f(int *)和函數void f(const int *)為不同的函數。

60. 重載函數集合中的所有函數都應該在同壹個域中聲明。using聲明和using指示符可以使得壹個名字空間的成員在另外壹個名字空間可見,這對重載函數集合產生影響。using聲明總是為重載函數的所有函數聲明別名,如果引入壹個函數在該域中已經存在並且參數表相同,則產生錯誤。而extern “C”鏈接指示符只能指定重載函數集中的壹個函數。

61. 函數重載解析的三個步驟(1)確定函數調用考慮的重載函數的集合,確定函數調用中實參表的屬性;(2)從重載函數集合中選擇函數,該函數可以在給定的情況下用實參進行調用;(3)選擇與調用最匹配的函數。在第二步中,編譯器確定需要進行的參數轉換,並劃分等級,通常分為精確匹配;與壹個類型轉換匹配;無匹配。其中類型轉換通常分為三組:提升、標準轉換和用戶定義的轉換。

62. 精確匹配細節:即使壹個實參必須應用壹些最小的類型轉換才能將其轉換為相應函數參數的類型;這些最小的類型轉換包括:左值到右值的轉換;從數組到指針;從函數到指針的轉換和限定類型轉換(通常是const和volatile類型轉換)。精確匹配可以使用壹個顯式強制轉換強行執行,這時實參類型就為轉換後的類型。

C 基本語法(下)

0. 類型轉換中的提示實際上就是內置數據類型的提升,如char轉換為int,bool轉換為int,float轉換為double等。

1. 類型轉換中的標準轉換有五種類型:(1)整值類型轉換(不包括提升);(2)浮點轉換;(3)浮點-整值轉換;(4)指針轉換和(5)bool轉換。前三種轉換是有潛在危險的轉換。所有的標準轉換都是等價的。壹些註意點:0可以被轉換為任何指針類型,這樣創建的指針稱為空指針值,同時0也可以是任何整型常量表達式。常量表達式0L及0x00都屬於整值類型因此能夠被轉換為int *的空指針值。指針轉換允許任何指針類型的實參轉換成void *,但是函數指針不能用標準轉換為void *。

2. 對於引用參數來說,如果實參是該引用的有效初始值,則為精確匹配,否則為不匹配。

3. 模板非類型參數代表了壹個常量表達式,由壹個普通的參數聲明構成,表示該參數名代表了模板定義種的壹個常量。在實例化時,該常量會被壹個編譯時已知的常量值代替。

4. 在模板中,為了支持類型表達式,必須使用typename;如typename Param::name *p;定義了壹個指針p;如果不使用typename則該表達式為乘法。另外,模板函數也可以被聲明為inline或extern,必須把指示符放在參數模板後。如template <typename T> inline T fun1(){…}

5. 函數實參的推演中三種類型轉換是允許的:(1)左值轉換;(2)限定轉換(const和volatile指示符);(3)到壹個基類的轉換:如果實參是壹個類,它有壹個從被指定為函數參數的類模板實例化而來的基類;如下面的代碼:template <typename T> class Array {}; template <typename T> T min(Array &array) {…};

6. 可以使用顯式指定模板參數,模板參數被顯式指定在逗號分隔的列表中,緊跟在函數模板實例的名字後面;如min<unsigned int>(a, b);代碼強行指定模板參數以unsigned int轉換。模板顯式指定參數類似於默認參數,只能省略後面的參數。

7. C 支持兩種模板編譯模式:包含模式和分離模式。包含模式下,在每個模板被實例化的文件中包含函數模板的定義,並且往往把定義放在頭文件中;分離模式下,函數模板的聲明被放在頭文件中,它的定義放在另外壹個實現文件中,函數模板在實現文件中的定義必須使用關鍵字export。

8. C 支持模板的顯式實例化,在顯式實例化聲明所在的文件中,函數模板的定義必須被給出。如template <typename T> T f(T t); 顯式實例化為int *類型,template int *f(int *);

9. C 支持模板的顯式特化定義,如:template <typename T> T max(T t1, T t2){…}顯式特化const char *類型的定義:template <> const char *max<const char *>(const char *c1, const char *c2);顯式特化隱藏了通用模板對於該類型的實例。如果模板實參可以從函數參數中推演出來,則模板實參的顯式特化可以從其中取消。如上面的例子: template <> const char *max(const char *, const char *);其省略與顯式指定模板參數壹樣。

10. 拋出異常可通過throw表達式來實現。如拋出壹個popOnEmpty(類對象)的異常,表達式為throw popOnEmpty();同時在catch子句中,為了防止大型類對象的復制,可以將catch子句的異常聲明改為引用。

11. 在查找用來處理被拋出異常的catch子句時,因為異常而退出復合語句和函數定義,這個過程稱為棧展開。C 保證,隨著棧的展開,盡管局部類對象的生命期是因為拋出異常而結束,但是所有的析構函數將被調用。要重新拋出接受到的異常,使用語句throw;重新拋出的過程中希望對接受到的異常對象進行修改,必須將catch子句的異常聲明改為引用。

12. 異常規範跟隨在函數參數表之後,用throw指定,後面是異常類型表。如void pop(int &value) throw(popOnEmpty);異常規範保證不會拋出任何沒有出現在異常類型表中的異常。如果在運行時拋出壹個沒有出現在異常類型表中的異常,則系統調用C 標準庫中定義的函數unexpected,該函數直接調用了terminate函數結束程序。空的異常規範不會拋出任何異常。

13. 異常規範可以在函數聲明中指出,當有異常規範的指針被初始化時,被用作右值的指針異常規範必須比用作左值的指針規範壹樣或者更嚴格,當然,參數類型表必須相同。

14. 使用函數指針來使得template適應更多的場合。內置的函數指針聲明的模板定義,代碼如下: template< typename Type, bool (*Comp)(const Type&, const Type &)> const Type& min(const Type *p, Comp comp);該方案的主要缺點是函數調用使它無法內聯。使用函數對象來替代函數指針,函數對象是類實現,它重載了調用操作符,即operaotr ()函數。有兩個優點:(1)如果被重載的調用操作符是inline,則編譯器能執行內聯編譯;(2)函數對象可以擁有任意數目的額外數據來緩沖結果。改寫模板使之能同時接受函數指針和函數對象(缺點是沒有任何的原型檢查),template<typename Type, typename Comp> min(const Type *p, Comp comp);

  • 上一篇:100個節日有那些
  • 下一篇:年度活動計劃
  • copyright 2024吉日网官网