臺中一中電研社C++教學講義

張皓凱、沈奕呈Sep 24,2021

tags:tcirc 社課 C++ 台中一中電研社

第一節社課


開始

首先感謝大家來參加我們電研社,沒接觸過c++的人不用擔心,我們會從零基礎教起,而且會盡量用讓大家容易懂的方式教喔,有任何不清楚的地方都可以舉手發問,回家可以練練題目讓自己進步更快喔;
如果是去年已經來過c++班的資深社員可以考慮看看新開的python班,或是解解我們電研開的judge😛


tcirc judge

-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://kopu.chat/2017/04/14/arm-intel-cpu/)


C++:

#include<iostream> using namespace std; int main(){ cout<<"hello world"<<'\n'; return 0; }

組合語言:

.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

#include<iostream> using namespace std; int main(){ //this program will print hello world cout<<"hello world"<<'\n'; return 0; }
/*OUTPUT---
hello world
------------*/

#include (工具箱🧰)

#include<iostream>

用來引入一些寫好的程式碼("標頭檔"),包含許多函數和物件(工具🔧),而<iostream>標頭檔包含一些基本物件及函式


namespace (哪來的工具)

using namespace std;

用來區分函式及物件所屬的函式庫,通常我們使用的為標準函式庫(standard library)


main{} (主要工作區)

int main(){ // your code goes here return 0; }

稱作「主函式」,由作業系統呼叫,並從此函式開始執行程式碼
大部分的程式會寫在這裡,也就是 {} 之間
(在主函式之前可以寫全域變數、函式、前置編譯指令)


cout

cout<<"hello world"<<'\n';

執行程式時可以把想輸出的東西(數字、字元、字串)顯示在使用者的畫面上,cout後面要加上 << 再接上想要輸出的東西
這裡要輸出字串(兩個以上的字或中文字),得用雙引號(" ")放在字串前後


註解

//this program will print hello world

這行就是註解,如果要寫的程式有點複雜的時候(要做不只一件事情),寫註解可以提醒你要做哪些事情、一項一項來看事情有沒有做好(就像寫待辦事項一樣);

當你以後重新回來看這支程式(或是和其他人合作寫一支程式)的時候,可以比較快理解每行程式碼在做什麼🤔🤔


寫法:

  • 單行註解:先打上 // 再寫上註解
  • 多行註解:用 /**/ 把註解包起來

註解單純只是寫給人理解程式碼用的,裡面的內容是不會被編譯,也不會被執行的。所以裡面要寫什麼都可以(包括程式碼)


分號 ;

請在每行程式碼結束的地方(通常是最後面)加上分號
這很重要
就像寫作文要分段一樣,不在後面加上分號的話系統執行會出錯
(就像作文老師會毫不留情給你0級分😂😂)


題目練習:b003: Hello,TCFSH!

  • 練習cout

各種型態的輸出

cout<<"hello world"<<'\n';
  • 數字與變數
    純數字或「變數」的輸出前後不用加東西
  • 字元
    單一個字(英文、數字、符號)的輸出得用單引號(' ')放在字元前後(中文算字串得用雙引號)
  • 字串
    兩個字以上和中文的輸出得用雙引號(" ")放在前後
  • 跳脫字元
    這個的輸出也是得用單引號(' ')放在前後,下一頁是它的獨立介紹

跳脫字元

跳脫字元是在特定字元前加上一個反斜線(\),為了讓系統知道某些符號不是用於特殊功能,就只是一個字元而已,或是模擬鍵盤上的其他功能


一些跳脫字元

  • ‘\0’ 空字元,用於字串的結束
  • ‘\n’ New Line,換行符號
  • ‘\r’ Carriage Return,回歸鍵(即 Enter 鍵)
  • ‘\t’ Tab,跳格
  • ‘\b’ Backspace,倒退鍵
  • ‘\a’ Bell,嗶一聲
  • ’ \\ ’ 反斜線 \
  • ’ \’ ’ 單引號 ’
  • ’ \" ’ 雙引號 "

題目練習:b004: 串串的強迫症

  • 練習使用跳脫字元

變數

存放在電腦裡的資料,不能更動的稱為常數,可以更改內容的則稱為變數。類似於數學中的x, y。


宣告

在C++中任何的變數都需要先透過宣告後才能夠使用,相當於數學中要先假設未知數後,才可以使用未知數。而宣告的方法如下:

資料型態 變數名稱; int a; float b; char c; int d, e;

在宣告時對於同資料型態的變數可以同時宣告多個變數,只需要在各個變數之間加上逗號即可。


  • 變數名稱是自己決定的,可以是任何未被定義的英文及數字字串。已經被定義的字串例如:資料型態名稱(int, float, char),純數字(2, 56),函式名稱(sort, upper_bound)
  • 變數名稱建議使用方便辨識及輸入的字串,如:a, temp, num
  • 每行結束務必記得加分號!

賦值

有了變數之後就可以設定變數的值,將一個變數的記憶體覆寫為一個值的過程就稱為賦值。

實際操作上會使用=來賦值,賦值可以在宣告變數後的任何地方進行,並且新的值會覆蓋過原本的值。賦值也可以在宣告時就同時進行。

#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來輸出。此時只需要在<<後加上變數名稱即可。
注意:此處不需要使用"",加上""後程式會將""內的認定為字串輸出。

#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}\)
有效位數 7位

型態 類型 占用記憶體(bytes) 可存放範圍
double 小數 8 ±\(1.7×10^{-308}\) ~ ±\(1.7×10^{308}\)
有效位數 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碼



(圖源:http://kevin.hwai.edu.tw/~kevin/material/JAVA/Sample2016/ASCII.htm )
(Dec:十進位,Hex:十六進位)


#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

cin >> 希望此資料存放的位置(即變數);

#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 邏輯運算

設定運算子

前面提到賦值用的=就是屬於設定運算子

算數運算子

常見的算數運算子有+-*/%,分別代表加、減、乘、除、取餘。


運算式

程式裡總不可能所有的變數都是先設定好或者是輸入的,程式的一大意義就是要幫你計算。這時候當你想要對一個變數進行運算時就需要使用到運算式了。


基本寫法

變數 = 常數或變數 算數運算子 常數或變數; //將左邊變數設定成右邊運算的結果

這裡的=是賦值得意思,並非數學上兩邊相等的意思。


#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
------------*/

簡寫

#include <iosream> using namespace std; int main(){ int i=1; i = i + 5; i += 5; }

從上面這隻程式我們可以發現第五行的地方是運算式的基本寫法,但左右兩邊都出現了i,於是我們就可以把兩邊都消掉i(設定運算子不能這樣用),於是懶惰的程式設計師就發明了簡寫,如第六行所示。


int i; //這兩行是一樣的意思 變數A = 變數A 算數運算子 常數或變數; 變數A 算數運算子= 常數或變數; i = i + 9; i += 9; //這三行是一樣的意思 i += 1; i++; ++i; //這三行是一樣的意思 i -= 1; i--; --i;

i++++i的差異(補充)

++i是先做,i++是後做,什麼先做後做的聽起來很抽象,那就直接看範例吧

#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. 在賦值時,「計算結果」統一轉換為該變數的資料型態(計算時依舊為原計算模式)利用(資料型態)可作強制轉換

#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'來達成。

#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。


題目練習

Select a repo