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函數體無法使用傳過來的行參
初學:
《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函數體無法使用傳過來的行參
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.