###### tags:`ACM` # C++ 基礎使用大全 [TOC] ## 運算子 - 指定運算子(assignment operator): - 「=」: 將等號右方的值指派給等號左邊的變數 - 算術運算子(arithmetic operator): + - * / %(mod) - 關係運算子: > , < , >= , <= , == , != - 等號關係是「==」運算子;「=」是指定運算子 - 邏輯運算子: - &&(and) : 兩邊運算式皆為true - ||(or) : 其中一邊為true - !(not) : 傳回與運算元相反的值 - 遞增與遞減運算子: - 1.前置型: ++ 或 -- 運算子放在變數前方,ex.++a -->先將變數的值做+1或-1的運算,再輸出變數的值 - 2.後置型: ++ 或 -- 運算子放在變數後方,ex.a++ -->先輸出變數的值,再將變數的值做+1或-1的運算 - 複合指定運算子:由指派運算子與其他運算子結合而成 - ex.a+=b --->a=a+b - ?:運算子: - (condition)? i1 : i2 ->condition成立執行i1,反之,執行i2 - ex. int x,y=40; x=(y>40)?50:10; ---> x=10 ## 迴圈比較 - while : ```cpp= while(++counter <= 10) cout << counter << " "; ``` - for: ```cpp= for(counter = 1; counter <= 10; counter++) cout << counter << " "; ``` - do...while: ```cpp= do{ cout << counter << " "; ++counter; }while(counter <= 10); ``` 以上三種的 output : 1 2 3 4 5 6 7 8 9 10 ## if ```cpp= if( condition 1 ){ //如果instruction只有一行,大括號可省略。 instruction 1 }else if( condition 2 ){ instruction 2 }else if( condition 3 ){ instruction ... }else{ instruction n } ``` >ex. | 成績 | 90+ | 80-90 | 70-79 | 60-69 | 其他 | | :----: |:---:| :-----: | :-----: | :-----: | :----: | | 等第 | A | B | C | D | F | ```cpp= if( grade >=90 ){ cout<<”A”; }else if( grade >=80 ){ cout<<”B”; }else if( grade >=70 ){ cout<<”C”; }else if( grade >=60 ){ cout<<”D”; }else{ cout<<”F”; } ``` ## switch ```cpp= switch(grade) { case'A' : case'a' : ++a count; break; . . . defult: count << "..."<< endl; } ``` ## break , continue , EOF - break :離開迴圈,繼續執行下一行。 - continue :跳過該敘述主體的剩餘敘述,再執行下一次的迴圈。 - EOF :按 ^z、^c 結束 ## 資料型態 - 整數 : short/int/long | | Type | Byte/Bit | 數值範圍 | | :-----: | :---: | :------: | :-----: | | 整數 | <font color="#3379FF">int | 4/32|-2,147,483,648 ~ 2,147,483,647| | |<font color="#3379FF">signed | | |<font color="#3379FF">signed int | | |<font color="#173F8B ">unsigned int|4/32|0 ~ 4,294,967,295| | |<font color="#173F8B">unsigned| | |<font color="#3379FF">short|2/16|-32,768 ~ 32767| | |<font color="#3379FF">short int| | |<font color="#173F8B">unsigned short|2/16|0 ~ 65,535| | |<font color="#173F8B">unsigned short int| | |<font color="#3379FF">long|4/32|-2,147,483,648 ~ 2,147,483,647| | |<font color="#3379FF">long int| | |<font color="#3379FF">signed long int| | |<font color="#173F8B">unsigned long int|4/32|0 ~ 4,294,967,295| | |<font color="#3379FF">long long|8/64|-9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807| | |<font color="#173F8B">unsigned long long|8/64|0 ~ 18,446,744,073,709,551,615| - 浮點數 : float/double/long double | | Type | Byte/Bit | 有效位數 |數值範圍 | |:-:| :-: | :------: | :-----: | :---: | |單精數|<font color="#BB69E9 ">float|4/32|6~7|±3.4×10-38 ~ ±3.4×1038| |雙精數|<font color="#8314C1">double|8/64|15~16|±1.7×10-308 ~ ±1.7×10308| | |<font color="#8314C1">long double|8/64|18~19|±1.2×10-4932 ~ ±1.2×104932| - - 表示方式: <font color="#FF0400 ">Sign(符號)</font> <font color="#001EFF ">Exponent(指數)</font> <font color="#000001 ">Mantissa(尾數)</font> - **float:** <font color="#FF0400 ">1</font><font color="#001EFF ">111 1111 1</font><font color="#000001 ">111 1111 1111 1111 1111 1111 1111 1111</font> - <font color="#FF0400 ">Sign(符號)</font> 第1個 bit - 0 = 正數 - 1 = 負數 - <font color="#001EFF ">Exponent(指數)</font> 第2個 ~ 第9個 bit - 總共 8 bit - 最大值 255 - 127為中間值原點 - <font color="#000001 ">Mantissa(尾數)</font> 第10個 ~ 第32個 bit - 轉為二進位按科學記號計算之後的尾數 - **double:** <font color="#FF0400 ">1</font><font color="#001EFF ">111 1111 1111</font><font color="#000001 "> 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111</font> - <font color="#FF0400 ">Sign(符號)</font> 第1個 bit - 0 = 正數 - 1 = 負數 - <font color="#001EFF ">Exponent(指數)</font> 第2個 ~ 第12個 bit - 總共 11bit - 最大值 2047 - 1023為中間值原點 - <font color="#000001 ">Mantissa(尾數)</font> ~ 第64個 bit - 轉為二進位按科學記號計算之後的尾數 - ex. (float) 17.625(10進制) =>10001.101 =>1.0001101*2^4 (2進制) ><font color="#FF0400 ">Sign(符號)</font>) 正數=>0 <font color="#001EFF ">Exponent(指數)</font> 實際為4,但是需要加上127,指數位131=>10000011(二進制) <font color="#000001 ">Mantissa(尾數)</font> 取小數點後的數=>0001101 <font color="#000001 ">17.625的存儲方式為:</font> <font color="#FF0400 ">0</font> <font color="#001EFF ">10000011</font> <font color="#000001 ">00011010000000000000000</font> - unsigned/signed - unsigned : 無號,只表示正值 - signed : 有號,正值與負值平均分配 - ex. - 8 位元字元表示整數 - 有號字元: -128 ~127 - 無號字元: 0 ~ 255 >signed int 最左邊位元被用來表示正負號 * 0 : 正號 * 1 : 負號 unsigned int 最左邊位元不用來表示正負號 - 字元 : char | | Type | Byte/Bit | 數值範圍 | | :-: | :-: | :-----: | :-----: | |字元|char|1/8|-128 ~ 127| - 布林 : bool - True: 1 or >0 - False: 0 | | Type | Byte/Bit | 數值範圍 | | :-: | :-: | :-----: | :-----: | |布林|bool|1|0、1| ## Function - funtion格式 ```cpp= type function名稱 ( 參數1 = 預設值1(可省略), 參數2 = 預設值2, 參數3 = 預設值3 ){ //若呼叫funtion時未輸入參數,則默認為預設值。若未設預設值,呼叫funtion時未輸入參數將出現錯誤代碼。 code; return 回傳值; //function類型非void(無回傳值),才需要回傳同funtion類型之參數 } ``` - ex. ```cpp= int square( int a=0){ return a*a; } int main(){ int i=5; i=square( i ); //呼叫square() cout<< i <<’ ‘<< square(10) <<endl; //印出"25 100" return 0; } ``` - inline - inline 函式只能建議(不一定採納)編譯器,該函式會自動在呼叫點展現為程式碼,通常直接在標頭檔中實作。 ## Pointer - 變數名稱,是**直接參用某數值**(directly references a value) ```cpp= int x = 5; ``` - 指標,是**間接參用某數值**(indirectly references a value) ```cpp= int x = 5; int *xPtr = &x; cout << "The value of *xPtr is " << *xPtr << endl; cout << "The value of x is " << x << endl; cout << "The value of xPtr is " << xPtr << endl; cout << "The address of x is " << &x << endl; ``` ```cpp The value of *xPtr is 5 The value of x is 5 The value of xPtr is 002DFD80 (假設的address) The address of x is 002DFD80 (假設的address) ``` 第2行 : xPtr指向x,意思是xPtr指向x的address,而不是x的值。 第3、4行 : output的結果為 5。 第5、6行 : output的結果為 同一個位址。 如果是 ```cpp= *xPtr = 9; ``` 會把 9 透過 *xPtr 指向 x,讓 x 的值變成 9。 以下有2種方式 - pass-by-value ```cpp= #include <iostream> using namespace std; int cubeByValue(int); int main() { int number = 5; cout << "The original cube value of number is " << number << endl; number = cubeByValue(number); cout << "The new value of number is " << number << endl; } int cubeByValue(int n) { return n * n * n; } ``` ```cpp The original cube value of number is 5 The new value of number is 125 ``` 上面第10行,把 number 傳給 cubeByValue (14~17行)算成立方,再回傳到第10行的 number。 - pass-by-reference ```cpp= #include <iostream> using namespace std; void cubeByReference(int *); int main() { int number = 5; cout << "The origianl value of number is " << number << endl; cubeByReference(&number); cout << "The new value of number is " << number << endl; } void cubeByReference(int *nPtr) { *nPtr = *nPtr * *nPtr * *nPtr; } ``` ```cpp The origianl value of number is 5 The new value of number is 125 ``` cubeByReference(第14~17行)會以 nPtr(指向 int 的指標)接收引數,函式會解參考nPtr,計算它所指向的變數做立方計算(第16行),這會直接改變main 函式中的 number(第8行),所以(第16行)不需要使用 return敘述。 ## 使用常數指標 - nonconstant pointer to nonconstant data : 指標可以改變指向的資料,資料也可以透過指標修改。 - nonconstant pointer to constant data : 指標可以被修改,指向不同資料,但是被指標所指的內容,不能透過指標修改。 ```cpp const int *countPtr; ``` ```cpp= void f(const int *); int main() { int y = 0; f(&y); } void f(const int *xPtr) { *xPtr = 100;// error : cannot modify a const object } ``` - constant pointer to nonconstant data : 指標不可以被修改,永遠指向一個記憶體位址,但程式可以透過該指標,修改記憶體位置上的資料內容。 ```cpp int * const ptr; ``` ```cpp= int main() { int x, y; int * const ptr = &x; *ptr = 7; ptr = &y;// error : ptr is const, cannot assign to it a new address } ``` - constant pointer to constant data : 指標只能指向固定的記憶體位址,而且也沒辦法透過指標修改資料內容(權限最低)。 ```cpp const int *const ptr; ``` ```cpp= #include <iostream> using namespace std; int main() { int x = 5, y; const int *const ptr = &x; *ptr = 7;// error : *ptr is const, cannot assign new value ptr = &y;// error : ptr is const, cannot assign new address } ``` ## sizeof運算子 - 常犯錯誤 :在函式中使用 sizeof,可以計算內建陣列參數的元組大小,即指標的位元組大小,不是整個內建陣列的位元組大小。 - 個資料型態所需的記憶體大小可能依系統而異。在不同電腦上執行時,可先用sizeof判斷儲存資料型態所需的位元組個數。 ex : ```cpp= #include <iostream> using namespace std; int main() { cout << "sizeof char : " << sizeof(char) << endl; cout << "sizeof int : " << sizeof(int) << endl; cout << "sizeof float : " << sizeof(float) << endl; } ``` ## 指標運算 假設宣告 ```cpp int v[5]; int *vPtr = v; int *vPtr = v[0]; ``` 且第一個陣列 (v[0]) 的記憶體位址是3000,那麼在4個位元組儲存整數的電腦系統上,記憶體位址為3000、3004、3008、3012、3016。 ```cpp vPtr += 2; ``` 的結果是 ```cpp 3008(3000 + 2 * 4) ``` 在陣列 v 中,vPtr 現在會指向 v[2]。 若現在位址在3016,也就是 v[4] ```cpp vPtr -= 4; ``` vPtr 的位址將回到3000,也就是 v[0]。 ## 指標與內建陣列的關係 假設宣告以下 ```cpp= int b[5]; int *bPtr; bPtr = b; ``` 第3行會將 bPtr 設為陣列 b 的第一個元素 ```cpp bPtr = &b[0]; ``` - 以陣列元素 b[3] 為例 : ```cpp *(bPtr + 3) &b[3] *(b + 3) ``` - 記得陣列名稱是常數指標,永遠指向陣列起始位址,因此 ```cpp b += 3; ``` 會產生編譯錯誤,因為這個運算用指標算術**修改陣列名稱**。 ## Array - 簡介: - 起始位置 : 表示陣列名稱(或陣列第一個元素)所在記憶體中的起始位址。 - 維度(dimension) : 代表此陣列為幾維陣列。 ex.一維陣列、二維陣列 - 陣列的第一個元素索引值為0(非1) - 兩個陣列不能直接用「=」運算子來互相指定,而只能利用陣列元素才能互相指定。 - 如果設定初始值少於陣列定義元素個數,則其餘元素的值會直接填入0。 - 在定義一維陣列時,如果沒有指定陣列元素個數,則編譯器會將陣列長度由初始值的個數決定。 ## Standard library headers ![](https://i.imgur.com/DC6tafW.png) ![](https://i.imgur.com/XJzA1Ef.png) ## 亂數 rand() / srand() - **需 #include<cstdlib> 或 <stdlib.h>** - rand()-產生亂數 ```cpp= x=rand(); //x=0~RAND_MAX y=rand()%i+j; //y=j~(i+j-1) ``` - srand()-重新設定亂數 ```cpp= #include<cstdlib> #include<ctime> srand(time(0)); //以現在時間重設亂數種子 x=rand()%6+1; //x=1~6; ``` ## 列舉 enum - 列舉是使用者定義類型,其中包含一組具名的整數常數,稱為列舉值。 - <font color="#3379FF">enum</font> 名稱 : <font color="#001EFF">資料類型</font> { enum-list }; ```cpp= enum A { E=1, W , S, N }; //指派給列舉值E的值為1(預設為0)。 //後續列舉值,如果未提供其明確值,則為前一個列舉值的值加一。 A a; //a包含 E, W, S, N a = S; switch( a ){ //印出"South " case a::E: cout<<”East"<<endl; break; case a::W: cout<<”West"<<endl; break; case a::S: cout<<”South"<<endl; break; case a::N: cout<<”North"<<endl; break; default: cout<<”Home"<<endl; } ``` ## 字串 String - **需 #include<string>** - operator - a = b : 將b字串指定給a字串 - a + b : 可直接串接a,b兩字串 - a == b : 判斷字串a,b是否相同 - a[ i ] : 指定a字串第i字元(從0開始) - 常用函式 - a.size() or a.length() : a字串之長度 - a.empty() : 檢查a字串是否為空 - 0 : 否 - 1 : 是 - a.clear() : 清空a字串 - a.at( i ) : a[ i ] - b.assign(a, i, n) : 從 a 字串的第 i 個字元取出 n 個字元指定給b字串 - b = a[ i ~ n -1 ] - b.append(a, i, n) : 從 a字串的第 i 個字元取出 n 個字元加到b字串後面 - b = b + a[ i ~ n -1 ] - b.insert( i, a) : 從b的第 i 個字元插入 a - b = b[0 ~ (i - 1)] + a + b[ i ~ b.end()] - b.find(a, 0) : 從b字串中第 0 個字元尋找是否有符合 a 之子字串 - a.erase(i, n) : 將a字串中從第 i 個字元取出 n 個字元抹去 - a = a[0 ~ i] + a[ i + n ~ a.end()] - stoi(a , nullptr, n) : 將a字串轉為n(預設為10)進位之整數 - 輸入 ```cpp= cin >> a; //遇到' '則停止輸入 getline(cin, a); //遇到'\n'則停止輸入 getline(cin, a , char delim); //遇到指定的delim字元則停止輸入 ``` - 印出 ```cpp= cout<< a <<endl; //直接印出 for(int i = 0; i < a.length(); i++) //字元一個一個印出 cout << a[ i ]; cout << endl; for(auto i : a) cout << i ; cout << endl; ```