NCUE-MECode
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Owners
        • Signed-in users
        • Everyone
        Owners Signed-in users Everyone
      • Write
        • Owners
        • Signed-in users
        • Everyone
        Owners Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights
    • Engagement control
    • Transfer ownership
    • Delete this note
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Versions and GitHub Sync Note Insights Sharing URL Help
Menu
Options
Engagement control Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Owners
  • Owners
  • Signed-in users
  • Everyone
Owners Signed-in users Everyone
Write
Owners
  • Owners
  • Signed-in users
  • Everyone
Owners Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       owned this note    owned this note      
    Published Linked with GitHub
    3
    Subscribed
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    Subscribe
    --- tags: 置頂,released, cpp --- <a rel="license" href="http://creativecommons.org/licenses/by-nc/3.0/tw/"><img alt="創用 CC 授權條款" style="border-width:0" src="https://i.creativecommons.org/l/by-nc/3.0/tw/88x31.png" /></a><br />本著作係採用<a rel="license" href="http://creativecommons.org/licenses/by-nc/3.0/tw/">創用 CC 姓名標示-非商業性 3.0 台灣 授權條款</a>授權. 在服用所有團隊內容前先看[這篇](/lwJ3tssyTpiFL8B3R8SUlw),~~不然 @yen0224 會打你屁屁~~,不遵守請立即離開,凡已觀看其他內容則視為已同意申明內條款 # C++ 教學講義 ==last updated: 2021, Mar 27^th^== ==新增陣列、~~函數~~== 課本解答參閱[程式範例解答](/J4UFI4rpR6i25jfOFxDGgQ/#C++)(目前編輯中進度約10%)\ 相關練習題在[GitHub](https://github.com/yen0224/NCUE_CPP_HW)\ ## 建議學習順序 1. [基本程式碼的概念](https://hackmd.io/4uvLo6aeTEGL1KEiA2oXFw?both#基本source-code架構) 2. [輸出入](https://hackmd.io/4uvLo6aeTEGL1KEiA2oXFw?view#基本輸出入) 3. [變數](https://hackmd.io/4uvLo6aeTEGL1KEiA2oXFw?both#基本內建型態primitive-built-in-type) 4. 條件if 5. while 6. for 7. 陣列 ## 建議編輯器: :::spoiler - [Jetbrains® CLion](https://www.itread01.com/content/1543921514.html)(IDE) ![](https://i.imgur.com/ZcB14wS.png) - [DevC++](https://sourceforge.net/projects/orwelldevcpp/)(IDE)https://hackmd.io/4uvLo6aeTEGL1KEiA2oXFw# ![](https://i.imgur.com/IbiUTrB.png) - [Visual Studio®](https://visualstudio.microsoft.com/zh-hant/)(IDE) ![](https://i.imgur.com/fR6hfxQ.png) - [VS Code](https://visualstudio.microsoft.com/zh-hant/)(欲編譯需配置/類IDE) ![](https://i.imgur.com/eFUOl6g.png) - [Code::Blocks](http://www.codeblocks.org) ![](https://i.imgur.com/ktyxjN3.png) > 以上都大同小異啦,但Visual studio通常都有自己的“功能”,上手需一段時間 - sublime(欲編譯需配置/類IDE) - atom(欲編譯需配置/類IDE) - Notepad++ (純指令編譯/非IDE) - Linux Vi/Vim (純指令編譯/非IDE) ::: ## 程式語言的發展 ### 程式語言大致可以分成三種:機器語言、組合語言和高(低)階語言 #### Machine Language 機器語言 微電腦最原始的語言—即僅以代表數位高低電位的1、0組成,並以不同的10組合代表不同的機器指令集,這種語言除了可讀性差之外,不同種的機器也有不同種的機器語言,然而這種語言絕對有必要存在,因為電腦***只看得懂這種語言***,因此為解決上述的兩種問題,勢必得找出機器語言的替代方案。 #### Assembly Language 組合語言 組合語言即為解決上述問題的其中一種方案,以一些特別的輔助記憶碼mnemonic來代替機器指令集,並建置出一個「組譯器」負責將記憶碼與該機器上的指令集進行轉換,以此方式,使得組譯語言可在不同的平台進行移植,並且大大的簡化了程式的開發過程。 ```assembly= add 2, 3, result ``` #### High-level Language 高階語言 高階語言與低階語言僅是相對的概念,通常把machine code, assembly code歸類於低階語言;現在大多學到的語言全數屬於高階語言,如C++, Python, Java, Visual Basic等 ![](https://i.imgur.com/UMVetV9.png) #### C與C++的不同: C相較於C++介於低階語言與高階語言間,較“貼近硬體的運作”,因此寫法較C++對人而言比較生澀難懂;C++則是赴著在C上的語言,C的header亦可用在C++中,且C++支援物件導向(object-oriented programming, OOP),對人較好理解 ## From Souce Codes To Executable Files C series語言的source code在進行編碼至機器碼的執行檔(windows是.exe, Unix系統是.out)前,皆會進行*前處理,編譯,組譯,連結*四部份,而C\++語言本身只含核心關鍵字,故我們在打c\++ source code時,需同時去引入(#include)相關的標頭,使前處理器可正常的運行 ![source code to executable file](https://i.imgur.com/hVNg9mg.gif) * 預先處理:預先處理是在進行編譯前的準備工作,包括去抓取header內容、將#define出來的東西將數字與文字做替換(就是把所有出現的這個名字東西都換成數字啦),並組合成一個檔案 > 預先處理過程就是將#include、#define、#if、特殊符號等*取出需要的東西後去除,且與原檔同義*,只有常數、字符串、變數定義、以及C關鍵字等[name=yen0224] * 編譯過程:在此階段中,編譯器會開始進行*語法的檢查及找出編譯路徑(優化)*,確認語法無誤後轉為組譯語言,接著組譯器開始再把由組譯語言轉換為機器語言,在輸出為目的檔。 * 連結:將上步驟中產生的目的檔將各種目標文件鏈結起來,將為定義標示符與其路徑做對應,最後產生一動態鏈結資料庫,或執行檔 命令列編譯指令:\ (前往cpp檔位置) ``` cd [address] ``` (name.cpp為檔名,請替換,a.out為預設名稱,不可更改) ``` g++ name.cpp && ./a.out ``` (optional parameter 自訂輸出檔名稱 ``` g++ -o name name.cpp ``` ### 前處理器 預處理器指示詞(例如 ==#define== 和 ==#ifdef== )通常用來讓來源程式在不同的執行環境中變得更容易變更和編譯。 來源檔案中的指示詞會指示前處理器採取特定動作。 例如,前置處理器可以取代文字中的語彙基元、將其他檔案的內容插入原始程式檔,或是透過移除文字區段來隱藏編譯檔案的一部分。 在巨集展開之前,會辨識並執行前置處理器程式行。 目前學習階段用到的前處理器keyword有: - #define: 用來宣告常數、亦可宣告簡易function(不嚴謹喔!!因無型別的定義) ```cpp= //語法 #define 識別符 值 #define PI 3.14 //定義PI為常數3.14 #define multiply( a1 , a2 ) ( a1 * a2)//定義multiply() ``` - #undef:取消#define的作用 ```cpp= //語法 #undef 識別符 #undef PI ``` - #include:告知前處理器指定檔案的內容包含在指示詞的位置 ```cpp= //語法 #include <標頭檔名> #include "路徑" #include <iostream> //宣告引入“iostream”標頭 #include <algorithms>//宣告引入“algorithms”標頭 #include "usr/lib/head.h"//宣告引入head.h自訂標頭 ``` - #if #elif #else:條件式 ### 基本source code架構 ```cpp= #include <iostream> using namespace std; int main(/*int argc, char const *argv[]*/) { return 0; } ``` #### 第一部分 #include \<iostream>: 告訴前處理器,此source code會用到名為*iostream*的*headers* - iostream 基本輸出入的標頭,包含ostream,istream - \"headers":標頭,為相關的函數\"定義"的地方 #### 第二部分int main(/\*int argc, char const \*argv[]*/){} - main function,為c++程式的基礎,是整個函式的主體,當作業系統執行程式時,呼叫的即是main() - function 就跟數學中的函數一樣,是一個工作模組,並允許參數的輸入,並執行特定任務,最後輸出結果 - int表示*回傳值*為整數型態(return type is integer) * int argc, int argc, char const \*argv[]:此為main function的參數列(parameter list) * int argc為宣告編號 * argc[0]為第一參數 * argv[1]為第二參數 * 「以此類推」 * 若此程式不需要任何參數資料以檔案等獨立形式輸入則可用void或直接留空代替 ```cpp= int main(void){} 或 int main(){} ``` - 註解:註解分為兩種形式,*單行註解* 與*多行註解* - 單行註解:以兩個斜線//作為開頭,此行的東西不會被編譯,也不會被輸出 ```cpp= //我是單行註解 ``` - 多行註解:以斜線和乘號成對表之,內容一樣無效果 ```cpp= /*我是多行註解 *(通常會加一個符號在前,其功能有二,一為對齊,二為告知在看的人此行為註解 */ ``` ---- #### 第三部分--大括號內的內容 括號內為函式的主要工作內容,return為回傳的關鍵字,在main函式中的return值較為特別,如同前面所說的“作業系統呼叫的是main函數”,同理main函數亦是回傳給作業系統直為電腦系統的,代表的是程式的執行狀態,0表示程式順利結束,其他非0零的值則由電腦做定義,*通常為錯誤碼* :::spoiler 若為自訂函式,可回傳變數、字串、矩陣、運算式值或空值,一樣要記得宣告函式時要同時宣告回傳值型別 ```cpp= void hello(){ cout<<"hello world"; } int returnMAX(int a1,int a2){ return (a1>a2)?a1:a2; } ``` ::: ---- ### 關鍵字與識別字 * 關鍵字keyword:為啟用相關功能、被定義於編譯器的字,可以解釋為“當這些字被打出來時,會有些預先定義的功能被發動”,根據微軟developer docs寫道“關鍵字是具有特別意義的預先定義保留識別項,他們無法當作程式中的識別字做使用”。 ![](https://i.imgur.com/JNiFzEs.jpg) * 識別字identifier:依程式需求自行定義的名稱,舉凡程式中所用的各種名稱都屬於識別字,標準程式庫、第三方程式庫中亦是。\ [最新資訊](https://en.cppreference.com/w/cpp/keyword) ## 基本輸出入 由於c\++可以說是由c語言「改良」後的新語言,故c語言的函式庫c\++皆可使用 (base on C.) ---- ### C++輸出入 #### \<iostream> cout cout物件,定義於iostream中,其可以將字串或數字輸出到標準輸出裝置上,和C語言中printf()相同,但使用法不同 cout物件可以接收由*串接運算子<<*所組成的字串,這些字串會依序組合成為一個更長的字串,再藉由cout物件輸出至螢幕上。 ```cpp= //語法 cout<<變數1或字串<<變數2或字串<<...<<變數n或字串; //example cout<<"hello world"; //(同義) cout<<"hello"<<" "<<"world"; //亦可與變數同時輸出 cout<<"After calculation, your BMI is"<<BMI; ``` 1. \<<為左移運算子 2. 可輸出運算式的結果、變數值、文字 3. 在句尾加endl,有換行和排清匯流排{可使資料立即顯示於螢幕上}的效果 ```cpp= cout<<........<<endl; ``` #### \<iostream> cin 相較於cout的輸出,cin則是用來從鍵盤中輸入各種資料,利用資料流截取運算子>>,即可讀取自鍵盤的輸入,供執行中的程式使用 ```cpp= cin>>[變數1](>>[變數2]>>...>>[變數n]); ``` ---- ### C輸出入 #### \<cstdio> printf() ```cpp= printf( const char* format, ... ); ``` - const char* format:填入輸出格式,後面填入參數 - 格式化方法: :::spoiler |參數 | 用途 | | :------: | :------: | | % | 格式化符| |%%|輸出%符號| | %d| 整數int| |%f|浮點數float| |%.nf|n為一數字,僅輸出到該位數| |%s|字串(可省)| ::: ---- Example: ```cpp= printf("abc");//輸出abc printf("%d",10);//輸出10 printf("%d",a);//輸出(整數)變數a值 printf("%f",0.1234)//輸出0.123400(預設輸出6位) printf("%.2f",0.1234)//輸出0.12 //多重參數 printf("今天的日期是:%d年%d月%d日,台幣兌美元匯率為%f\n",year, mounth, day, exchange); ``` *more info: https://en.cppreference.com/w/cpp/io/c/fprintf* --- ## 變數—基本內建型態primitive built-in type 看完上面的解說,我們應該已經成功在電腦上輸出資料,但有兩個問題:我們要如何輸入東西到電腦?還有上面一直提到的「變數」是什麼呢?? >變數在電腦中的定義就和他字面上的意義相同,為一可變的數,若結合計算機硬體的概念來看,即是將待用資料存入於記憶體的其一位址中,待需要使用時再將其呼叫此位址然後將值載入暫存器中,但因為位址很難記,打程式時Coders會利用一個標示符來代替他,以提高效率及程式碼的理解性。 我們已知,電腦的資源是有限的,故我們要依資料的不同類去分配不同型態的變數來儲存,例如人數一定是**整數**,重量可能帶有小數位,因此用**浮點數**較為適合 C和C++一樣皆有下列這些變數型態(型態最大的不同在於在記憶體內的空間): >可以把變數當成是一個一個不同大小的盒子,可以裝入不同大小的東西,但東西的大小一定要比盒子小,雖然可以硬塞,但會讓裡面的東西壞掉(overflow溢位) > >宣告的概念即是向作業系統索取盒子的過程,必須明確告知作業系統這個盒子的大小,是整數、浮點數、或字元值 > >接著,在作業系統給予我們這個盒子時,作業系統也會在這個盒子上坐上一個標籤,稱為記憶體位址,是一個獨一無二的id,然而因為現在的記憶體都是動輒好幾GB的,他的位址也是0x123...不易讓人記憶,因此,高階語言也允許我們自訂這個盒子的名稱,使我們方便編程(記憶體位置仍然不變,只是多了一個“給人看”的標籤而已) ### 基本資料型態(盒子的大小) | 資料型態 | 型態說明 | 位元數 |數值有效範圍| | :------: | :------: | :------: |---| | 整數類型 | |long long|長長整數|8|-9,223,372,036,854,775,808 至 9,223,372,036,854,775,807| | long int | 長整數 | 4 |-2147483648~2147483647| | int | 整數 | 4 |-2147483648~2147483647| | short int | 短整數 | 2 |-32768~32767| |unsigned long long|無號長長整數|8|0 到 18,446,744,073,709,551,615| |unsigned long int|無號長整數|4|0~4292967295| |unsigned int|無號整數|4|0~4292967295| |unsigned short int|無號短整數|2|0~65535| | 浮點數類型 | | || | float | (單精度)浮點數 | 4 |1.2e^-38^~3.4e^38^| | double | (雙精度)浮點數 | 8 |2.2e^-308^~1.8e^308^| |字元類型||| | char | 字元 | 1 |ASCII CODE| |(C++11)char16_t|UTF-16|16|unicode 編碼| |(C++11)char32_t|UTF-32|32|unicode 編碼| |布林類型||| |bool|布林值|1|true, false| :::spoiler C++11 標準新增char16_t, char32_t來表示UTF-16, UTF-32字元, 亦新增long long的整數型態 ::: ### 變數宣告 ```cpp= //只宣告型別,代賦值 type name1,[name2,name3,...]; int a,b,c; //型別、值同時宣告 type name=number; int a=1,b=2; //亦可混合,部分賦值、部份不賦值 int a,b=33,c; ``` ### 細說型別與變數 #### 宣告??變數??常數?? ***變數***,即為一可變的數,恰與亙久不變的***常數***相反,然而不管變數變了多少次,其在記憶體內的佔用空間不會改變(,故資料精度大於記憶體分配空間則會造成資料數值錯誤的**溢位overflow**現象);**宣告**的概念,會指定實體的唯一名稱,以及其型別和其他特性的相關資訊。 #### 字面常數literal 即程式中直接寫出來的數值value #### bool 宣告(declare)布林型態的變數使用關鍵字(keyword) **bool**,其字面值有true和false,分別代表1,0,邏輯上的真與假 #### int, long int, short int 一般而言,最常用的是int型態,***沒有特別指定的整數字面常數皆會被視為int型態,欲使用long型態,則需在字面常數的尾巴加上l或L*** ```cpp= int a=1; long b=1234l; ``` #### float &double 最常使用的是double,***沒有特別指定的浮點數字面常數會被視為double,欲使用float型態,需在字面常數尾加上f或F*** ```cpp= double a=2458.3721; float p=22.0f; ``` #### char 宣告字元型態的變數使用關鍵字**char**,字元型態的字面常數為*單引號圍起來的單一字元*,或是單引號圍起來反斜線加上四位的十六位元數字 ```cpp= char e='a'; char f='2'; char i='\n'; char k='\a'; ``` char變數的字面常數是「文字」 沒錯,但事實上它是依據ASCII表將文字轉為數字來進行儲存的,每個字母有其專屬的數字代碼,大小有不同,故其亦有有效範圍且一樣是由數字決定 可參閱[ASCII表](https://zh.wikipedia.org/wiki/ASCII)\ 在上面程式碼區塊的3,4行可以看到由反斜線\加上一個英文字母的組合文字,其稱作**跳脫字元**,即一些不可見字元(換行、對其、雙引號(因已被定義)) | 跳脫序列 |代表意義 | ASCII CODE(dex) | | :------: | :------: | -------- | | \a | 警告音 | 7 | |\b|倒退一格|8| |\n|換行|10| |\r|歸位|13| |\t|跳格|9| |\0|字串結束字元|0| |\\\\|反斜線|92| |\\'|單引號|39| |\\"|雙引號|34| 變數若不是基本內建型態則代表他是個物件,看得懂的話可以先看[指標與參考](https://hackmd.io/4uvLo6aeTEGL1KEiA2oXFw#指標與參考) #### 變數命名原則(識別字命名原則) * 變數命名原則 1. 變數的命名以==簡單==、==清楚==為原則,常見小寫英文單字ex. iter, total...;或以底線連接多個單字而成ex. exam_score,count_time... 2. 數字不能是識別字的開頭,另建議不要以兩個連續的底線命名(程式庫中的很多函式都是這樣命名,會衝突) 3. 每個英文單字之間不能有空格,因空格是區分兩個程式中記號的符號 * 型態type如類別class、結構structure、列舉enumeration使用的識別字以大寫駝峰式命名法, ex.SimpleGame, RunTimeExpection * 函數的命名亦已大寫駝峰式命名,第一字通常為動詞 * 簡易函式、或類別中的存取、修改函數,較常用小寫字母組合 ## 運算式expression ***C++中的每一行,都為一陳述,而每行陳述,可以運算式組成,並以==分號==作為運算式的結尾*** ### 運算式expression=運算元oprand+運算子operator * operand1; 單一運算元 * operand1 operator operand2; 運算元+運算子 * operand1? operand2 : operand3; 具條件判斷功能之運算式 #### 算術運算子 arithmetic operator |優先順序| 運算子 | 功能 | 用法 | |---| -------- | -------- | -------- | |1| + | 單元的加法 | + expr | |1|-|單元的減法|- expr| |2|\*|乘法|expr * expr| |2|\/|除法|expr / expr| |2|%|取餘數|expr % expr| |3|+|加法|expr + expr| |3|-|減法|expr - expr| :star:全數皆為左結合(由左邊看到右邊) 包括加減乘除取餘數,分別符號為+\-\*\/%,使用概念和數學的概念一模模一樣樣,唯有一個要注意的就是除法時要注意捨去的問題: ```cpp= int a=1,b=3; cout<<a/b;//輸出值應該要是0.333 ``` 實際結果:![](https://i.imgur.com/W5ab7ja.png),然而浮點數除法就不會有此問題,因此要將原函式改為: ```cpp= float a=1,b=3; cout<<a/b;//輸出值應該要是0.333 //或 int a=1,b=3 cout<<(float)a/b; ``` 第二種寫法稱為型別的強制轉換,原本a是整數,但在進行運算時加上了(float)的前綴使其暫時轉為浮點數進行運算,故其小數值不會被捨掉。 大家可以試試看此段程式碼,看結果有何不同: ```cpp= int a=1,b=3; cout<<float(a/b); ``` 結果 :arrow_down_small: :::spoiler 答案應該也是0對吧 原因是因為在電腦中的運算,和數學中的運算一樣也有先後順序 在這邊的步驟是:先算出1/3,但因為是整數除法得值為0,再將0轉為浮點數,得值依舊為0 ::: #### 遞增、遞減運算子 increment /decrement operator | 種類 | 使用法 | 例子| | :------: | -------- | -------- | | 遞增運算子++(先遞增再運算) | ++[變數] | 如++a | | 遞增運算子++(先運算再遞增) | [變數]++ | 如a++ | | 遞減運算子--(先遞減再運算) | --[變數] | 如--a | | 遞減運算子--(先運算再遞減) | [變數]-- | 如a-- | > 判斷是「先運算再進行遞增減」還是「先遞增減再運算」的方法,是看他們在變數的哪個位置上,在前面就是先遞增減,在後面就是後遞增減 > [name=yen0224] > [color=#ed4b5c] 遞增減運算子的優先順序高於算數運算子,可以思考一下下列程式碼輸出的值為多少: ```cpp= b = 10 ; cout << 10 * (++b) ; ``` :::spoiler 110,到cout那行時,b會先+1,再進行運算。 ::: 再思考一下如果對字元變數進行遞增會輸出什麼呢: :::spoiler 若對字元變數進行遞增並且輸出,可以輸出全部的字母 ::: #### 邏輯、關係運算子 logical &relational operator |優先性|結合性| 運算子 | 功能 | 用法| |:--:|:--:|:-------: | :------: |:--:| |1|R|!|邏輯NOT|!expr| |2|L| > | 大於 |expr > expr| |2|L| < | 小於 |expr < expr| |2|L| >= |大於等於| expr >= expr| |2|L| <= |小於等於|expr <= expr| |3|L| == | 相等 | expr == expr| |3|L| != | 不等 | expr != expr| |4|L|&&|邏輯AND|expr && expr| |5|L|\|\||邏輯OR|expr \|\| expr| ##### 邏輯AND與OR運算子 即為數學「且」與「或」的概念,只有在兩個運算元皆為true時,AND運算的結果才會是true,若是or的話,任一運算元為true時即為true。\ AND與OR永遠會進行==短路運算==(short-circuit evaluation),即右運算元只在左運算元無法決定結果時才會進行運算: * 一個&&的右邊只在右邊為true才運算(AND兩邊都要是true,若前面是false,那右邊就可不計算) * 一個||的右邊只有在左邊為false時才計算(OR任一為true即可,前面為false,則要知後面是true還false才有結果) ##### 邏輯NOT運算子 邏輯運算子NOT回傳其運算真假值的相反,即expr的結果為true,!expr的結果為false ##### 關係運算子 關係運算子的概念很簡單、和數學中的概念是相同的,唯二要注意的是==相等==是======,=====為指派運算子,另外若要有連續判斷大小,如*i<j<k*的情況,需借助邏輯運算子來寫判斷式,否則結果會出錯。 ```cpp= if( i<j && j<k ) ``` 原因:若k大於1,因關係運算子為*左結合*的,k會跟i<j的結果進行判斷,即使k並無大於J,其與布林值的比較會是恆成立的(true=1, false=0) #### 指派與複合指派運算子 指派運算子是*右結合*的,其左運算元需為一個可改變的lvalue; 複合指派,即是把“一個運算子套用在一個物件上,然後結果指派在相同的物件”這個動作合一\ 以下為用法: |運算子|原本|複合指派| |:---:|:---:|:---:| |+=|a=a+1|a+=1| |-=|b=b-a|b-=a| |\*=|c=c\*a|c\*=a| |/=|d=d/1000|d/=1000| |%=|e=e%3|e%=3| #### 條件運算子(?:運算子) ```cpp= cond ? exp1 : exp2 ; ``` *cond*是用來表示條件的運算式,而exp1和exp2為相同型別的運算,其執行方式為:當cond為true時,exp1會被執行,若否,exp2執行 ```cpp= int score = 60 ; cout << ((score > 60 ? ) pass : fail); //result :fail ``` #### 位元運算子 |優先序|運算子|功能|用法| |:---:|:---:|:-:|:-:| |1|~|位元NOT|~expr| |2|<<|左移位|expr1 << expr2| |2|>>|右移位|expr1 >> expr2| |3|&|位元AND|expr1 & expr2| |4|^|位元XOR|expr1 ^ expr2| |5|\||位元OR|expr1 \| expr2| ==建議將位元運算子*只用於*unsigned型別,才不會使正負號錯誤== ##### 位元NOT,AND,XOR,OR NOT運算:將每個bit反轉\ AND,XOR,OR:將expr1與expr2進行邏輯運算 #### sizeof運算子 回傳型別所佔大小 ```cpp= int a; sizeof a; ``` #### 總表 ![](https://i.imgur.com/q6onP91.png) ![](https://i.imgur.com/utjl8PK.png) ## 述句statement 程式的結構主要三種,其共同的特徵是,只有一個進入點,也只有一個出口 1. 循序性結構:採top-to-down的敘述方式,當一個敘述執行完畢之後,接著在執行下一行敘述 2. 選擇性結構:此結構會依據條件的成立與否,再決定要執行哪些敘述 3. 重複性結構:此結構會根據判斷條件的成立與否,決定程式段落的執行次數 ### 選擇性結構—if述句 (if statement) 最簡單的條件判斷式:一個if加上一個運算式,若運算式的結果為***非零***,則進行if括號內的述句,若為零,則進行else的內容,若無else則不進行任何動作; 在多個條件運算式中,則以else if關鍵字進行第二條件的判斷,else if可有可無,務必注意的是,連續多個條件的判斷,應將最小範圍的條件排在最前,否則可能會有淺在的bug產生。 巢狀if:if中又有if ```cpp= if(/*condiotion1*/){ statement1; } else if(/*condition2*/){ statement2; } ~ ~ else if(/*conditionN*/){ statementN; } else{ statementN_1; } ``` for example #1 閏年的判斷:\ 已知判斷閏年的條件有: * 非百年則能除4則閏 * 逢百年需亦能用400才潤 ```cpp #include <iostream> using namespace std; int main(){ int year; cin >> year; if ((year % 4) == 0){ if ((year % 100) == 0){ if ((year % 400) == 0){ cout << year << "年是閏年(400倍數)" << endl ; } else{ cout << year << "年非閏年(100年)" << endl ; } } else{ cout << year << "年是閏年(非100倍數4倍數)" << endl ; } } else{ cout << year << "年非閏年(非4倍數)" << endl ; } return 0; } ``` 可觀察一下4, 100, 400出現位置、及改變他們的位置可能會有什麼影響;若硬要改變位置,相對應的寫法要怎麼寫呢?為何要用巢狀,不用多個if和邏輯運算式呢?? :::spoiler Q1:4,100,400出現位置: * 從數學來看4是100,400的因數,100又是400的因數,(假設相同寫法),4為公因數,故可當作最大層的過濾,若第一層以400做過濾,對於小於400的數取餘數會造成全部都被濾掉的問題,100同理 * 接著是以閏年條件來看,逢四閏,逢一百不閏,遇四百又閏,故100倍數為例外狀況,400和100公因數為100,(非4之倍數、為4倍數但非百倍數已排除),可先做100倍數之過濾,再對400倍數做處理即可 * 條件過濾的方法(尤其適用於多個條件時): * 先找出共同條件(由亂七八糟的不同點中找到相同的) * 針對共同條件找出異處(從相同的在找出不同) * 針對異處做處理 * 如車子:相同點有大小、位子數、顏色,不同點在於通過的安規、品牌、燃油or燃氣or電力,想找出想要的車可以這樣找: 1. 先從大小、位子數挑 2. 安規、(我是環保左膠)電力驅動 4. 顏色&品牌 Q2:通靈能力已全部耗盡,我猜不到你想啥,略\ Q3:使用多個if和邏輯條件組合呢? * 用多個if+邏輯判斷式,可行,問題是出現在邏輯判斷的部分,C(2,3)=6,需進行12次的邏輯比對(比大小&邏輯,6\*2=12),相較巢狀if只需進行3次比大小運算,巢狀效率(不符合的直接丟到else或不處置略過,只接少一層比對)較優,更別提即有更多的條件要判斷的情形了 ::: ### if-else變形:switch statement ```cpp= switch(variables){ case const1: states; break; case const2: states; break; default: states; } ``` ### 重複性結構 ### while述句 (while statement) ```cpp= while(/*condition*/){ statement; } ``` ```cpp= do{ statement; }while(/*condition*/) ``` ### for 述句 (for statement) ```cpp= for ( init-statement ; condition ; iteration_expression ){ statements; } ``` for迴圈由三部分組成: 1. 第一是在執行迴圈之前,所需要先給定的初始值設定。 2. 第二是進入或留在迴圈的條件,有如while指令後面接著的判斷式。 3. 第三是在每當要執行下一次迴圈之前,所需要執行的式子。 由上面三個部分,可以得知for loop 等效於: ```cpp= { init_statement while ( condition ) { statement; iteration_expression ; } } ``` > 對於for語法還不熟悉的可以先嘗試用while去寫,尤其是做有計數器的題目可以更快掌握for的用法[name=yen020224] ### 迴圈跳離 #### ==break== break敘述可以讓程式強迫跳離回圈,當程式執行到break敘述時,即會離開回圈,繼續執行回圈之外的下一行敘述(若違巢狀迴圈,則跳至此回圈外之下行敘述) ```cpp= for(;;;){ staA; staB; staC; ... break; staN; } statements;//break之後會執行這行 ``` #### ==continue== continue敘述, #### ==goto== ## 陣列 > 陣列array是由一群相同型態的變數所組成的變數型態,他們以一個共同的名稱表示,陣列中的個別元素(element)則以註標(index)來標示其存放的位置;一陣列的複雜程度可分為一維、多維陣列 ### 一維陣列 ![](https://i.imgur.com/5BVGjNq.png) **宣告法1:純宣告** ```cpp= type name[amount]; //[資料型態] 陣列名稱[元素數量]; //e.g. int score[6]; //宣告一個陣列名為score,內有6個元素 float temp[7]; //宣告一個陣列名為temp,內有7個元素 char name[12]; //宣告一個陣列名為name,內有12個元素 ``` **宣告法2:陣列初值設定** ```cpp= //[資料型態] 陣列名稱[n]={初值0,1,2,.....,n-1}; //注意 //注意 //注意 //註標只有到n-1,因為是從0開始的 type name[n]={0,1,2,3,...,n-1} //e.g int monthDay[12]={31,28,31,30,31,30,31,31,30,31,30,31}; //也可這樣寫 int day[]={31,28,31,30,31,30,31,31,30,31,30,31}; ``` 編譯器錯誤訊息\ 若所宣告大小與實際情形不符:\ 宣告數>輸入數:其餘以==0==補齊\ 宣告數<輸入數:出現錯誤訊息**"太多初始設定式值"**\ (以macos為例:) ![](https://i.imgur.com/kkbMD6g.png) 若是要讓使用者輸入值可以怎麼寫?\ ANS:用==for迴圈== ```cpp= #include <iostream> using std::cin; using std::cout; using std::endl; int main(void){ int amount; cout << "要輸入幾個數?" << endl ; int inputNum[amount]; for(int i=0;i<amount;i++){ // ^注意初值,以及條件 cout << "請輸入第" << i+1 <<"個數:"; cin >> inputNum[i]; // ^ } return 0; } ``` ~~## 函數~~ ## 指標與參考 > 指標pointer儲存變數的記憶體位址address,參考reference為變數的別名alias。 宣告指標變數使用\*運算子,範例如下 ```cpp= #include <iostream> using namespace std; int main(void){ //設值n 為整數11 int n = 11; cout << n << endl; //設置np為指向n的指標,&為取址運算子 int *np = &n; cout << np << endl; //設定t取得從np位址指向的值,*為反參考運算子 int t = *np; cout<< t << endl; return 0; } ``` 設置完n的值為11後, ```cpp= int *np = &n ; cout<< np << endl; ``` 用np取得n的記憶體位址,\*np中的\*用來宣告指標,&運算子可取得變數之位址。這段程式碼的完整解釋為:\*宣告np變數為指標形式後,由取址運算子&取得n之位址,儲存於np中。 前面的int 為**指標指向的變數位址所對應的變數的型態**,在這邊,即是指n的型態,所以是int,若n為float,則程式為: ```cpp= float n = 11.0f; float *np = &n; ``` ```cpp= int t = *np; cout << t << endl; ``` 同樣是*,但這次出現在等號的右邊,則變成了**反參考運算子**,由t取得np所儲存記憶體位址變數的值;這裡的np儲存的為n的記憶體位址,所以t藉由\*np反參考取得n之值,(#2行)輸出11 * 指標 \*p:可儲存物件的記憶體位址 * 取址運算子&n:取得變數、物件的記憶體位址 * 反參考運算子=\*p:由指標取得指向物件之值 > 好麻煩,指標的概念好複雜,一樣是移動變數,為何要分那麼多步驟還有位址移來移去,直接複製變數不就好啦?? 答案是:效率的考量 當今天有100個變數要複製等處理,每個變數所佔空間是好幾個Byte,所以移動100個就是等於要對好幾百個Byte作處理,相較之下,一個記憶體位址只有一個位址的空間,相較之下,效率不就更好了? 若是對於更複雜的資料結構,指標的優點就更顯而易見了。 ### new關鍵字 ## Error Code & Bug排解 bug有兩種,其中一個幾乎可以依靠編譯器的錯誤碼去判斷,另一種則需去檢視程式碼去找出錯誤 ### 語法錯誤Syntax Error:指程式的敘述不符合編譯器.直譯器或組譯器正確的文法規則如 * 敘述句尾未加分號:Expected ';' after expression * 未宣告型別:Use of undeclared identifier * 分號出現在錯誤的地方,如出現在條件運算式內:Expected expression * 符號、括號未對稱: Expected '}' * 使用關鍵字當作識別字使用:Expected unqualified-id * 字串、字元少引號 * 參數未加分格 * 打成全形字元 * 大小寫誤用(JAVA) * 改到常數:Cannot assign to variable 'PI' with const-qualified type 'const float' ### 邏輯錯誤、演算法錯誤:為bug中最常發生的錯誤,且有時候會找很多次還找不到,甚至bug會生更多bug(苦笑...),最後可能要整格程式碼重寫,並且算每個不同參數直到找到出錯點在哪,這就是最可怕的debugging過程 ->建議解法:小鴨除錯法(Rubber Duck Debugging),找一個人或物,向他一行一行解釋程式碼的功用與執行過程,藉此找到矛盾及激發靈感(但因為電腦工程師很多都是邊緣人所以只能跟小鴨講 (;´༎ຶД༎ຶ`\)) ![](https://i.imgur.com/Qn4fx36.png) ## Reference 參考資料 * <C++ Primer 11st ED.> * <旗標出版 C++教學手冊 洪偉恩著> * [C++ 入門手冊]() * [Microsoft® developers DOCS](https://docs.microsoft.com/zh-tw/cpp/?view=msvc-160) * http://billor.chsh.chc.edu.tw/IT/Supply/01.pdf

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully