c++筆記01---c++ 簡介,g++ 編譯器,名字空間,結構,聯合,枚舉

1. C++ 相關書籍
    初學:
        《C++ Primer plus》
    進階:
        《C++ Primer》
        《Effective C++》
        《More Effective C++》
    深入:
        《C++程序設計語言》作者:B jarena Stroustrup,機械版
        《深度探索C++對象模型》
    休閒閱讀:
        《C++語言99個常見錯誤》
        《C++語言的設計於演化》作者:B jarena Stroustrup

2.    計算機語言發展史:
    1960 - Algol 60,算法語言,缺點:遠離硬件,不適合進行系統開發;
    1963 - CPL,劍橋大學在 Algol 60 的基礎上增加對系統開發的支持,缺點:複雜,不易掌握
    1970 - BCPL,麻省理工(MIT)對 CPL 進行精減,易學易用,缺點:太慢;
    1972 - B 語言,貝爾實驗室 Ken Thomposon(肯*湯普森),通過運行時支持優化 CPL 的性能;缺點:缺少類型;
    1973 - C 語言,Dennis Ritchie(丹尼斯*裏奇),重新實現 UNIX 內核;運行快,適合作系統開發;
    1978 - 《The C Programming Language》,第一個 C 語言的事實標準;
    1989 - ANSI C,C89,美國國家標準化委員會標準 C;
    1990 - ISO C,C90,國際標準 C;
    1999 - ISO C 修訂,C99;

    1983 - C++ 命名;(197x出現)
    1985 - CFront 1.0 第一款商用 C++ 編譯器;
    1987 - GNU C++
    1990 - Borland C++
    1992 - Microsoft C++, IBM C++
    1998 - ISO C++98
    2003 - ISO C++03
    2011 - ISO C++2011/C++11/C++0x

    www.tiobe.com (國際計算機排行榜)

3.    C++ 使用領域:
    1)遊戲開發:需要非常強的建模能力,性能高;
    2)科學計算:原來使用 FORTRAN 語言;算法庫;
    3)網絡和分佈式:ACE框架;
    4)桌面應用:主要指 windows 桌面,VC/MFC,Office,QQ等;
    5)操作系統和設備驅動:優化編譯器的發明;
    6)移動終端;

    既需要性能,同時又需要面向對象建模就選擇 C++;

4.    C++ 比 C豐富:
    1)支持面向對象,將問題域和方法域同一化。
        宏觀:面向對象;
        微觀:面向過程;
    2)支持泛型編程:
        template <typename T>
        T add(T a, T b){ ... }
    3)支持異常機制;
    4)操作符重載;

5.    源文件擴展名:.cpp/.cc/.C/.c++/.cxx,最好使用 .cpp,提高源文件兼容性;
        創建方法同 c 語言;
    cout:輸出 - 標準輸出對象,對應c裏面的 stdout:fprintf(stdout...
    cin:輸入 - 標準輸入對象,對應c裏面的 stdin
    << :插入運算符
    >> :提取運算符

    #include <iostream>        // 大多數輸入輸出流頭文件沒有 .h
    int main(void)
    {
        int i = 0;
        double d = 0;
        char s[5];
        std::cin >> i >> d >> s;                                    // std 命名空間,:: 作用域
        std::cout << i << ' ' << d << ' ' << s << std::endl;    // 這裏有endl;
        return 0;
    }

    使用g++編譯器,如果使用gcc需要加上 -lstdc++,指定其使用標準c++運行庫;
        g++ hello.cpp
        gcc hello.cpp -lstdc++
    如果要用新版c++的一些特性,需要加上 -std=c++0x
        g++ hello.cpp -std=c++0x
    如果把c++文件的擴展名改爲 .c,可以用下面兩種方式編譯:
        g++ hello.c
        gcc -x c++ code.c -lstdc++

6.    名字空間
    定義名字空間:
    namespace 名字空間名 {名字空間成員};

    使用名字空間:
    1)作用域限定符:    名字空間名 : : 名字空間成員
        只可以訪問該名字空間指定的空間成員;
    2)名字空間指令:    using namespace 名字空間名;
        在該條指令之後的代碼對指令所指的名字空間中的所有成員都可見,可直接訪問,無須加“ : : ”;
    3)名字空間聲明:    using 名字空間名 : : 名字空間成員;
        將指定名字空間中的某個成員引入當前作用域;

    名字空間指令和名字空間聲明最大的區別是:
        名字空間指令不改變作用域;
        名字空間聲明則引入了作用域;

    匿名名字空間:
        如果一個標誌符沒有被定義在任何名字空間中,編譯器會將其缺省爲匿名名字空間中;訪問方式如下:
            : : 名字空間成員

7.    名字空間遵循合併原則 ??

8.    名字空間嵌套
    namespace ns1 { namespace ns2 { namespace ns3 { food(){...}}}}
    作用域調用:    ns1::ns2::ns3::food();
    指令調用:        using namespace ns1::ns2::ns3;            food();

9.    c++ 中結構體
    1)定義結構可以省略 struct 關鍵字
    2)結構體內部可以定義函數---成員函數;
        同理,變量叫做成員變量;(c 裏面不能定義函數)
    3)sizeof (空結構)
        返回值爲 1;(c 裏面返回 0)
    4)c++ 默認爲 private,c 默認爲 public;

10.    聯合 union
    和 c 相比,增加了匿名聯合;
    匿名聯合借用聯合語法形式,描述一些變量在內存中的佈局方式;
    c++ 裏聯合可以省略關鍵字 union;
    
    聯合一般用於判斷計算機大小端:
    計算機中存儲數據有兩種方式:
    把低位數據存儲在低地址字節中的方式叫做小端存儲(小低低),反之叫大端存儲。
    union {
        int i;
        char a[4];
    }
    i = 0x12345678;
    for(int i = 0; i < 4; ++i)
        cout << a[i];
    如果輸出:12 34 56 78    爲小端;
    如果輸出:78 56 34 12    爲大端;
    
    問:結構與聯合有和區別?
    答:1) 結構和聯合都是由多個不同的數據類型成員組成,
    但在任何同一時刻, 聯合中只存放了一個被選中的成員(所有成員共用一塊地址空間),
    而結構的所有成員都存在(不同成員的存放地址不同)。
    2) 對於聯合的不同成員賦值 , 將會對其它成員重寫 , 原來成員的值就不存在了 ,
    而對於結構的不同成員賦值是互不影響的。


11.    枚舉 enum
    是一個獨立的數據類型;
    關鍵字也可以省略;
    
    相對於 C 的整數類型枚舉,C++ 提供了真正意義上的枚舉類型;
    
    C語言裏面:(enum 當整型處理)
    enum E {a, b, c};
    E e;
    e = a;
    e = 1000;        // 合法,

    C++語言裏面:
    enum E {a, b, c};
    E e;
    e = a;
    e = f;            // 報錯,超出作用域
    e = 1000;        // 報錯,數據類型不對
    e = 1;        // 報錯,同上

12.    布爾類型,返回值是 true 或者 false,也就是 1 和 0; 佔用 1 個字節;
    等號右邊可以是任何類型,編譯器都認爲 true;(非零即真)
    bool b = true;
    b = "hello";    b = 5.44;                // 返回值爲 1
    cout << b << endl;                    // 輸出:1
    cout << hex << b << endl;            // hex返回十六進制整數:1
    cout << boolalpha << b << endl;        // boolalpha返回true或false,本程序返回:true

13.    運算符別名(一般是嵌入式,鍵盤不全的情況下使用)
    && --- and
    ||---or
    &---bitand
    ^---xor
    !---not
    { --- <%
    } --- %>
    [ --- <:
    ] --- :>

14.    函數
    1)重載:在同一個作用域中,函數名相同,參數表(參數類型)不同的函數,構成重載關係;(c沒有重載)
        和返回值沒關係,例如:
            void foo(int a) 和 int foo(int a)         不構成重載關係,因爲參數類型一樣;且編譯器會報重定義錯誤;
            void foo(int a) 和 int foo(double b)     構成重載關係,只和參數有關係,和返回值無關;
        和參數表類型的順序也有關係,和參數名沒關係,例如:
            void foo(int a, double b) 和 void foo(double a, int b) 構成重載;
            void foo(int a, double b) 和 void foo(int b, double a) 不構成重載;且編譯器會報重定義錯誤;
    
    重載時,編譯器會自動對函數作換名;如果不換名,使用 extern 關鍵字;
    extern 可以指示編譯器按 C 的命名方式編譯,這樣在 C 裏面可以直接調用這個函數
        這種情況下就不能用重載方式了,使用規則如下:
        extern "C" int foo(int a, int b) {...};        // 這裏 foo 函數一定不能重載,否則編譯報錯
        extern "C" { int foo(int a, int b) {...}}    // 可以在{ ... }裏定義多個函數
    
    extern 可以置於變量或者函數前,以表示變量或者函數的定義在別的文件中,
    編譯器遇到此變量或者函數的時候,在其他模塊中尋找其定義;
    
    問:如何引用一個已經定義過的全局變量 ?
    答:可以用引用頭文件的方式,也可以用 extern 關鍵字,
    如果用引用頭文件方式來引用某個在頭文件中聲明的全局變量,
    假定你將那個變量寫錯了,那麼在編譯期間會報錯;
    如果你用 extern 方式引用時,假定你犯了同樣的錯誤,
    那麼在編譯期間不會報錯,而在連接期間報錯。
    在後面學習庫函數的時候會經常用到。

15.    缺省參數
    void foo (int a, double b, char *c = "hello") {}
    下面調用:
    foo(1, 3.2);                                            // 輸出:1 3.2 hello

    缺省值遵循靠右原則,這裏如果a有缺省值,那麼a右邊的所有參數必須都有缺省值;
    注意:void foo(int a = 2, double b, char *c = "hello"){}        // 編譯錯誤

    如果聲明和定義是分開的,那麼缺省參數只能放在聲明裏;
    因爲缺省參數是給編譯器用的,編譯器只關心聲明部分,從聲明部分獲取缺省參數;
    同時,定義缺省參數的時候也要避免和重載發生歧義;
        void foo (int a = 10) {}
        void foo (int a, double = 2.35) {}
        int main () {
            foo ();            // ok
            foo (5);            // error,有歧義,編譯錯誤;
            foo (5, 2.55);    // ok
        }
    
    缺省默認值參數在一定程度上可以減少重載函數個數,減輕代碼量;

16.    啞元參數:只有類型沒有名字的行參;
    一般用於向下兼容;或者函數名不能變更的特殊情況下;
    void foo(int, int) {}                                // foo函數體無法使用傳過來的行參
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章