c++基本語法(上中下)

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

1.   C庫頭文件的C++名字總是以字母C開頭,後面去掉後綴.h的C名字,如<assert.h>在C++庫中的名字是<cassert>。兩種使用方法:
#include <assert.h>或者
#include <cassert>
using namespace std;

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

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

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

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中的單個元素,他們的名字爲firstsecond

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

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

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

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

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

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

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>,支持三種構造方式,第一是直接指定向量長度,如bitset<32> bs;第二是顯式提供一個無符號參數,如bitset<32>bs(012);將第1和第3位設置爲1。第三是傳遞一個代表1和0集合的字符串參數,還可以標記字符串的範圍,如stringbitval(“1111110101100011010101”);bitset<32> bs(bitval, 6,4);則bs的第1和第5位被初始化爲1;如果去掉指定字符串範圍的第三個參數,則範圍是指定的位置開始一直到字符串的末尾。而函數to_stringto_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. 兩個主要的順序容器listvector另外一個順序容器是deque;兩個主要的關聯容器mapset

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函數接受一個大寫字符,並返回與之等價的小寫字母,必須包含頭文件<ctype.h>,另外一些該文件中的函數,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<iterator,iterator> pos; pos = mp.equal_range(tst);

42. stack,頭文件<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改變文件的保護級別,它的函數聲明在系統頭文件<cstdlib>中

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

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

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

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

49. 函數參數的類型不能是函數類型,函數類型的參數將被自動轉換爲該函數類型的指針。如存在函數類型typedefint 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 = newchar[10];因爲它的值不能在編譯時確定,不能定義在頭文件;const char*msg=”Error”;因爲msg不是常量,它是指向常量值的非常量指針,必須修改爲constchar *const msg=””;

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

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

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

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

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

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

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

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

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

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

發佈了9 篇原創文章 · 獲贊 2 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章