# 東山高中程式研究社 複習講義 - C++篇 ## 什麼是C++ > 暫時跳過不介紹,之後有時間再來慢慢補 ## bit/byte > bit叫做位元,是電腦的最基本單位,代表的值為0或1,byte叫做位元組,說白了就是8個位元,是電腦處理資料用的最小單位(其實不是最小,但基於效率考量,就算是沒有到1byte的資料還是會佔一個byte),由於一個bit可以有兩種型態(0或1),因此一個byte就能夠表示2^8^個不同的值 ## 二進位(binary)) > 因為bit只能是0或1兩種值,所以電腦使用的不是我們平常常看到的十進位,而是用二進位,十進位的概念就是數到十就進位,二進位也是一樣,數到二就進位,因此只會有0跟1 > 十進位再計算的時候可以將第一位看成n * 10^0^,第二位是n * 10^1^以此類推,二進位也是一樣,第一位代表2^0^,第二位代表2^1^...,其實不會算也沒關係,重要的是要知道什麼是二進位以及二進位的基本概念 ## include > C++在做任何事之前,一定要先`include`一個標頭檔(header file),這些標頭檔中會包含一些函數(function),`include`進來,電腦才知道那些函數是什麼。最基本的標頭檔叫做`iostream`就是I/O stream也就是輸入輸出串流類似python的`import` > > ```c++=1 > #include <./iostream> //其實不用打./,只是編講義的格式需求 > ``` > 如果說是要打比賽或是考apcs之類的,就不要在那邊記標頭檔,通通都用`bits/stdc++.h`就好了,這個標頭檔裡面就幫你`include`了幾乎所有有可能用到的標頭檔了,要理解他的具體原理之類的有點複雜,如果只是為了打比賽之類的死記就好了 > ```c++=1 > #include <bits/stdc++.h> > ``` ## main() > C++程式中最重要的就是`main()`,他是主程式,當成是開始執行的時候,就會從`main()`開始,然後在執行其他指令 > ```c++=1 > #include <bits/stdc++.h> > > int main(){ > return 0; //這一行是要讓main回傳0,讓程式結束 >} > ``` ## I/O > 寫程式學的第一個東西當然就是輸出輸入,在C++中,輸出輸入分成兩種,一種是`cin cout`另一種是`scanf printf`,這兩種都可以用,但是`scanf printf`很難用,一般來說都會選擇用`cin cout` > Cpp的`cin cout`在使用前要先打一行`using namespace std;`這樣電腦才知道`cin cout`是什麼 > Cpp的輸出一般來說是`cout`一次,就輸出一次,但是這樣在打比賽等有執行時間壓力的時候就會慢很多,因此可以將所有輸出的資料先堆起來,等程式結束一次輸出,具體寫法在下面 > ```c++=1 > #include <bits/stdc++.h> > using namespace std; > > int main(){ > ios::sync_with_stdio(0); //這兩行要記得,很重要 > cin.tie(0); > > cout << "hello world"; > > return 0; >} > ``` > ### output > ``` > Hello world > ``` ## 變數(variable) > C++的變數在使用之前,要先向電腦宣告,具體語法是`type variable_name = value;`,其中`value`可空白 ### 1.types > C++中的各種type有嚴格的分類,中間幾乎是不通用的,以下幾種類型都很重要,也很常用 > 1.`int`全名integer,是整數,在記憶體中佔4byte,上限是2^31^-1,下限是-2^31^ > 1-1.`int`的另外一種形態叫做`long long`,叫做長整數,在記憶體中佔8byte,上下限從原本的2^31^變成2^63^,通常用來儲存大於2^31^-1的數 > 2.`double`是倍精準浮點數,其實浮點數還有一個`float`但是因為不好用,而且誤差偏大,所以無論是在做開發還是打比賽都會選擇用`double`,在記憶體中佔8byte > 3.`string`是字串,說簡單點就是一串字,由複數個字元組成,沒有硬性的記憶體限制,具有疊加性,也就是兩個字串可以直接加起來,在程式中要用`""`括起來,用`''`的話,會變成字元 > 4.`char`是字元,就是單一一個的字,在記憶體中佔1byte,範圍是0~255,其值可由ascii table對照成字元,在程式中`char`要用`''`去括起來,不能用`""`不然會變成字串 > 5.`bool`是布林值,佔1byte,代表`true`或`false`,另外,除了0以外的所有數值,如果換成布林值都是`true`,只有0是`false` ### 2.變數的處理 > 變數的用處最直接就是存儲資料,但是居然都叫變數了,當然是可以動的,不然就變成常數了,所以要學怎麼給變數做改變 > 變數要改變,就直接就是用`=`,例如`a = 1;`就是將`a`存的資料變成1 > 數字的資料在改變的時候還有其他的方法,就是`a++`和`a--`,意思是`a = a + 1`,至於`a++`跟`++a`的差別在於先處理和後處理,用實際案例更好懂 > ```c++=1 > #include <bits/stdc++.h> > using namespace std; > > int main(){ > ios::sync_with_stdio(0); > cin.tie(0); > > int n = 3; > cout << n++ << '\n'; //先輸出了n在執行了n = n + 1 > cout << ++n; //先執行n = n + 1後再輸出 > > return 0; >} > ``` > ### output > ``` > 3 > 5 > ``` ## 判斷式 > 數學上經常會用到的`>`, `<`, `=`等,在程式中也經常用到,具體用法就是`a > b`之類的,使用後會有一個布林值的回傳,注意,數學上的`=`在程式中是給變數賦值,`==`才是數學上的`=` > ```c++=1 > #include <bits/stdc++.h> > using namespace std; > > int main(){ > ios::sync_with_stdio(0); > cin.tie(0); > > cout << (1 <= 2) << '\n'; > cout << (2 == 2) << '\n'; > cout << (1 >= 2) << '\n'; > > return 0; > } > ``` > ### output > ``` > 1 > 1 > 0 > ``` ## 條件判斷(if else) > 在執行程式時經常需要進行條件的判斷,這時候就可以用`if`, `else`等做判斷 > 1.`if`的用法是`if (bool)`,通常會在`bool`的地方放判斷式 > 2.`else`是當前面的`if`判斷式為`false`時執行的 > ```c++=1 > #include <bits/stdc++.h> > using namespace std; > > int main(){ > ios::sync_with_stdio(0); > cin.tie(0); > > int n = 10; > > if (n < 10){ > cout << "n < 10"; > }else{ > cout << "n >= 10"; > } > > return 0; > } > ``` > ### output > ``` > n >= 10 > ``` ## 迴圈(loop) > C++的迴圈有三種,分別是`for`, `while`, `do-while`,都是重複執行的一種做法 > 1.`for`迴圈的寫法是`for (第一圈執行的;持續條件;每一圈的執行的)` > 2.`while`迴圈的寫法是`while (bool)` > 3.`do-while`迴圈的寫法是`do{...}while(bool)`跟`while`差別在於至少會執行一次 > ```c++=1 > #include <bits/stdc++.h> > using namespace std; > > int main(){ > ios::sync_with_stdio(0); > cin.tie(0); > > for (int i = 0; i < 10; i++){ //這裡寫i++跟++i都可以 > cout << i << ' '; > } > > cout << '\n'; > > int a = 10; > > while (a){ //當a不等於0時就會持續運行 > cout << a-- << ' '; > } > > cout << '\n'; > > do{ //至少跑一圈 > cout << a << '\n'; > }while (a); > > return 0; >} > ``` > ### output > ``` > 0 1 2 3 4 5 6 7 8 9 > 10 9 8 7 6 5 4 3 2 1 > 0 > ``` ## 陣列(array) > 陣列是一連串的同一類型的資料,就像是名單一樣,存儲著一連串的名字,其中的值可以用`[index]`去提取,跟變數一樣要用宣告的`type arr_name[lenth] = {data};` > 其中`lenth`或是`data`其中一個可空白,如果說不給`lenth`的話,程式會自動從後面`data`的個數去判斷要多長,不打`data`的話,就是一個長度`lenth`的空陣列,但是`type arr_name[lenth];`和`type arr_name[lenth] = {};`是不一樣的,沒有大括弧的話,陣列的內容會是亂碼,有的話就會是0 > 另外,陣列的長度是固定的,想要改變的話要用記憶體配置,非常的麻煩 > ```c++=1 > #include <bits/stdc++.h> > using namespace std; > > int main(){ > ios::sync_with_stdio(0); > cin.tie(0); > > int arr[10] = {}; //宣告名為arr的陣列 長度為10 > > for (int i = 0; i < 10; i++){ > arr[i] = i; //將arr的第i項設為i > } > for (int i = 0; i < 10; i++){ > cout << arr[i] << ' '; //輸出 > } > > return 0; > } > ``` > ### output > ``` > 0 1 2 3 4 5 6 7 8 9 > ``` > ### 補充 二維陣列 > 前面講的是一維陣列,就像是數學的數列一樣 > 這裡要講的二維陣列就像是數學的行列式,由行跟列組成,是一種平面上的資料 > ```c++=1 > #include <bits/stdc++.h> > using namespace std; > > int main(){ > ios::sync_with_stdio(0); > cin.tie(0); > > int arr[10][10] = {}; //宣告名為arr的二維陣列 大小是10x10 > > for (int i = 0; i < 10; i++){ > for (int j = 0; j < 10; j++){ > arr[i][j] = i+j; //將arr的第i行j列的值設成i+j > } > } > > for (int i = 0; i < 10; i++){ > for (int j = 0; j < 10; j++){ > cout << arr[i][j] << ' '; //輸出 > } > cout << '\n'; > } > > > return 0; > } > ``` > ### output > ``` > 0 1 2 3 4 5 6 7 8 9 > 1 2 3 4 5 6 7 8 9 10 > 2 3 4 5 6 7 8 9 10 11 > 3 4 5 6 7 8 9 10 11 12 > 4 5 6 7 8 9 10 11 12 13 > 5 6 7 8 9 10 11 12 13 14 > 6 7 8 9 10 11 12 13 14 15 > 7 8 9 10 11 12 13 14 15 16 > 8 9 10 11 12 13 14 15 16 17 > 9 10 11 12 13 14 15 16 17 18 > ``` ## vector > vector這個單字在英文裡原本的意思是向量,但是在C++中`vector`就不是向量了,他是一種類似陣列的東西,不同的是的他可以自己改變長度 > 在新增資料的時候他就會自己變長,處理的時間依資料而定 > 當刪除資料的時候,他也會自己變短,處理的時間是固定的 > ```c++=1 > #inlcude <bits/stdc++.h> > using namespace std; > > int main(){ > ios::sync_with_stdio(0); > cin.tie(0); > > vector< int> v{1,2,3,4}; //宣告就做v的vector > > for(int i = 0;i < 4;i++){ > cout << v[i] << '\n'; > } > return 0; >} > ``` > ### output > ``` > 1 > 2 > 3 > ``` ## function > `function`並不是一個叫做`function`的函數,而是一種用法,前面說過`main`是主程式,實際上應該叫做主函數更貼切,總之就是可以自訂一個函數,去處理事情 > ```c++=1 > #include <bits/stdc++.h> > using namespace std; > > int func(int n, int m){ //前面的int是設定這個函數return的類型 > return n + m; //在int的函數裡面 return的type就要是int > } > > int main(){ > > ios::sync_with_stdio(0); > cin.tie(0); > > int ans; > > ans = func(1, 2); //讓ans等於func處理(0, 1)的結果 > cout << ans << '\n'; > } > ``` > ### output > ``` > 3 > ``` ## struct > `struct`可以建立一種自訂的`type`,然後再用去宣告自己要的結構,用以儲存一坨資料,注意不是像`array`那樣的多筆資料 > ```c++=1 > #incldue <bits/stdc++.h> > using namespace std; > > int main(){ > > ios::sync_with_stdio(0); > cin.tie(0); > > struct { //設定type > int num; > string str; > } Struct1; //用定好的type去宣告名叫Struct1的結構 > > Struct1.num = 1; //根據宣告的結構,把裡面的num設定成1 > Struct1.str = "Hello world"; > > cout << Struct1.num << '\n' << Struct1.str << '\n'; >} > ``` > ### output > ``` > 1 > Hello world > ``` ## class > `class`是一個物件的類型,一個`class`中可以包含多種函數,函數比平時多了一個屬性:`private`和`public` ||其實還有一個protected,但是我真的搞不懂那到底是怎樣,所以我這裡就不寫了|| `public`是可以讓程式再`class`外讀取的函數,`private`不行 > ```c++=1 > #include <bits/stdc++.h> > using namespace std; > > class object{ > public: //public是class外面可以讀取的 > void plus_and_minus(int n, int m){ > cout << plus(n, m) + minus(n, m) << '\n'; > } > private: //private是只有class才可以呼叫的 > int plus(int n, int m){ > return n + m; > } > int minus(int n, int m){ > return n - m; > } > }; //注意這裡一定要加分號 > > int main(){ > > ios::sync_with_stdio(0); > cin.tie(0); > > object obj; //宣告名為obj的物件 class是前面定義的object > obj.plus_and_minus(1, 2); //使用class裡面的plus_and_minus函數 > } > ``` > ### output > ``` > 2 > ```