# 第一章: 基礎語法 這篇參考了一些網路上的教材,如果有不正確的可以留言或是去DC留言,本篇的內容可能有點對新手不友善,如果你是自學的,可以善用AI以及[cpp reference](https://en.cppreference.com/w/),否則在讀書會內的講師們應該都介紹的蠻詳細的。 ### 標頭檔及程式基礎架構 * 引入標頭檔&&`<bits/stdc++.h>`的介紹 #### 程式基礎架構 ```cpp #include <iostream> 標頭檔 using namespace std; int main() { cout<<"Hello world"; } ``` #### code ```cpp #include <iostream> 標準標頭檔 #include <bits/stdc++.h> 萬用標頭檔 ``` [參考網址](https://www.796t.com/content/1547093362.html) --- ### 變數宣告 在使用變數前,要先告訴電腦你要創造一個[變數](https://openhome.cc/Gossip/CppGossip/Variable.html),這個動作叫做宣告。 * 宣告格式:**`變數型別 變數名稱`**; 例如 **`int x;`** 就是宣告一個整數變數x。 變數可分為 > 1. 整數-**int** > 2. 浮點數-**double** > 3. 字元-**char** > 4. 字串-**string** #### ```cpp= int x, y; ////宣告兩個整數 double a = 3.14159; //宣告一個浮點數=3.14159 char b = 'A'; //宣告一個字元=A string s="hello"; //宣告一串字串 ``` [浮點數介紹](https://hackmd.io/@Tamilala/cpp_float) --- ### 輸入輸出 * 標準輸入輸出 > 輸入-cin 遇空格或是換行即結束 > 輸出-cout 在需要換行的地方可以輸出 **`endl`** 或是 **`'\n'`**。 #### code ```cpp= int x, y; ////宣告兩個整數 double a = 3.14159; //宣告一個浮點數=3.14159 cin >> x ; //輸入 x (5) cout << "hello world " << x << " " << a ; //輸出 = hello world 5 3.14159 ``` **※ 不可使用沒設定變數值之變數(會是亂數)** ==**補充**== * [控制輸出位置精準度(精準度)](https://ithelp.ithome.com.tw/articles/10249426) * [輸入時不要被空格split](https://hackmd.io/@L-W7DgKMR_G7ZX3wGcC3Zw/BkVhJORNK) --- ### 運算子 在C++中,可以使用運算子來對變數或數值做運算。以下介紹幾種常用的運算子,同時也會提到當兩種不同型別的變數進行運算時,電腦會如何判斷要使用哪個型別,以及如何做強制型別轉換。 #### 1. 指定運算子 使用等於`=`符號表示,會先對等號右邊進行運算,再將結果指定給左邊的變數。這個等號跟數學的等號不太一樣,需要花一點時間習慣。 ```cpp= int x; x = 2 + 1; //x = 3 (//是註解,在C++程式編譯時不會被編譯) x = x + 1; //x = 4,因為是先計算右邊的x + 1 = 3 + 1,再存到左邊的x ``` #### 2. 算術運算子 算術運算子就是數學的運算符號,具有跟數學四則運算一樣,先乘除後加減的規則。 * 加法 **`+`** ```cpp int x = 3 + 2; ``` * 減法 **`-`** ```cpp int x = 10 - 5; ``` * 遞增 **`++`** 遞增可分成前置`++x`和後置`x++`,它們的不同在於,前置的值會是運算之後的值,後置的值則是運算之前的值。可以看成前置`++x`是先加再用,而後置`x++`是先用再加。 ```cpp= int x = 0; cout << ++x << endl;// x = 1, 輸出1 x=0; cout << x++ << endl; // x = 1, 輸出0 ``` * 遞減 **`--`** 與遞增相同,一樣有分成前置和後置。 ```cpp= int x = 0; cout << --x << endl; // x = -1, 輸出-1 x=0; cout << x-- << endl; // x = -1, 輸出0 ``` * 乘法 **`*`** ```cpp int x = 2 + 3 * 4; //x = 14, 先乘除後加減 ``` * 除法 **`/`** 兩個整數在做運算時, 當對兩個整數做除法`/`,會自行向下取整,也就是取商。 ```cpp int x = 7 / 2; // x = 3 float y = 1.0 / 2.0; // y = 0.5 ``` - 取餘數 **`%`** ```cpp int x = 5 % 2; // x = 1 ``` - 補充 mod 的一些數學性質 $$(a+b) \bmod p = (a\bmod p + b\bmod p)\bmod p$$ 證明: $$\begin{aligned} (a+b) \bmod p &= ((k_a\times p+(a\bmod p)) + (k_b\times p+(b\bmod p)))\bmod p \\ &= \end{aligned}$$ * 括號 `()` 在C++中,一樣可以使用括號來標示優先計算的部分,且都是使用小括號`()`。 ```cpp cout << (1 + 2) * 3 << endl; //輸出9 cout << 2 * ((1 + 2) * 3 + 2) << endl; //輸出22 ``` **3. 比較運算子** 在比較運算中只會有` true `或 `false` 兩種結果。 * `<`小於、`>`大於 * `<=`小於等於、`>=`大於等於 * `==` 相等 、 `!=` 不相等 (相等是`==`,而`=`是指定運算子,意義跟用途都不同,要小心不要搞混。) **4. 邏輯運算子** 在邏輯運算中只會有 `true` 或 `false` 兩種結果。 * **邏輯AND** **`&&`** A、B皆為 `true` 時, `A && B ` 為`true`, 否則 `A && B` 為 `false`。 | **A && B** | B : true | B : false | | ---------- | -------- | --------- | | **A : true** | true | false | | **A : false** | false | false | * **邏輯OR** **`||`** A、B其中一個為`true`時,`A||B`為`true`,兩者皆為`false`時為`false`。 | **A \|\| B** | **B : true** | **B : false** | | ---------- | -------- | --------- | | **A : true** | true | true | | **A : false** | true | false | * **邏輯NOT** **`!`** A為`true`時,`!A`為`false`,A為`false`時,`!A`為`true`。 | **!A** | A : true | A : false | | ------ | -------- | --- | | **result** | false | true | --- ### 強制型別轉換 強制型別轉換是在程式運算過程中,對型別做強制的轉換。 轉換格式: ``` (轉換型別) 變數; (轉換型別) 數值; ``` 例如要將數字轉為字元的編號: ```cpp= int x = 3; cout << (double)x / 2 << endl; //輸出 1.5 cout << (char)97 << endl; //輸出「a」, 97是字元'a'在ASCII碼中的編號 ``` --- ### 選擇結構 選擇結構在C++ 中用於判斷條件並決定要執行哪些程式,C++使用`if`、`else`和`else if`作為選擇結構的語法,接下來會一個一個介紹它們的用法。 #### if `if`的使用格式如下: ``` if(判斷條件){ 判斷條件成立時執行的程式; } ``` `if`後的小括號用於放判斷式,如果判斷式運算結果為`true`,就會執行大括號內的程式碼。要注意大括號後不需要加分號。 以下是一個用於判斷你輸入的數是否大於100的程式,如果大於100,將輸出「x大於100」: ```cpp= int x; cin >> x; if(x > 100){ cout << x << "大於100" << endl; } ``` #### else 若在**if**判斷為`false`,就可能會需要處理條件不成立的狀況,這時就會用到`else`。`else`需要接在`if`或`else if`後,`else if`會在後面提到。 以下是`else`的用法: ``` if(判斷條件){ 判斷條件成立時執行的程式; }else{ 判斷條件不成立時執行的程式; } ``` 以下是一個用於判斷輸入的數是否大於100的程式。如果大於100,將輸出「x大於100」;否則輸出「x小於等於100」: ```cpp= int x; cin >> x; if(x > 100){ cout << x << "大於100" << endl; }else{ cout << x << "小於等於100" << endl; } ``` #### else if 當你需要多個選擇時,你可以使用`else if`來達成,`else if`可以接在`if`或`else if`後面,以下是`else if`的用法: ``` if(判斷條件1){ 判斷條件1成立時執行的程式; }else if(判斷條件2){ 判斷條件2成立時執行的程式; } else{ 判斷條件2不成立時執行的程式; } ``` 要特別注意的是,在整個選擇結構中,如果在其中一項成立,它就會跳過結構中後面的部分。 以下是一個用於判斷輸入的數是否大於100的程式。如果x大於100,將輸出「x大於100」;如果x等於100,則輸出「x等於100」;否則輸出「x小於100」: ```cpp= int x; cin >> x; if(x > 100){ cout << x << "大於100" << endl; }else if(x == 100){ cout << x << "等於100" << endl; }else{ cout << x << "小於100" << endl; } ``` ### 迴圈 當你需要重複執行一樣的程式時,可以使用迴圈反覆執行相同的程式。在C++中,迴圈分為兩種:`for`迴圈和`while`迴圈。 #### for `for`迴圈通常用在需要重複的次數已知時使用,它的格式如下: ``` for(一開始要執行的動作; 迴圈執行條件; 每次迴圈跑完後要執行的動作){ 迴圈內的程式; } ``` 在for迴圈的大括號後不需要加分號。 比較常見的程式寫法如下: ```cpp for(int i = 0; i < 執行次數; i++){ //迴圈的內容 } ``` 以下是一個可以輸出0 ~ n - 1的程式: ```cpp= int n; cin >> n; for(int i = 0; i < n; i++){ cout << i << ' '; } cout << endl; ``` #### while `while`迴圈的結構比`for`迴圈簡單,只需要一個迴圈執行條件,格式如下: ```cpp while(判斷條件){ 迴圈內的程式; } ``` 這是一個計算輸入數字是幾位數的程式: ```cpp= int x; cin >> x; int cnt = 0; while(x > 0){ cnt++; x = x / 10; } cout << cnt << endl; ``` `while`迴圈還有另一種寫法,是使用`do-while`。 ```cpp= do{ 迴圈內容 }while(執行條件); ``` 它跟`while`迴圈不同的地方是,`while`迴圈會在一開始就檢查是否執行迴圈,而`do-while`則是先執行過第一次之後再判斷是否繼續執行迴圈。還有要注意在`do-while`的大括號後需要加上分號,`while`迴圈則不用。 #### break `break`是迴圈的一個特別的指令,只能在迴圈內使用。當執行到`break`時,電腦會直接結束break所屬的迴圈。 以下是一個輸入數字n,輸出$0 \sim n-1$的程式: ```cpp= int n; cin >> n; int now = 0; while(true){ if(now >= n) break; cout << now++ << ' '; } ``` #### continue `continue`也是迴圈的指令,當執行到`continue`時他會跳過迴圈剩下的部分,直接回到判斷迴圈條件的步驟。 以下是一個輸入數字n,輸出0 ~ n - 1的偶數的程式: ```cpp= int n; cin >> n; for(int i = 0; i < n; i++){ if(i % 2 == 1) continue; cout << i << '\n'; } ``` ### 陣列 陣列是多個相同資料型別的變數所組成的,陣列中的每個元素都是一個變數。它的宣告格式如下: ```cpp 變數型別 陣列名稱[陣列大小]; //陣列大小須為正整數 ``` 當要使用時,用中括號`[]`加上索引值```陣列名稱[索引值]```來表示陣列的某個變數。要特別注意的是,陣列的第一個位置索引值是0,以下是一些簡單的操作方式: ```cpp= int a[5]; a[0] = 1; a[1] = 2; a[2] = 3; a[3] = 4; a[4] = 5; ``` ### 陣列和迴圈 陣列經常搭配迴圈一起使用,以下是一個簡單的程式: ```cpp= int a[10]; for(int i = 0; i < 10; i++){ cin >> a[i]; } ``` ### 將陣列排序 C++中有可使用的函數``std::sort()``,能將陣列由小排到大(預設),使用時傳入陣列開始的指標和陣列最後的下一位指標 ```cpp= int a[10]; for(int i=0;i<10;i++) cin>>a[i]; sort(a,a+10); // a+9是陣列最後的位置,a+10則是最後一位的下一位 ``` 也可傳入第三個參數,傳入一比較布林函數,函數需實現三個功能,接受兩個和陣列型別相同的變數作為參數傳入,回傳True表示目前位置不需要交換,反之交換 ```cpp= bool comp(int a,int b){ //a表示位置在前數值,b則表示後者(不一定要取a和b) return a<b; //如果a<b則回傳1,表示a在前b在後不需要交換 } int a[10]; for(int i=0;i<10;i++) cin>>a[i]; sort(a,a+10,comp); ``` --- ### 題目: - 基礎輸入輸出 - if-else [cchs judge a563](https://judge.cchs.chc.edu.tw/ShowProblem?problemid=a563) [cchs judge a564](https://judge.cchs.chc.edu.tw/ShowProblem?problemid=a564) [cchs judge a565](https://judge.cchs.chc.edu.tw/ShowProblem?problemid=a565) - 迴圈 [ABC256A](https://atcoder.jp/contests/abc256/tasks/abc256_a) [ABC281A](https://atcoder.jp/contests/abc281/tasks/abc281_a) [ABC365B](https://atcoder.jp/contests/abc365/tasks/abc365_b) [ABC339C](https://atcoder.jp/contests/abc339/tasks/abc339_c) - 陣列 [ABC396A](https://atcoder.jp/contests/abc396/tasks/abc396_a) [CF2103A](https://codeforces.com/contest/2103/problem/A) [cchs judge a545](https://judge.cchs.chc.edu.tw/ShowProblem?problemid=a545) - 排序 [ABC360C](https://atcoder.jp/contests/abc360/tasks/abc360_c)