###### 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


## 亂數 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;
```