【01】C到C++(基礎)
版權宣告:zhuhurry 未經博主允許不得轉載 https://blog.csdn.net/zhuhurry
為什麼要學C++:
C++是更高階的C語言,在保證C語言執行效率的同時具有現在語言的特性、在工業等效能要求較高的領域運用廣泛
C與C++的區別簡介
C語言是一個結構化語言,重在演算法和資料結構,它是程式導向的程式設計思想
C++全面相容C,支援C風格、基於物件、物件導向、泛型、函式式5種程式設計方式
一、bool 布林型
其值為true(邏輯真)和false(邏輯假),儲存的位元組在不同的編譯系統中不同,vc++中為1個位元組。可以當作整數用(true一般為1,false為0)
宣告方式:bool result
把其它型別的值轉換為布林值時,非零值轉換為true,零值轉換為false
二、const 限定符
C++ const 允許指定一個語義約束,編譯器會強制實施這個約束,允許程式設計師告訴編譯器某值是保持不變的。如果在程式設計中確實有某個值保持不變,就應該明確使用const,這樣可以獲得編譯器的幫助。
提高程式的效率:編譯器通常不為普通const常量分配儲存空間,而是將它們儲存在符號表中,這使得它成為一個編譯期間的常量,沒有了儲存與讀記憶體的操作,使得它的效率也很高。
1.修飾變數
int const a= 100;//兩種修飾方法效果一致,變數a的值不可變,必須要初始化
const int a= 100;
2.修飾指標
const int * p; //const在*左邊,表示*p為常量,即p指向的內容不可變
int* const p; //const在*右邊,表示p為常量,指標本身是常量不可變
const int* const p; //兩者都不可變
3.const修飾引數和返回值
(1)const修飾函式引數
void function(const int Var); //傳遞過來的引數在函式內不可以改變(無意義,因為Var本身就是形參,不會改變實參)
void function(const char* Var); //引數指標所指內容為常量不可變
void function(char* const Var); //引數指標本身為常量不可變(也無意義,因為char* Var也是形參)
void function(const int& Var); //引用引數在函式內為常量不可變,引數為引用,為了增加效率同時防止修改,C++中比較常見
(2)const 修飾函式返回值
const修飾函式返回值其實用的並不是很多,它的含義和const修飾普通變數以及指標的含義基本相同。
4.const修飾類的成員函式
const修飾的成員函式不能修改任何的成員變數
const成員函式不能呼叫非onst成員函式,因為非const成員函式可以會修改成員變數
三、#define使用及在定義常量時和const的區別
1.const定義的常量有型別,而#define定義的沒有型別,編譯可以對前者進行型別安全檢查,而後者僅僅只是做簡單替換
2.const定義的常量有型別,而#define定義的沒有型別,編譯可以對前者進行型別安全檢查,而後者僅僅只是做簡單替換
3.作用域不同,const定義的常變數的作用域為該變數的作用域範圍。而#define定義的常量作用域為它的定義點到程式結束,當然也可以在某個地方用#undef取消
#define 替換 在底層實現的時候應用廣泛
#define注意出錯的地方:
#define CALL_WITH_MAX(a,b) f((a) > (b) ? (a) : (b))
int a = 5;
int b = 0;
CALL_WITH_MAX(++a, b); //a被累加二次
CALL_WITH_MAX(++a, b+10); //a被累加一次
四、結構體記憶體對齊
記憶體對齊:編譯器為每個“資料單元”按排在某個合適的位置上,C、C++語言非常靈活,它允許你干涉“記憶體對齊”。
為什麼要對齊
效能原因:在對齊的地址上訪問資料快。
如何對齊
(1)第一個成員與結構體變數的偏移量為0
(2)其它成員要對齊到對齊數的整倍數的地址,(注意是地址)
(3)對齊數取編譯器預設的一個對齊整數與該成員大小的較小值
(4)結構體總大小為最大對齊數的整數倍
如何幹涉“記憶體對齊”
#pragma pack(1) //指定編譯器的對齊整數
struct test{}; //需要對齊的結構體
#pragma pack() //取消設定的對齊整數
五、域運算子(C++新增)::
用於對與區域性變數同名的全域性變數進行訪問
用於表示類的成員,這將在關於類的一節中詳細說明
六、new、delete運算子
new運算子可以用於建立堆空間,成功返回首地址
指標變數=new 資料型別 int *p; p=new int;
指標變數=new 資料型別[長度n]; char *pStr=new char[50];
delete運算子 可以用於釋放堆空間
delete 指標變數; delete p;
delete [] 指標變數; delete [] pStr;
new一個新物件
記憶體分配(operator new)
呼叫建構函式
delete釋放一個物件
呼叫解構函式
釋放記憶體(operator delete)
七、過載
相同的作用域,如果兩個函式名稱相同,而引數不同,我們把它們稱為過載overload,函式過載又稱為函式的多型性,呼叫過載函式時,編譯器通過檢查實際引數的個數、型別和順序來確定相應的被呼叫函式。
函式過載不同形式:
形引數量不同 形參型別不同
形參的順序不同 形引數量和形參型別都不同
注意,如果函式的返回型別不同,但函式名、引數相同,則不是過載,編譯器報錯
八、name managling與extern “C”
name managling這裡把它翻譯為名字改編,C++為了支援過載,需要進行name managling
extern “C”實現C與C++混合程式設計, 即對C語言寫的函式不進行改名。如果我們在c++編譯環境中沒有使用extern “C”來引用C的函式,則C++編譯器會對其函式名進行改編,則找不到對應的函式實現。
我們一般書寫格式如下:
#ifdef __cpluscplus //如果是C++編譯器,則引用extern “C”
extern “C”
{
#endif
...
#ifdef __cpluscplus
}
#endif
這樣書寫的方便之處是當書寫的程式碼可用於C和C++語言,不需要做修改。
九、帶預設形參值的函式
函式宣告或者定義的時候,可以給形參賦一些預設值、呼叫函式時,若沒有給出實參,則按指定的預設值進行工作。
需要注意的地方:
1.若函式具有多個形參,則預設形參值必須自右向左連續地定義,並且在一個預設形參值的右邊不能有未指定預設值的引數。
void func1(int a, double b=4.5, int c=3); //合法的
void func1(int a=1, double b, int c=3); //不合法的
在呼叫一個函式時,如果省去了某個實參,則直到最右端的所有實參都省去
int f(int a, float b=5.0, char c='c', int d=10);
f(9,4.5) == f(9,4.5,'c') == f(9,4.5,'c',10)
2.預設形參值的說明必須出現在函式呼叫之前,如果存在函式的宣告則在函式的宣告中給預設值,一般不再函式定義中給預設值。如果不存在很熟宣告則在函式定義中給預設值。若函式原型中已給出了形參的預設值,則在函式定義中不得重複指定,即使所指定的預設值完全相同也不行。
int sub(int x=8,int y=3);
int sub(int x=8,int y=3){ //不合法、重複指定
return x+y;
}
需要注意的錯誤:
sum=add(10,20)語句產生二義性性,可以認為該語句是呼叫第一個函式,也可以是第二個,因此編譯器不能確定呼叫的是哪一個函式。
十、namespace名稱空間
所謂namespace,是指識別符號的各種可見範圍。C++標準程式庫中的所有識別符號都被定義於一個名為std的namespace中。
為了避免在大規模程式的設計中識別符號名稱發生衝突,標準C++引入了namespace,可更好的控制識別符號的作用域。c++標準為了和C區別開,也為了正確使用名稱空間,規定標頭檔案不使用字尾.h。
C語言中只有一個全域性作用域,所有的識別符號共享一個作用域,識別符號之間可發生衝突,而在C++中,名稱空間將全域性作用域分成不同的部分,不同名稱空間中的識別符號可以同名而不會發生衝突,命令空間可以相互巢狀,全域性作用域也叫預設名稱空間
名稱空間的定義:
namespace name {...}
名稱空間的使用:
使用整個名稱空間:using namespace name
使用名稱空間中的變數:using name::variable
使用預設名稱空間中的變數: ::variable
預設情況下可以直接使用預設名稱空間中的所有識別符號
十一、“實用性”增加
C語言中的變數都必須在作用域開始的位置定義
C++中更強調語言的“實用性”,所有的變數都可以在需要使用時再定義
十二、register關鍵字增強
在C和C++中,這個關鍵字請求編譯器儘可能的將變數存在CPU內部暫存器中,而不是通過記憶體定址訪問,以提高效率。注意是儘可能,不是絕對。假如,CPU內部暫存器不夠時,該變數就是一個普通的變數。
在C中:
register可以在全域性中定義變數,當對其使用&時,只是警告“有壞的儲存類”
register可以在區域性作用域中宣告,但這樣就無法對其使用&。否則編譯不通過
在C++中:
register無法在全域性中定義變數,否則會被提示為不正確的儲存類
register在區域性作用域中宣告時,可以用&操作符取地址,一旦使用了取地址操作符,被定義的變數會強制存放在記憶體中
總之:
建議不要用register定義全域性變數,因為全域性變數的生命週期是從執行程式開始,一直到程式結束才會終止,而register變數可能會存放在cpu的暫存器中,如果在程式的整個生命週期內都佔用著暫存器的話,這是個相當不好的舉措。
十三、struct型別加強
C語言的struct定義了一組變數的集合,C編譯器並不認為這是一種新的型別
C++中的struct是一個新型別的定義宣告,與類功能相同
相關文章
- C++ 基礎C++
- c++基礎C++
- 【C++】C++基礎知識C++
- C++基礎::StreamC++
- 01- 從C 到C++C++
- C++基礎語法C++
- C++基礎 constC++
- C++基礎::stringC++
- C++基礎總結C++
- C++基礎知識C++
- C++基礎知識篇:C++ 運算子C++
- c++基礎三(變數)C++變數
- 面試總結(C++基礎)面試C++
- C++基礎::檔案流C++
- C++基礎:: struct vs classC++Struct
- C++基礎知識整理C++
- C++基礎資料二C++
- C++基礎學習1C++
- C++基礎學習6C++
- 01_C++基礎C++
- 零基礎如何學習C/C++C++
- C/C++ Qt 基礎通用元件應用C++QT元件
- C++ -> Java快速學習-基礎C++Java
- c++基礎十(流程結構)C++
- (C++) queue容器基礎知識C++
- C++基礎::STL中的定理C++
- C++基礎::拾遺&&瑣碎C++
- C++基礎簡單總結C++
- C++的基礎學習5C++
- 【C++基礎複習01】結構體和連結串列C++結構體
- C++多執行緒基礎教程C++執行緒
- python入門(需要C++基礎)PythonC++
- 【c++基礎】菱形繼承問題C++繼承
- C++基礎知識筆記(1)筆記
- C++基礎::變數模板(variable template)C++變數
- 【01】C語言基礎C語言
- 從C到C++C++
- 深入理解 C++ 語法:從基礎知識到高階應用C++