---
# System prepended metadata

title: C++ Computer Programming

---

## Hardware
- RAM: random access memory
- bit: 0,1
- Byte: 8 個 bit
- KB: 2的10次方 = 1024 byte
- MB: (mega) 2的20次方
- GB: (Giga) 2的30次方
- TB: 2的40次方
 ![image](https://hackmd.io/_uploads/BkZYgB_Ep.png)
- Main Memory & Secondary Memory
    - Primary / Main Memory
        - CPU可以直接存取的電腦內存，保存處理器正在處理的資料和指令
    - Secondary Memory / Mass Storage
        - 先傳到main memory，再給CPU存取
    - 表格比較
    
        | Primary / Main Memory |Secondary Memory / Mass Storage |
        | -------- | -------- |
        | 儲存處理中的程式和資料 | 儲存暫時不用的大量程式和資料 |
        | 暫時的 | 永久的 | 
        | CPU直接存取 | CPU無法直接存取 |
        | volatile會消失的(ROM除外) | non-volatile不會消失 |
        | 價格貴 | 價格便宜 |
        | 半導體記憶體(semiconductor memories) | 磁帶或光碟(magnetic and optical memories) |
        | 內部記憶體/主記憶體 | 外部記憶體/輔助記憶體 |
        | RAM(隨機存取記憶體), ROM(唯讀記憶體), Cache memory(快取記憶體), PROM(可程式化唯讀記憶體), EPROM(電子抹除式可複寫唯讀記憶體), Registers(暫存器), etc. | Hard Disk(硬碟), Floppy Disk(軟碟), Magnetic Tapes(磁帶), etc. |
  ![image](https://hackmd.io/_uploads/rJwqBHO4T.png)
## Software
- **System software:** ios, Linux, Windows
- **Application software:** Powerpoint, Word, Skype 等應用程式
- **Programming language**
    - **Machine language (Low-level Language) 機器語言 :** 基本上由0,1組成，不同的computer就要用他接受的語言下指令，且要下的非常仔細，容易出錯。
    - **Assembly language (Middle-level Language) 組合語言 :** 用類似簡易英文的方法創建指令，但對user不友善，因為要先轉成0,1才能執行，要花很多精力才能做簡單的事
    - **High-level language 高階語言 :** 有預設單字和規則，由Compiler和Interpreter轉成機器語言0,1，可以跨machine執行。
        -  直譯 (Interpreter) : 
        我們所寫的程式碼會透過直譯器一行一行的被執行。直譯式語言有JavaScript、Python、PHP及Ruby等。
        -  編譯 (Compiler) : 
        我們所寫的程式碼會先經過編譯器，將程式碼全部編譯成機器語言，編譯完後(產生執行檔)再一次執行。
        編譯語言有C#、Java、C、C++、Objective-C、Swift等。
![image](https://hackmd.io/_uploads/B1qKG8dV6.png)

## Variables
- `int a = 8 ; b = 3 ;` => 定義a和b是數字型態(宣告在一起不等於位置memory location會在旁邊)
- `std::cin >> number1` => input(cin存在number1)，重複input就蓋過舊的值
- `std::cout << 12 << "Hello" ;` => output 12Hello 在螢幕上
    ```c++
    int main(){
    std::cout << "hello"
    }
    ```
    會等於
    ```c++
    using std::cout;  //代替std::
    int main(){
    cout << "hello"
    }
    ```
    會等於
    ```c++
    using namespace std;
    int main(){
    cout << "hello"
    }
    ```
- output換行
    - `cout << "hello\n" ;` => 字串用\n
    - `cout << a << endl ;` => 非字串用end of line
## Data Types 資料型態
    

| Types            |     |      |
| ---------------- | --- | ---  |
| bool             |**False**: (1) false本身 (2)整數 0 (3)浮點數 0.0 (4)空指標 NULL 或 nullptr |**True**: (1) 零字元 '0' 和空白字元 ' ' (2) 空字串 "" (3) 空陣列|
| char             |**窄字元型態**: (1)char (2)signed (3)char| **寬字元型態**: (1)char16_t (2)char32_t (3)wchar_t|
| float (4 bytes)  | double (8 bytes) | long double |
| string |    |    |
| int   | (詳細看下圖) |  |

![image](https://hackmd.io/_uploads/ryUQOJoVT.png)

## 運算符號 (基本上都跟js一樣)
- +, -, *, /, %, >, <=, !=, ==
- &&, ||, !
- 整數與整數做運算還是整數，小數同理
- 愈上面優先權(precedence)愈高
    - ![image](https://hackmd.io/_uploads/HJQ-DMs4T.png)
- **數字相加，會往精確度高的去存取**
    - ex. float = int + float -> (資料庫存float)
- **加一的區別，`++a` & `a++`**
    - `cout << ++9` => 輸出10，先加再做
    - `cout << 9++` => 輸出9，先做再加
- **static_cast<型態>(值) : 暫時產生copy，改變型態**
    ```c
    int a=8; b=3;
    double c;
    c = a / b  
    // => 整數 / 整數 = 整數，c還是2
    ```
    - 當今天要把整數改為小數型態，就使用static_cast<型態>轉換型態。這不會改變memory中原本的a是整數型態，只是在計算時**暫時**改變型態而已。
    ```c
    int a=8; b=3;
    double c;
    c = static_cast<double>(a) / b
    // => 小數 / 整數 = 小數，已轉換a為小數
    ```
## 迴圈
- **While loop & Do While loop**
    - 單個statement
    ```c
    while(condition)
        statement;

    // ------------

    int a =1 ;
    while(a<=10)
    cout << a; // 只有這個statement
    a++; // 這個不屬於while loop的body，所以a會一直都是1
    // 用大括號即可解決
    ```
    - 多個statement，用do包起來
    ```c
    do{
    statement;}
    while(conditions);

    // ------------

    int a=1;
    // do無論如何都會先跑一次
    do {
        cout <<a; // 兩個都屬於while loop的body
        a++;
    }
    while(a<=10);
    ```
- **More on while loop**
    - Counter-controlled loop (知道次數)
    ```c
    int a=1, total=0;
     do{
        total+=a++;
     }
     while(a<=10);
    ```
    - Sentinel-controlled loop (不知道次數)
    ```c
    int a=1, total=0;
    do{
        cin >>a;
        total+=a;
     }
     while(a!=-1);
    ```
- **For loop** 次數固定
    ```c
    for(int a=1; a<=10; a++)
    cout << a;

    // --------------

    for(int i=1, j=10; i<=j; i++, j--)
    cout << i+j;
    ```
- **Switch**
    ```C
    switch(){
        case 'A':
            statement;
            break; // => 沒有break就繼續執行
        case 'B':
            statement;
            break;
        default:
            statement;
            break;
    }
    ```
## Function
```c
// 前面型別是return type
int square(int y){  
    return y*y
}

sqaure(x) // called function
```
- **Scope :** 即使有scope，仍盡量避免變數名稱相同
    - `cout << :: x ;` => 使用global variable
    - `cout << x << endl ;` => local variable
- **Inline Function** 
    - 當程式不複雜時可使用，直接替代 statement 本身
    - 可提高程式執行速度
    ```c
    inline void printSum(int num1,int num2) {
    cout << num1 + num2 << "\n";
    } 

    int main() {
        // call the inline function
        printSum(10, 20);
        printSum(2, 5);
        printSum(100, 400);
        return 0;
    }
      ```
- **Defalut Argument**
    ```c
    void point(int x = 3, int y = 4); //預設是3和4

    point(1, 2); // calls point(1, 2)
    point(1);    // calls point(1, 4)
    point();     // calls point(3, 4)
    ```
- **Recursion Funciton**
    - 呼叫自己(直接/間接)
    - ex. n階層、Fibonacci、
    - ![image](https://hackmd.io/_uploads/SyVplK5O6.png)
    - ![image](https://hackmd.io/_uploads/Hk2b-t9_6.png)
    - ```C
        F(0) = 0
        F(1) = 1
        F(n) = F(n-1) + F(n-2)
      ```
- References
    - 將參數傳給function的方法
        - pass by value : 將參數的副本傳給function，改變副本的值並不會改變原本的值
        - pass by reference : 直接存取和修改參數，會影響到原本的值
    - 宣告reference就是pass by reference
- Function Overloading
    - 相同名稱的function，不同的參數設定就是overloading function
    - 會根據傳入的參數決定要呼叫哪個function
    - 通常是要做相似的事情，只是傳入的資料類型不同
- Function Template
    - 不管傳入的值是什麼，執行的動作都一樣

## Array
- 宣告方式
    ```c
    int a[5]={1,2,3,4,5}
    int a[]={1,2,3,4}
    int a[5]={1} // => a[5]={1,0,0,0,0} 沒有給到值的就會賦予0
    ```
- 結合for loop
    ```c
    int total = 0;
    for(int i = 0 ; i < arraySize ; i++){
        total += a[i]
        cout << "total of array elements :" << total << endl;
        return 0;
    }
    ```
- 多維宣告方式
    ```c
    int a[4][8]; // 二維 => 迴圈就用兩層for loop
    int b[1][5][1]; // 三維
    ```
    ```c
    int a[2][3]={{1},{2,3}} // 第一列1,0 ; 第二列2,3,0
    int b[2][3]={1,2,3,4,5} // 先從橫列row開始填值，填滿再換第二列
    ```
- Array function防止更改參數的值
    ```c
    // 第一個const是array，使用pass by reference傳遞參數
    // 只要在參數前加const就代表值不可在這個function中被更改
    // ---------------------------------------------------
    // 第二個const非array，所以加入const後會copy一份給function
    // 一樣不可在這個function中被更改
    
    void modifyArray (const int b[], const int sizeOfArray){
        for (int k = 0; k < sizeOfArray; k++)
            b[k]* = 2;
    }
    ```
- 程式範例
    - 線性搜尋程式範例
    ```c
    int linearSearch(const int array[], int key, int sizeOfArray){
        for (int j = 0; j < sizeOfArray; j++)
            if(array[j] == key)
                return j; // 找到值了
        
        return -1; // 沒找到值
    }
    ```
    - Binary Search ( 利用切一半開始搜尋 )
    ```c
    int binarySearch(int array[], int x, int low, int high){
        while(low <= high){
            int mid = low + (high - low) / 2; //取中間值
            
            if(array[mid] == x) //找到值了，中斷迴圈
                return mid;
            
            if(array[mid] < x) //如果值在中間值以上
                low = mid + 1;
            
            else
                high = mid - 1 //如果值在中間值以下
        }
        return -1
    }
    ```
    - Sorting ( Bubble Sort )
    ```c
    void InsertionSort(int *arr, int size){
        for (int i = 1; i < arraySize; i++){
            int key = arr[i];
            int j = i - 1;
            while (key < arr[j] && j >= 0){
                arr[j + 1] = arr[j];
                j--;
            }
            arr[j+1] = key;
        }
    }
     ```
     
## Pointer
- 儲存變數的記憶體位址 (address) ，是儲存記憶體位址的資料型態
- 除了儲存address，也可以存 0 和 null，表示沒有存到任何address
- ex. 給網址，就可以藉由網址拿到照片，也就是網址是指向這個資料的「pointer指標」
    當我們宣告一個變數時，總共會有三個要素
    1. 變數位址 = pointer指標
    2. 變數值
    3. 變數名稱
- '&' 取位址 -> 我們拿到地址，都是為了要去到這個地址上、以抓取變數
- ' * ' 取值 -> `*&b = b` 取b的位址再取值=原本的值
```c
int b;
b = 2;

int* pointer; // 宣告pointer變數只能放int型變數的指數(位址)
pointer = &b; // 把b的位址給pointer

// => 指標變數pointer就會指向變數b
```
```c
int main(void) {
    int b = 2;
    int* pointer = &b; // 宣告指標pointer = b的位址 
    printf( b ); // 2
    printf( &b ); //0x7fff551n49c8
    printf( pointer ); //0x7fff551n49c8
    
    *pointer = 100; // pointer的值是100
    printf( *pointer ); // 100
    printf( b ); // 100
    printf( &pointer ); //0x45h945774g
    
       return 0;
}
```

## Classes and data abstraction
```C
class c_name {
  public: // => 給外面看的interface，可以跟外面access
    member functions;
  private: // => 外面不可以直接access，不可直接修改
    data member; // => 靜態特徵
}; 
```