---
# System prepended metadata

title: C++ 基礎使用大全
tags: [ACM]

---

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

