--- title: C++教室第一節社課 slideOptions: # 簡報相關的設定 theme: blood # 顏色主題 transition: 'slide' # 換頁動畫 parallaxBackgroundImage: 'https://c.wallhere.com/photos/a5/a8/Neon_Genesis_Evangelion_mech_EVA_Unit_13-1319035.jpg!d' --- C++教室教學講義 === >[name=Howard] [time=September 18th] [color=#333] ###### tags:`tcirc` `社課` ---- [TOC] 第一節社課 === ---- ## 開場 歡迎各位來到電腦資訊研究社,在這邊也謝謝每位選擇電研的你們。在未來的六節社課中,顧及到剛進來的學弟,我們會從基礎開始教起。 <span>資深社員們嫌無聊也不要去打lol拉,我們電研有開judge,你把裡面的題目做一做再去打你的lol拉<!-- .element: class="fragment" data-fragment-index="1" --></span> <span>嗚嗚嗚 。゚(゚´ω`゚)゚。<!-- .element: class="fragment" data-fragment-index="2" --></span> ---- ## 上課講義服用方法 本講義採用HackMD簡報模式製作 [![HackMD](https://hackmd.gallerycdn.vsassets.io/extensions/hackmd/vscode-hackmd/1.1.2/1594261172870/Microsoft.VisualStudio.Services.Icons.Default)](https://hackmd.io/@howard60308/S1sZwObSP) 在畫面右下角可以看到藍色的箭頭可以換頁 ###### 補充: `有分x、y軸` `[esc]鍵可以選頁` ---- ## 所以... <span>什麼是C++?<!-- .element: class="fragment" data-fragment-index="1" --></span> ---- C++是一種被廣泛使用的電腦程式設計語言。它是一種通用程式設計語言,支援多重程式設計模式,例如程序化程式設計、資料抽象化、物件導向程式設計、泛型程式設計和設計模式等。 ---- 《C\++語言的設計和演化》(1994): * <span>C\++設計成直接的和廣泛的支援多種程式設計風格(程序化程式設計、資料抽象化、物件導向程式設計、泛型程式設計)。<!-- .element: class="fragment" data-fragment-index="1" --></span> * <span>C\++設計成給程式設計者更多的選擇,即使可能導致程式設計者選擇錯誤。<!-- .element: class="fragment" data-fragment-index="2" --></span> * <span>C\++設計成儘可能與C相容,藉此提供一個從C到C\++的平滑過渡。<!-- .element: class="fragment" data-fragment-index="3" --></span> * <span>C\++避免平台限定或沒有普遍用途的特性。<!-- .element: class="fragment" data-fragment-index="4" --></span> * <span>C\++不使用會帶來額外開銷的特性。<!-- .element: class="fragment" data-fragment-index="5" --></span> * <span>C\++設計成無需複雜的程式設計環境。<!-- .element: class="fragment" data-fragment-index="6" --></span> ---- 學長,上面的我都聽不懂怎麼辦:dizzy_face: <span>反正不知道也活得好好的<!-- .element: class="fragment" data-fragment-index="1" --></span> <span>有興趣自己去[維基百科](https://zh.wikipedia.org/wiki/C%2B%2B#C++%E5%90%8D%E5%AD%97%E7%9A%84%E7%94%B1%E4%BE%86)翻:stuck_out_tongue_closed_eyes: <!-- .element: class="fragment" data-fragment-index="2" --></span> ---- ## 撰寫第一個程式('Hello World') ``` c++= #include<iostream> int main(){ using namespace std; cout << "Hello World!"<<"\n"; return 0; } ``` ``` /*OUTPUT--- Hello World! ------------*/ ``` ---- ## include 用來引入標頭檔(header file),是一些已經寫好的程式碼,包含許多函式和物件,而\<iostream>標頭檔即包含了輸入(input)和輸出(output)的物件及函式。 ---- ## namespace 用來區分函式及物件所屬的函式庫,這裡所使用的函式庫為標準函式庫(standard library) ---- ## main{ } 稱作「主函式」,由作業系統呼叫,並從此函式開始執行程式碼。 而左大括號( \{ \)為函數區塊的開始,至右大括號( \} \)結束。 ##### `雖說是如此,但是「前置編譯指令」和「全域宣告」會優先於主函式執行。` <span>注意 : 當每個指令敘述結束時,必須以「 <font color="#F00">;</font> 」做結尾 <!-- .element: class="fragment" data-fragment-index="1" --></span> <span>而某個指令要使用的敘述不只一行的時候,我們也要使用{ }把敘述包起來 <!-- .element: class="fragment" data-fragment-index="2" --></span> ---- ## cout 在標頭檔\<iostream>中定義,為標準函式庫中的物件,所以正確名稱為 std::cout,但是因為有宣告 using namespace std,故寫cout即可。cout 的用法為使用串接運算子(<<)將資料輸入串流,而被雙引號所包含的"hello world"稱作「字串」,除了字串外,數字亦可以同種方式輸出。除此之外,cout還有許多更有趣的使用方法,之後會一一介紹。 ---- ## 題目實作[b003: Hello,TCFSH!](http://judge.tcfsh.tc.edu.tw/ShowProblem?problemid=b003) * 試著利用cout<<輸出字串吧 ---- ## 字串輸出與跳脫字元 ``` c++ cout << "Hello World!"<<"\n"; ``` 在我們要輸出Hello World!時的這串程式碼,Hello World!是作為字串(字元的集合體)的形態被輸出,C++把雙引號字元(")用作字串的分界符。 而字元中有些字元同時擔任兩種角色,平常做為一般字元,但在加上反斜線( \\ )後,會以跳脫字元的方式登場。 ---- ## 跳脫字元 這邊舉幾個跳脫字元的例子 * '\0' 空字元,用於字串的結束 * '\n' New Line,換行符號 * '\r' Carriage Return,回歸鍵(即 Enter 鍵) * '\t' Tab,跳格 * '\b' Backspace,倒退鍵 * '\a' Bell,嗶一聲 * ' \\\ ' 反斜線 \ * ' \\' ' 單引號 ' * ' \\" ' 雙引號 " ---- ## 控制字元 ```C++= #include<iostream> using namespace std; int main(){ cout << "Hello!\n"; cout << "Hello again!\n"; cout << "\tThis is a buuk\b\b\b\bbook\n"; cout << "but what if I want to type\"?\n"; cout << "\ayy you heard something?" << endl; cout << "\\aha!"; } ``` ``` /*OUTPUT--- Hello! Hello again! This is a book but what if I want to type"? yy you heard something? \aha! ------------*/ ``` ---- ## 題目實作[b004: 串串的強迫症](http://judge.tcfsh.tc.edu.tw/ShowProblem?problemid=b004) + 試著利用跳脫字元輸出「\」 ---- ## 宣告變數 存放在電腦裡的資料,不能更動的稱為常數,可以更改內容的稱為變數。在C++內,使用變數之前需要經過宣告,在為變數編輯一個名稱的同時也為其指定存放的資料型態。 ---- #### 如何宣告變數 首先宣告資料型別,然後給予名稱,可以觀察以下範例: ```c++= #include<iostream> using namespace std; int main(){ int num; num = 38; cout<<num<<"\n"; return 0; } ``` ``` /*OUTPUT--- 38 ------------*/ ``` ---- 我們在第4行宣告了一個變數叫做「num」,他是一個int型別的整數,這個時候電腦會找尋記憶體中的空間存放這個「num」變數,每當我們提及他的名字的時候,我們就會對那一塊記憶體進行操作。 第五行的num = 38是甚麼意思呢?「=」在C++(和大多數程式語言中)並非數學上的等號,而是「賦值」,也就是我們將「num」這塊記憶體種存放的資料複寫為38。 ---- ```c++= #include<iostream> using namespace std; int main(){ int num = 8; num = num*num + 1; cout<<num<<"\n"; return 0; } ``` ``` /*OUTPUT--- 65 ------------*/ ``` ##### tags:`每行結束記得加分號!` ---- | 型態 | 占用記憶體 | 可存放範圍 | |:------------:|:----------:|:----------------------:| | int | 4 | $-2^{31}$ ~ $2^{31}-1$ | | unsigned int | 4 | $0$ ~ $2^{32}-1$ | | short int | 2 | $-2^{15}$ ~ $2^{15}-1$ | | float | 4 | 1.2e-38 ~ 3.4e38 | | double | 8 | 2.2e-308 ~ 1.8e308 | | char | 1 | $0$ ~ $2^{8}-1$(256個字元)| | bool | 1 | true,false | ---- | 型態 | 占用記憶體 | 可存放範圍 | |:------------:|:----------:|:----------------------:| | long long | 8 | $-2^{63}$ ~ $2^{63}-1$ | |unsigned long long| 8 | $0$ ~ $2^{64}-1$ | ---- ## 溢位 如果我們這時宣告(int)一個整數i的值為2147483647,值的範圍會落在int的範圍內。但是這時我們使 i+1 便會發生<font color="#F00">溢位</font>的狀況,就像是計數器的內容達到最大值時會歸零一般,這時的i會回到int的最小值-214748348。 ---- ```C++= #include<iostream> using namespace std; int main(){ short k = 5000; k = k*k; int m = 5000; m = m*m; cout << k << " " << m; } ``` ``` /*OUTPUT--- 30784 25000000 ------------*/ ``` ---- ## 字元型態 ```C++= #include<iostream> using namespace std; int main(){ char a ='b'; cout<<a; } ``` ``` /*OUTPUT--- b ------------*/ ``` ---- ## 浮點數與整數的比較 ```C++= #include<iostream> using namespace std; int main(){ int k = 5000; double r = 5000; k = k/13; r = r/13; cout << k << ' ' << r << '\n'; int a; double b; a = 21445333; b = 21445333; cout << a << ' ' << b; } ``` ``` /*OUTPUT--- 384 384.615 21445333 2.14453e+007 ------------*/ ``` ---- ## 整數與字元的比較 ```C++= #include<iostream> using namespace std; int main(){ char a ='b'; cout<<a<<endl; cout<<"a"<<endl; cout<<int(a)<<endl; cout<<int('a')<<endl; } ``` ``` /*OUTPUT--- b a 98 97 ------------*/ ``` ---- 為什麼這些看似相同的語法能輸出不一樣的結果 ```c++ cout<<a<<"a"<<int(a)<<int('a'); ``` ---- ###### [ASCII碼的介紹](http://kevin.hwai.edu.tw/~kevin/material/JAVA/Sample2016/ASCII.htm) ![ascii碼表](https://pic.pimg.tw/isvincent/4b512eb611a6f.png) ---- ## 資料型態之間的轉換 不同的資料型態在計算時會發生一些變換,在撰寫程式時必須特別注意以下規則: * <span>當整數和浮點數進行運算時,統一轉換為浮點數運算。否則一律以整數運算<!-- .element: class="fragment" data-fragment-index="1" --></span> * <span>當2個大小不同的整數/浮點數做運算時,較大的型別會被採用。short一律當作int計算<!-- .element: class="fragment" data-fragment-index="2" --></span> * <span>字元做運算時,統一轉換為整數<!-- .element: class="fragment" data-fragment-index="4" --></span> * <span>在賦值時,「計算結果」統一轉換為該變數的資料型態(計算時依舊為原計算模式)<!-- .element: class="fragment" data-fragment-index="5" --></span> * <span>利用(資料型態)可作強制轉換<!-- .element: class="fragment" data-fragment-index="6" --></span> ---- ```C++= #include<iostream> using namespace std; int main(){ double a = 5000/3; //"5000/3" is calclated in int then assigned to double cout << a << '\n'; double b = 5000.0/3; //"5000.0/3" is calculated in double then assigned to double cout << b << '\n'; double c = 2.25; int d = c; //double is converted to int before assigning cout << d << ' ' << c*d << ' ' << (int)(c*d) << '\n'; char k = 'A'; //char is converted to int during compution cout << k + 5 << ' ' << k + 'A' << ' ' << (char)(k+5) << '\n'; short x = 5000; cout << x*x << ' '; //short is converted to int during compute x = x*x; //int is converted back to short during assignment cout << x << '\n'; int y = 2147483647; long long z = 1; cout << y+1 << ' ' << y+z << ' ' << (long long)(y+1) << ' ' << (long long)y+1'\n'; } ``` ---- ``` /*OUTPUT--- 1666 1666.67 2 4.5 4 70 130 F 25000000 30784 -2147483648 2147483648 -2147483648 2147483648 ------------*/ ``` ---- ## 整數(ascii碼)與字元(char)的轉換 從[ascii碼表](https://pic.pimg.tw/isvincent/4b512eb611a6f.png)中我們了解一個十進位整數可以對到一個字元,一樣利用資料型態轉換語法,我們也可以將整數型態轉為字元型態 ```c++= #include<iostream> using namespace std; int main(){ int x = 65; int y = 97; cout<<"整數"<<x<<"對應字元"<<(char)x<<"\n"; cout<<"整數"<<y<<"對應字元"<<(char)y<<"\n"; } ``` ``` /*OUTPUT--- 整數65對應字元A 整數97對應字元a ------------*/ ``` ---- ## 比較: 有沒有 ' ' ? ```c++= #include<iostream> using namespace std; int main(){ char x = 65; char y = '65'; cout<<x<<"\n"; cout<<y<<"\n"; } ``` ---- 你有想對嗎 ``` /*OUTPUT--- A 5 ------------*/ ``` 字元型態本身就只能儲存一個字元,故只有最後面那位會被輸出。 若是以整數(無 ' ' )賦值便會以ascii碼的方式進行儲存。 ---- ## 運算子 除了基本的加減乘除外,C++內還有各式各樣的其他運算子: | 運算子 | 說明 | |:------------:|:----------:| | + - * / | 加減乘除 | | % | 取餘數(a%b = a除以b的餘數) | | += -= *= /= %= | 表示對變數本身做運算(a += b相當於a = a+b) | | >> << | 位元左/右移(右移一次就是/2,左移就是*2) | ---- | 運算子 | 說明 | |------------|----------| | == > < <= >= | 比較運算子,回傳值是bool | | ! | 將一個bool值做反向 | | \| & ^ | OR/AND/XOR 位元運算 | | \|\| && | OR/AND 邏輯運算 | ---- ## bool(布林值)型態 ```C++= #include<iostream> using namespace std; int main(){ bool a = true; bool b = false; cout << a << b << endl; a = 3; b = -7; bool c = 0; cout << a << b << c << '\n'; a = (7 > 4); b = (5 == 20); c = (1 <= 2)||(2 <= 1); cout << a << b << c << '\n'; a = b||c; b = !((1 == 1)&&(2 <= 2)); c = !(-5); cout << a << b << c << '\n'; cout << a+a+a+a+a+a << '\n'; cout << (5 < 3) << (bool)(a+a+a+a+a+a); } ``` ---- ``` /*OUTPUT--- 10 110 101 100 6 01 ------------*/ ``` ---- ## cin 你或許在思考---我們到底在做什麼?沒有寫程式的感覺?程式的目的是為了要為使用者做事情,所以我們必須從使用者取得資料。此時我們要取得程式的輸入(input),要取得輸入必須用cin去取得,使用方法類似cout,我們要將輸入資料存放到記憶體---也就是變數中。 ---- ```C++= #include<iostream> using namespace std; int main(){ int k; //建立變數k cin >> k; //將取得的輸入賦值於k cout << k*k; //根據所輸入的數字做對應的輸出 } ``` ``` /*INPUT--- 85 ------------*/ /*OUTPUT--- 7225 ------------*/ ``` ---