臺中一中電研社C++教學講義
===
>[name=張皓凱、沈奕呈][time=Sep 24,2021]
###### tags:`tcirc` `社課` `C++` `台中一中電研社`
---
第一節社課
===
[TOC]
---
## 開始
首先感謝大家來參加我們電研社,沒接觸過`c++`的人不用擔心,我們會從零基礎教起,而且會盡量用讓大家容易懂的方式教喔,有任何不清楚的地方都可以舉手發問,回家可以練練題目讓自己進步更快喔;
如果是去年已經來過`c++`班的資深社員可以考慮看看新開的python班,或是解解我們電研開的judge😛
---
## tcirc judge
-[https://judge.tcirc.tw/](https://judge.tcirc.tw/)
---
## C++
> C++是一種被廣泛使用的電腦程式設計語言。它是一種通用程式設計語言,支援多重程式設計模式,例如:程序化程式設計、資料抽象化、物件導向程式設計、泛型程式設計和設計模式等。
(引用自維基百科)
----
反正就是通用,很多平台支援,歷久不衰,適合用於畫面呈現需求低作業👍👍
---
## IDE
> 整合開發環境(Integrated Development Environment,簡稱IDE),是一種輔助程式開發人員開發軟體的應用軟體,在開發工具內部就可以輔助編寫原始碼文字、並編譯打包成為可用的程式。
(引述自維基百科)
簡單來說就是可以幫助你寫程式更方便的一種軟體,常見的有:codeblock, devc++, eclipse, visual stdio...
----
IDE主要有的功能有:
1. 將程式碼上色以方便閱讀
2. 自動排版
3. 智慧完成程式碼(Intelligent code completion)
4. 將編譯這個麻煩的動作變成一個按鈕
5. 預覽圖形介面(GUI)
6. 除錯(debug)
---
## 編譯(compile)(補充)
程式語言一共分成三種,高階語言、組合語言(Assembly Language)及機器語言(Machine Code),一般常聽到的程式名稱都是高階語言,例如:C++, python, java, javascript, ruby...而高階語言及組合語言是讓人類看的,電腦是無法閱讀的,所以這時候就需要一個翻譯,那就是編譯器。這三種語言的關係圖如下:
----
![](https://i1.wp.com/kopu.chat/wp-content/uploads/2017/04/e89ea2e5b995e5bfabe785a7-2017-04-14-23-14-38.png?resize=1180%2C491&ssl=1)
(圖源:https://kopu.chat/2017/04/14/arm-intel-cpu/)
----
**C++:**
```cpp=
#include<iostream>
using namespace std;
int main(){
cout<<"hello world"<<'\n';
return 0;
}
```
----
**組合語言:**
```assembly=
.LC0:
.string "hello world"
main:
push rbp
mov rbp, rsp
mov esi, OFFSET FLAT:.LC0
mov edi, OFFSET FLAT:_ZSt4cout
call std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)
mov esi, 10
mov rdi, rax
call std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char)
mov eax, 0
pop rbp
ret
__static_initialization_and_destruction_0(int, int):
push rbp
mov rbp, rsp
sub rsp, 16
mov DWORD PTR [rbp-4], edi
mov DWORD PTR [rbp-8], esi
cmp DWORD PTR [rbp-4], 1
jne .L5
cmp DWORD PTR [rbp-8], 65535
jne .L5
mov edi, OFFSET FLAT:_ZStL8__ioinit
call std::ios_base::Init::Init() [complete object constructor]
mov edx, OFFSET FLAT:__dso_handle
mov esi, OFFSET FLAT:_ZStL8__ioinit
mov edi, OFFSET FLAT:_ZNSt8ios_base4InitD1Ev
call __cxa_atexit
.L5:
nop
leave
ret
_GLOBAL__sub_I_main:
push rbp
mov rbp, rsp
mov esi, 65535
mov edi, 1
call __static_initialization_and_destruction_0(int, int)
pop rbp
ret
```
----
**機器語言:**
會由一堆0和1構成,但因為過於攏長,這裡就不列出了。
以上的內容聽不懂就算了,對於以後寫程式不會有什麼影響。
---
## hello world
```cpp=
#include<iostream>
using namespace std;
int main(){
//this program will print hello world
cout<<"hello world"<<'\n';
return 0;
}
```
```
/*OUTPUT---
hello world
------------*/
```
---
### #include (工具箱🧰)
```cpp=
#include<iostream>
```
用來引入一些寫好的程式碼("標頭檔"),包含許多函數和物件(工具🔧),而`<iostream>`標頭檔包含一些基本物件及函式
---
### namespace (哪來的工具)
```cpp=
using namespace std;
```
用來區分函式及物件所屬的函式庫,通常我們使用的為標準函式庫(standard library)
---
### main{} (主要工作區)
```cpp=
int main(){
// your code goes here
return 0;
}
```
稱作「主函式」,由作業系統呼叫,並從此函式開始執行程式碼
大部分的程式會寫在這裡,也就是 `{` 到 `}` 之間
(在主函式之前可以寫全域變數、函式、前置編譯指令)
---
### cout
```cpp=
cout<<"hello world"<<'\n';
```
執行程式時可以把想輸出的東西(數字、字元、字串)顯示在使用者的畫面上,cout後面要加上 `<<` 再接上想要輸出的東西
這裡要輸出字串(兩個以上的字或中文字),得用雙引號(`" "`)放在字串前後
---
### 註解
```cpp=
//this program will print hello world
```
這行就是註解,如果要寫的程式有點複雜的時候(要做不只一件事情),寫註解可以提醒你要做哪些事情、一項一項來看事情有沒有做好(就像寫待辦事項一樣);
當你以後重新回來看這支程式(或是和其他人合作寫一支程式)的時候,可以比較快理解每行程式碼在做什麼🤔🤔
----
寫法:
- 單行註解:先打上 `//` 再寫上註解
- 多行註解:用 `/*` 和 `*/` 把註解包起來
註解單純只是寫給人理解程式碼用的,裡面的內容是不會被編譯,也不會被執行的。所以裡面要寫什麼都可以(包括程式碼)
---
### 分號 `;`
請在每行程式碼結束的地方(通常是最後面)加上分號
**這很重要**
就像寫作文要分段一樣,不在後面加上分號的話系統執行會出錯
(就像作文老師會毫不留情給你0級分😂😂)
---
### 題目練習:[b003: Hello,TCFSH!](https://judge.tcfsh.tc.edu.tw/ShowProblem?problemid=b003)
- 練習cout
---
## 各種型態的輸出
```cpp=
cout<<"hello world"<<'\n';
```
- 數字與變數
純數字或「變數」的輸出前後不用加東西
- 字元
單一個字(英文、數字、符號)的輸出得用單引號(' ')放在字元前後(**中文**算字串得用雙引號)
- 字串
兩個字以上和**中文**的輸出得用雙引號(" ")放在前後
- 跳脫字元
這個的輸出也是得用單引號(' ')放在前後,下一頁是它的獨立介紹
---
### 跳脫字元
跳脫字元是在特定字元前加上一個反斜線(`\`),為了讓系統知道某些符號不是用於特殊功能,就只是一個字元而已,或是模擬鍵盤上的其他功能
----
#### 一些跳脫字元
- ‘\0’ 空字元,用於字串的結束
- ‘\n’ New Line,換行符號
- ‘\r’ Carriage Return,回歸鍵(即 Enter 鍵)
- ‘\t’ Tab,跳格
- ‘\b’ Backspace,倒退鍵
- ‘\a’ Bell,嗶一聲
- ’ \\\\ ’ 反斜線 \
- ’ \’ ’ 單引號 ’
- ’ \\" ’ 雙引號 "
---
### 題目練習:[b004: 串串的強迫症](https://judge.tcfsh.tc.edu.tw/ShowProblem?problemid=b004)
- 練習使用跳脫字元
---
## 變數
存放在電腦裡的資料,不能更動的稱為常數,可以更改內容的則稱為變數。類似於數學中的x, y。
----
### 宣告
在C++中任何的變數都需要先透過宣告後才能夠使用,相當於數學中要先假設未知數後,才可以使用未知數。而宣告的方法如下:
```cpp=
資料型態 變數名稱;
int a;
float b;
char c;
int d, e;
```
在宣告時對於同資料型態的變數可以同時宣告多個變數,只需要在各個變數之間加上逗號即可。
----
* 變數名稱是自己決定的,可以是任何未被定義的英文及數字字串。已經被定義的字串例如:資料型態名稱(int, float, char),純數字(2, 56),函式名稱(sort, upper_bound)
* 變數名稱建議使用方便辨識及輸入的字串,如:a, temp, num
* **<font color="#f00">每行結束務必記得加分號!</font>**
----
### 賦值
有了變數之後就可以設定變數的值,將一個變數的記憶體覆寫為一個值的過程就稱為賦值。
實際操作上會使用`=`來賦值,賦值可以在宣告變數後的任何地方進行,並且新的值會覆蓋過原本的值。賦值也可以在宣告時就同時進行。
```cpp=
#include <iostraem>
using namespace std;
int main(){
int a;
a = 1;
int b = 2;
a = 3;
//a=3, b=2
int c = 3, d = 4;
// c=3, d=4
}
```
----
### 輸出
如果想要知道一個變數的值可以透過前面教過的`cout`來輸出。此時只需要在`<<`後加上變數名稱即可。
**注意:此處不需要使用`""`**,加上`""`後程式會將`""`內的認定為字串輸出。
```cpp=
#include <iostraem>
using namespace std;
int main(){
int a=1;
cout << a << endl;
a = 3;
cout << a << endl;
cout << "a" << endl;
}
```
```
/*OUTPUT---
1
3
a
------------*/
```
----
### 資料型態
前面一直提到的資料型態究竟是什麼呢?資料型態就是指變數的種類,以下列舉出一些C++常見的變數:
----
| 型態 | 類型 | 占用記憶體(bytes) | 可存放範圍 |
|:------------:| --- |:----------:|:------------------------------------------------:|
| int | 整數 | 4 | $-2^{31}$ ~ $2^{31}-1$ |
| unsigned int | 整數 | 4 | $0$ ~ $2^{32}-1$ |
| short int | 整數 | 2 | $-2^{15}$ ~ $2^{15}-1$ |
| float | 小數 | 4 | ±$3.4×10^{-38}$ ~ ±$3.4×10^{38}$<br>有效位數 7位 |
----
| 型態 | 類型 | 占用記憶體(bytes) | 可存放範圍 |
|:------------------:| --- |:----------:|:---------------------------------------------------:|
| double | 小數 | 8 | ±$1.7×10^{-308}$ ~ ±$1.7×10^{308}$<br>有效位數 15位 |
| char | 字元 | 1 | $0$ ~ $255$ (ASCII碼) |
| bool | 布林 | 1 | true, false |
| long long | 整數 | 8 | $-2^{63}$ ~ $2^{63}-1$ |
| unsigned long long | 整數 | 8 | $0$ ~ $2^{64}-1$ |
----
### 字元
字元這一種資料型態在宣告時有兩種方式,第一種是在`''`內輸入字元,第二種是直接輸入0~255之間的數字(不須`''`)。而所有字元以及其對應的數字可以參考ASCII碼
----
![](https://i.imgur.com/mEFiLy9.gif)
![](https://i.imgur.com/ASqcwId.gif)
(圖源:http://kevin.hwai.edu.tw/~kevin/material/JAVA/Sample2016/ASCII.htm )
(Dec:十進位,Hex:十六進位)
----
```cpp=
#include <iostream>
using namespace std;
int main(){
char a = 'A';
char b = 65;
char c = '65';
cout << a << " " << b << " " << c;
}
```
```
/*OUTPUT---
A A 5
------------*/
```
變數a與b都是字元的宣告方法,而c因為字元型態本身就只能儲存一個字元,故只有最後面那位會被儲存。
---
## cin
你可能覺得為什麼聽到現在,感覺不像在寫程式的?因為程式的目的是為使用者做事情,所以我們必須從使用者取得資料,此時我們就需要輸入(input)了。在C++,中要取得輸入時可以使用`cin`,使用方法類似`cout`。
```cpp=
cin >> 希望此資料存放的位置(即變數);
```
----
```cpp=
#include <iostream>
using namespace std;
int main(){
int a;
cin >> a;
cout << a;
}
```
```
/*INPUT---
565
------------*/
/*OUTPUT---
565
------------*/
```
---
## 運算子
有特定運算功能的符號即稱為運算子,以下皆為運算子的舉例。
| 運算子 | 說明 |
|:-------:|:--------:|
| + - * / | 加減乘除 |
| % | 取餘,a%b = a除以b的餘數 |
| == >< >= <= | 比較運算子,回傳值是bool |
| ! | 將一個bool值做反向 |
| \|\| && | OR/AND 邏輯運算 |
----
### 設定運算子
前面提到賦值用的`=`就是屬於設定運算子
### 算數運算子
常見的算數運算子有`+`、`-`、`*`、`/`、`%`,分別代表加、減、乘、除、取餘。
---
## 運算式
程式裡總不可能所有的變數都是先設定好或者是輸入的,程式的一大意義就是要幫你計算。這時候當你想要對一個變數進行運算時就需要使用到運算式了。
----
### 基本寫法
```cpp=
變數 = 常數或變數 算數運算子 常數或變數;
//將左邊變數設定成右邊運算的結果
```
這裡的`=`是賦值得意思,並非數學上兩邊相等的意思。
----
```cpp=
#include <iostream>
using namespace std;
int main(){
int a = 1, b = 2, c;
c = 4 + 3;
cout << c << " ";
c = 5 - b;
cout << c << " ";
c = a * 2;
cout << c << " ";
c = b / a;
cout << c << " ";
c = (b+5)%4;//程式中一樣可以透過括號來進行優先運算
cout << c << endl;
c=(a+1)*(b+9); //但任何的運算符號都不能被省略
//c=(a+1)(b+9)此行是錯誤的
}
```
```
/*OUTPUT---
7 3 2 2 3
------------*/
```
----
### 簡寫
```cpp=
#include <iosream>
using namespace std;
int main(){
int i=1;
i = i + 5;
i += 5;
}
```
從上面這隻程式我們可以發現第五行的地方是運算式的基本寫法,但左右兩邊都出現了i,~~於是我們就可以把兩邊都消掉i~~(設定運算子不能這樣用),於是懶惰的程式設計師就發明了簡寫,如第六行所示。
----
```cpp=
int i;
//這兩行是一樣的意思
變數A = 變數A 算數運算子 常數或變數;
變數A 算數運算子= 常數或變數;
i = i + 9;
i += 9;
//這三行是一樣的意思
i += 1;
i++;
++i;
//這三行是一樣的意思
i -= 1;
i--;
--i;
```
----
### `i++`與`++i`的差異(補充)
`++i`是先做,`i++`是後做,什麼先做後做的聽起來很抽象,那就直接看範例吧
```cpp=
#include<iostream>
using namespace std;
int main(){
int i=1;
cout<<"1:"<<i++<<endl;
cout<<"2:"<<i<<endl;//i++會先輸出後才進行i=i+1
i=1;
cout<<"3:"<<i<<endl;
cout<<"4:"<<++i<<endl;//而++i則是先進行i=i+1後才輸出
cout<<"5:"<<i<<endl;
}
```
```
/*OUTPUT---
1:1
2:2
3:1
4:2
5:2
------------*/
```
---
## 資料型態之間的轉換
----
### 數字
不同的資料型態在計算時會發生一些變換,在撰寫程式時必須特別注意以下規則:
1. 當整數和浮點數進行運算時,統一轉換為浮點數運算。否則一律以整數運算
2. 當2個大小不同的整數/浮點數做運算時,較大的型別會被採用。short一律當作int計算
3. 字元做運算時,統一轉換為整數
4. 在賦值時,「計算結果」統一轉換為該變數的資料型態(計算時依舊為原計算模式)利用(資料型態)可作強制轉換
----
```cpp=
#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' << ' ' << '\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';
}
```
```
/*OUTPUT---
1666
1666.67
2 4.5 4
70 130
25000000 30784
------------*/
```
----
### 數字及字元
可以利用`(int)`及`(char)`對字元及整數進行轉換,轉換結果會依照ASCII碼。若是想要將`'0'~'9'`之間的字元轉換為`0~9`的數字,可以透過`-'0'`來達成。
```cpp=
#include <iostream>
using namespace std;
int main(){
int a = 65;
char b = 'a';
char c = '5';
int d = c;
int e = c - '0';
cout << (char)a << " " << (int)b << endl;
cout << d << " " << e;
}
```
```
/*OUTPUT---
A 97
53 5
------------*/
```
---
## 溢位
既然資料型態有範圍,那如果數字超出了範圍會怎樣?當變數的值超出範圍,我們就稱這個情況為溢位(overflow)。如果我們宣告(int)一個整數i的值為2147483647,值的範圍會落在int的範圍內。但是這時我們使 i+1 便會發生溢位的狀況,這時的i會回到int的最小值-214748348。
---
## 題目練習
* [b005: 電電的三角形](https://judge.tcfsh.tc.edu.tw/ShowProblem?problemid=b005)
* [b006: 電電的梯形](https://judge.tcfsh.tc.edu.tw/ShowProblem?problemid=b006)
* [b007: 邊緣的串串](https://https://judge.tcfsh.tc.edu.tw/ShowProblem?problemid=b007)
{"metaMigratedAt":"2023-06-16T10:12:35.698Z","metaMigratedFrom":"YAML","title":"C++教學講義-第一週","breaks":true,"slideOptions":"{\"theme\":\"blood\",\"transition\":\"slide\"}","contributors":"[{\"id\":\"a031de8f-38ef-4123-9d53-e13dd69cbbc3\",\"add\":590,\"del\":19},{\"id\":\"bd47cc0a-d3e4-4997-b042-3ae3230b8982\",\"add\":33,\"del\":33},{\"id\":\"6a5475c5-bfd3-428c-9219-c760b9000deb\",\"add\":13103,\"del\":2030}]"}