C++ 入門隨手筆記及聯繫

1、第一個C++程序
 一、文件擴展名
  C++源代碼的文件擴展名.cpp、C、cxx、c(須要指定編譯語言)
  自定義的頭文件依然保留.h
 二、頭文件
  C++標準庫的頭文件不帶.h,最經常使用的是iostream
  C語言中的頭文件依然能夠繼續使用,stdio.h或cstdio
 三、輸入輸出
  cout<<輸出
  cin>>輸入
  endl換行
  cout和cin再也不使用佔位符,它能夠自動識別數據類型。
  scanf和printf能夠繼續使用。
 四、編譯器
  gcc也能夠編譯C++的源碼,但須要添加額外的參數
  g++是編譯C++源碼的最簡單的編譯器,通常操做沒有默認安裝。
  ubuntu系統的安裝指令:sudo apt-get install g++
  以前的gcc的編譯參數,依然能夠繼續使用。
  注意:C++編譯時的錯誤提示不是很精準,一個錯誤可能會產生大量的錯誤提示。
 五、引入了名字空間概念
  using namespace std;
2、C++中的基本數據類型
 一、C++徹底兼容C語言中的全部數據類型(C++兼容C語言的全部語法。)。
 二、添加了bool類型、字節寬度1,數值true(非零值),false(零值)。
 三、在顯示bool變量前,使用boolalpha能夠以true或flase的形式顯示bool值。
 四、void* 與其它類型指針的轉換受到限制
  void* 不能夠直接給其它類型的指針賦值,必須通過強制轉換。
  任意類型的指針均可以直接給void*賦值。
3、C++中的聯合、枚舉、結構
 一、在C++中聯合、枚舉、結構設計成功後,再使用不須要加關鍵字。
 二、枚舉的檢查更爲嚴格(C++中的枚舉是一種獨立的數據類型)。
 三、結構成員中能夠有函數,在函數中能夠直接訪問結構的成員。
 四、結構對象能夠繼續使用.或->訪問成員、成員函數。
 五、結構中的成員添加了訪問屬性:
  public:開放的,被它修飾過的成員在任何位置均可以訪問
  private:私有的,被它修飾過的成員只能在成員函數中使用
  protected:之後再說。
 六、結構在建立時會自動調用一個函數-構造函數。
  a、無返回值
  b、名字與結構相同
  c、參數能夠任意
 七、結構在釋放時會自動調用一個函數-析構函數。
  a、無返回值、參數
  b、~結構名
  
 練習:C++的走迷宮。
4、引用
 一、引用就起"外號",爲一個標識符另外再取一個名字。
 二、引用必需初始化,不然編譯錯誤。
 三、引用不光能夠引用標識符,也能夠引用當即數(右值、字面值、常量),但必須加const屬性。
 四、不能定義空引用,但"野引用"或"懸空引用"是存在的(引用了堆內存的數據,當堆內存釋放後就不該該再使用)。
 五、引用只能是一次性的,沒法再更改(引用一旦成功後,它是個變量了這個身份至死不渝)。
 六、引用能夠看成函數的參數,它引用的對象就是函數的實參,因此引用能夠達到指針的效果。
  a、函數之間共享變量
  b、提升參數的傳遞效率(比指針還要高)
  c、能夠獲取參數
  注意:能使用引用就不要再使用指針了。
  引用可否徹底取代指針,不能夠。
 七、引用也能夠看成函數的返回值,但毫不能返回局部變量的引用。
 練習1:使用引用定義一個能夠交換兩人個變量值的函數。
 練習2:定義一個函數,計算兩個整數的最大公約數和最小公倍數,最大公約數使用返回值返回,最小公倍數使用引用返回。
5、C++中的內存管理運算符
 一、在C++中使用 new/delete 來管理內存,new用來申請內存,delete用來釋放內存。
 二、new在內存時容許對內存進行初始化。
 三、使用new建立結構對象時會自動調用構造函數,delete時會自動調用析構函數。
 總結:malloc/free與new/delete的區別?
  一、malloc/free標準庫的函數,使用時還須要添加頭文件,而new/delete是C++語言中的運算符。
  二、malloc返回值的是void*指針,new返回的是有類型的指針。
  三、malloc建立對象時不會調用構造函數,free時不會調用析構函數,但new/delete會自動調用構造和析構函數。
  四、使用malloc使用內存時須要本身計算字節數,而使用new的時候會自動計算。
 四、[]能夠配合new和delete申請或釋放數組。
  new[]與不能夠與delete混用,必須使用delete[]釋放。
  使用new[]/delete[]建立多少個對象就會調用屢次構造和析構。
 五、new/delete與malloc/free不能混用。
 六、delete不能夠重複釋放,但能夠釋放空指針。
 七、若是使用new申請內存失敗會拋出異常"std::bad_alloc",異常的捕獲和處理會在之後講解。
6、C++中的函數
 一、C++中函數能夠在main前執行,C語言中不能夠。
 二、C++中的函數名能夠相同,只要參數不一樣便可(函數重載,不僅是參數)。
  函數能夠同名並非真正意義上的同名,它只在編譯基本把函數的名字添加了額外信息(函數的參數),返回值不算內。
 三、內聯函數
  內聯函數就是把函數編譯成二進制,而後在須要的位置直接把函數拷貝過去,而不是跳轉後再執行,這樣能夠減小進棧、出棧、和調用,以此提升程序的執行效率,但這樣會增長可執行文件的大小。
  內聯函數與宏函數的區別:從本質上來講它們是同樣的,但內聯函數能夠檢查參數,也能夠具備返回值。
 inline 返回值 函數名(參數)
 {
 }
 四、C++中函數的參數能夠有默認值
  一、函數的默認參數要靠右。
  二、默認參數要儘可能要少用,由於可能會引用重載錯誤。
  三、默認參數是編譯器在編譯時幫助賦值的,因此只能由全局變量、靜態變量、字面值對參數進行賦值。
  
 
1、名字空間
 C語言中的名字空間的劃分:全局、局部、塊
 C++認爲:全局空間用起很是方便,但若是把太多的東西放在全局空間會形成命名衝突,因此C++引用了這樣一種機制就是名字空間。
 名字空間:把全局的命名空間進一步分割,能夠建立出一個個獨立的命名空間防止相互之間衝突。
 1、定義名字空間:
 namespace name
 {
  變量;
  函數;
  結構、類;
 }
 2、名字空間的合併
  a、同名的名字空間會自動合併。
  b、在同一個名字空間中只標識符必須是惟一的。
 
 3、定義與聲明分開
 namespace n1
 {
  //在名字空間中聲明函數
  void func(void);
 }
 // 在名字空間外定義函數
 void n1::func(void)
 {
 }
 4、如何使用名字空間中的內容
  a、域限定符(::),直接使用,名字空間::標識符,這樣的好處是絕對不會衝突,但就是麻煩了些。
  b、using namespace 名字空間; 功能是把名字空間中的標識符對以後的代碼所有公開。
  c、using 名字空間::標識符,表示此標識符對後面的代碼公開。
 5、名字空間的嵌套
  名字空間能夠嵌套,但使用時要逐層解析。
  namespace n1
  {
   int num = 10;
   namespace n2
   {
    int num = 20;
    namespace n3
    {
     int num = 30;
    }
   }
  }
  n1::n2::n3::num == 30;
  n1::n2::num == 20;
  n1::num = 10;
  using namespace n1::n2;

 

 六、全局空間歸屬爲匿名空間
  在全局空間定義的標識符都屬於這個匿名空間,匿名空間默認開放。
  若是函數中有同名的標識符把匿名空間中的屏蔽了,可使用空的域限定符表示它。
 注意:不一樣命名空間中的同名函數不構成重載,同一做用域下的同名函數叫重載。
 
2、class
 一、C++的class與struct同樣,是一種複合數據類型。
 二、裏面能夠有變量用來表達屬性,函數用來表示行爲。
 三、在C++的class與struct,幾乎沒有任何區別。
 四、struct中默認訪問屬因而public,class中默認的訪問屬性是private。
 五、在C++默認使用class,以示與C語言中的class進行區分。
 
練習:定義一個Date類: year,month,day,在類裏提供
 一、年月日是否有效,返回bool類型
 二、是不是閏年,返回bool類型
 三、求nextday() ,返回下一天的日期
  四、寫一個nextday(int n)表示n表後的日期,注意n可正可負
 
 一、日期轉換整天數
 二、由天數轉換成日期
3、class的構造函數
 一、在建立對象時自動調用的函數,在整個對象的生命週期中必定會被調用一次,且只能被調用一次。
 二、在構造函數中負責對成員變量的初始化、分配資源、設置對象的初始狀態。
 三、構造函數能夠有多個版本,這些不一樣的版本之間會構造重載,建立對象時的方式不一樣、給的參數不一樣會調用相應的構造函數,若是調用的構造函數不存在可能會形成編譯錯誤。
  // 無參構造
  Student stu <=> Student* stup = new Student;
  Student stu(參數列表) <=> Student* stup = new Student(參數列表);
 四、若是類中沒有定義構造函數,編譯器會自動生成一個無參構造。
  一旦定義了其它版本的構造函數,無參構造就不會再生成了,所以爲了防止無參方式建立對象出錯,在定構造函數時,至少要實現兩個。
 五、無參構造未必無參,在C++中函數能夠有默認參數,若是有參構造所有設置了默認參數,就會和無參數構造有衝突,它們兩個只能有一個存在。
 六、所謂的"編譯器生成的某某函數"
  "編譯器生成的某某函數",不是真正意義上的函數,編譯做爲指令的生成者,只要生成具備某些函數功能的指令即,沒有必須生成高級語言的主義上的函數。
 七、何時調用無參構造
  a、Student stu <=> Student* stup = new Student;
  b、建立對象數組,每一個對象都會調用一次無參構造。
  c、若是類A中有成員是類B,當執行守類A的構造函數前會自動調用類B的無參構造。
  d、在類A中如何調用類B的有參構造
  類A(參數列表):成員類B(參數列表)
  {
   ...
  }   
 八、類型轉換構造函數
  用一個數據給對象初始化,默認會自動調用構造函數,達到類型轉換的效果。
  這種方式雖然使用方便,但也會包容一些錯誤存在,若是想讓代碼檢查更爲嚴格可使用explicit關鍵字禁止隱式轉換的方式調用構造函數。
 九、也能夠實現自動類型轉換構造函數(默認)。
練習:
一、寫一個Date類,有屬性:年、月、日,實現其各類構造函數。
二、寫一個Timer類(屬性定義爲私有,方法定義爲公開)
     有一個屬性 unsigned int second;//second記錄定時器的秒數
     有一個屬性 Action action;//定時器響應動做
     typedef bool (*Action)(void *);
     有一個方法setAction(Action a),當調用begin()方法以後,second秒以後自動調用a函數。
三、使用class方式實現五子棋。
 
相關文章
相關標籤/搜索