C 語言 | 程式碼基本要素 | if else / if 差別

更新於 2024/10/27閱讀時間約 11 分鐘

為什麼從 C 開始 ? 為什麼不是 Python?

因為 C 是個「麻煩」的程式語言,而 Python 其實已經簡化很多步驟。先學 C 語言了解程式語言的架構,再學其他語言就會覺得更簡單。在學習 C 語言的過程中可以了解電腦科學較接近底層的基本運作,不只有侷限在單純寫出漂亮的程式碼。

首先,我們從印出 hello,world 認識標頭檔。


怎麼寫出 Hello World?

怎麼運行 Hello World? 記得要編譯阿!

  • 初學者可以用 CS50.dev 內建的雲端版,寫自己第一個程式。每一行程式都可以解釋,請見下圖程式碼:
#include <stdio.h>  //第一步:加入標頭檔,讓程式能使用「標準輸入輸出」的功能。

int main(void)  // 主程式的起點
{
    printf("hello, world"); // 最後加上;表示結束
}
  1. // 是程式的註解,在此之後的資訊都不會被運行。
  2. 這個標頭檔叫做 <stdio.h>,是 C 語言裡負責處理輸入和輸出的函式庫。函式庫的概念是前人寫好的功能包,只要導入標頭檔,即可使用該函式庫的所有功能。注意,stdio 是 "standard input/output" 的縮寫,不是 "studio"。
  3. 主程式的起點。int 表示這個主程式會回傳一個整數結果,main 是程式的主要函式。(void)表示這個程式不需要從使用者接收任何資料。C 語言中,需要定義每個函數的型態。雖然結果是印出「hello,word」,但實際上程式的最後一段會有return 0 表示程式執行成功,並結束主程式,所以這個函式仍是int 類別。
  4. printf 是用來輸出文字到螢幕上的函式。這裡會顯示 "hello, world"。每個命令結尾要用分號 (;) 表示這一行程式碼結束。

寫完之後還不能直接跑,必須先用 make 檔名編譯轉成電腦,再輸入 ./ 才會跑出程式的結果。

make hello 才是對的,多打了 hello.c 就跑不出來。

make hello 才是對的,多打了 hello.c 就跑不出來。

跑出另外一個檔是由 0 和 1 組成,電腦才看得懂得檔案~ 點開沒有 .c 的檔案會被告知檔案是二進位檔案。

跑出另外一個檔是由 0 和 1 組成,電腦才看得懂得檔案~ 點開沒有 .c 的檔案會被告知檔案是二進位檔案。




編譯之後,再 ./ 檔名,就會跑出「hello, world」,

編譯之後,再 ./ 檔名,就會跑出「hello, world」,

最後的成果

最後的成果

咦?奇怪怎麼出現 $

解法是要「換行」, 輸入 \n (注意 \ 跟 / 的差別)。完整的寫法會是:

printf("hello, world\n")

\n 是屬於 Escape Sequence 跳脫序列的其中,除了 \n 還有

  1. \t:水平跳位 (tab)
    • 插入一個水平跳位,相當於按下 Tab 鍵。
    • 範例:printf("Hello\tWorld"); 會輸出:Hello World
  2. \\:反斜線 (backslash)
    • 用來輸出一個反斜線字符。
    • 範例:printf("C:\\Program Files"); 會輸出:C:\Program Files
  3. \":雙引號 (double quote)
    • 用來在字串中輸出雙引號。
    • 範例:printf("\"Hello, World\""); 會輸出:"Hello, World"

這些跳脫序列讓你可以在字串中包含特殊的格式或字符。

C 語言的資料型別:int, float, char...

電腦新手村的第一篇提到,電腦的 0 和 1 都需要有空間儲存。能處理的數值範圍越廣,占用的空間也越大。

int (整數型別):

  • 一般來說,int 是 4 個位元組(32 位元),因此範圍是:
    • 有號整數: -2,147,483,648 到 2,147,483,647
    • 無號整數 (unsigned int): 0 到 4,294,967,295 (把負數的數值移到正數,想像範圍是一把尺,起始點不同但是區間內包含的數量相同)

float (浮點數型別):

  • 通常是 4 個位元組(32 位元),可以表示的範圍約為:
    • 正或負的範圍:約 ±3.4 × 1038 到 ±1.2 × 10-38
    • 小數點精度: 通常能提供 6 到 7 位有效數
  • 需要更廣的範圍要用到 double

int 的 Truncation (截斷) 問題:

1 除以 3 應該得到 0.3333333 但是最後只有 0。因為電腦只保留整數部分,把小數點後面的數字直接捨去。更多的基本資料型別請按這裡

raw-image

float 浮點數不精確:

float 不等於小數的原因是,超過記憶體負荷,後面的小數就會出現亂碼,並不符合數學定義的小數條件。

假設我要算 1/3 到小數第20位:

#include <stdio.h>
#include <cs50.h>
int main(){
int x = get_int("x: ");
int y = get_int("y: ");
float z = (float) x/ (float) y; //整數計算不會出現浮點數 (會出現0.000),所以要先轉成浮點數
printf("%.20f\n",z); // 取到20
}
應該要是 0.3333 但是已經超出 float 所用的空間,後面就出現亂數。

應該要是 0.3333 但是已經超出 float 所用的空間,後面就出現亂數。

解決方式:改成 double的資料型別。

儲存空間不足造成的問題:Integer overflow(整數溢位)

如果我不改變資料型別,會造成 Integer overflow(整數溢位)的問題。

前面提到,int 範圍是 -2,147,483,648 到 2,147,483,647。如果你嘗試加一個大於這個範圍的數字,結果就會發生「溢位」。代表數值爆掉,會從頭開始。例如:

  • 最大整數 2,147,483,647 + 1 會變成 -2,147,483,648,而不是你預期的 2,147,483,648


C 語言沒有字串 String !!!如何讓使用者輸入字串?

如果是在 CS50 的環境,先導入<cs50.h> 的函式庫才可以繼續使用 string 這個字串;至於一般在電腦本機運行的C語言則是要用「字元陣列」的方式表達。( 之後再細講這個部分。

#include <stdio.h>  
#include <cs50.h>

int main(){
    string name = get_string("請問你叫什麼名字?\n"); //()括弧裡面是提示
    int age = get_int("請問你幾歲?\n"); // 程式從右邊讀到左邊,即將使用者輸入的值,「賦值給age這個變數」
    printf("Hi %s, 你 %d 歲\n", name, age);
//因為使用者輸入名字和歲數都不固定所以要用%s表示變數,而%s代表的數值又是從剛剛問的name得到,同理用%d表示整數,整數來自剛剛使用者輸入的age
}

賦值

  • =:這是賦值的符號。它的作用是把右邊的值賦給左邊的變數。可以把它想像成把右邊的內容放到左邊的容器中。舉個例子:
    • 如果你寫 count = 1,這表示把數字 1 放到變數 count 中。
    • 如果後來你寫 count = count + 1,這表示把 count 現在的值加 1,然後把這個新值再放回 count 中。
  • count++:這是一種簡化的寫法,等同於 count = count + 1。它的作用是把 count 的值增加 1。使用 count++ 可以更簡潔地完成這個操作。

小結:

  • = 是用來賦值的,把右邊的內容給左邊的變數。
  • count = count + 1count++ 都是用來讓變數 count 的值增加 1
  • %d%s 是格式化輸出(format specifiers)用來顯示變數的不同類型

變數表示 %d%i%s

printf("Hi %s, 你 %d 歲\n", name, age);

舉例來說,%d 是指輸出的變數型態為整數,而輸出的值要對應到 age 。如果直接輸入 age 而不是變數,最後的結果會變成 「你 age 歲」,而不是「你 25 歲」。

進階練習

看起來都可以得到正確答案,但假如使用者亂回答,我們怎麼避免呢?我們來做進階的練習~

如果使用者回答 200 歲或是 -10,可以在前面多設一個關卡。這裡會用到「 C 語言中的邏輯運算子」

AND: &&

OR: ||

NOT: !

#include <stdio.h>
#include <cs50.h>
#include <string.h>

int main()
{
string name = get_string("請問你叫什麼名字?\n"); // ()括弧裡面是提示
int age = get_int("請問你幾歲?\n"); // 程式從右邊讀到左邊,即將使用者輸入的值,「賦值給age這個變數」

while (age > 100 || age < 0) {
age = get_int("請重新輸入年齡\n");
}

if (age >= 65) {
printf("Hi %s, 你 %d 歲是老年\n", name, age);
} else if (age >= 18 && age <= 65) {
printf("Hi %s, 你 %d 歲是成年\n", name, age);
} else {
printf("Hi %s, 你 %d 歲是未成年\n", name, age);
}
}

while 在這裡的用意是確認使用者輸入到正確的年齡才可以進行判斷,若單純用 if 只會問一次「請重新輸入年齡」。

C 語言| 迴圈寫法| 函數作用域

三個 if 跟 if/else if/else 差在哪裡?

連續三個 if 是 前一個判斷的結果都沒有功能

raw-image


相關補充

「布林值」就是 truefalse 兩個答案,true 代表 1 ,false 代表 0 ,所以寫 if 60 <= a <= 100 居然是錯的邏輯,因為程式從左邊讀到右邊,首先讀 60 <=a ,不管答案是true (1) 或是false (0)。再往右邊讀,0 或 1都小於等於 100,所以答案會永遠都是 true。參考筆記


終端機使用技巧與寫程式小工具分享

clear 清除前面終端的指令

raw-image

參考資源:






    留言0
    查看全部
    avatar-img
    發表第一個留言支持創作者!
    在我們深入探討程式設計之前,讓我們先掌握 Linux 作業系統的基礎,學習如何在命令提示字元(CMD)中靈活運用指令,並了解位元與位元組之間的差異。這樣的學習路徑雖然乏味但有助於打下穩固的基礎,一起在電腦新手村獲得經驗值吧!
    在我們深入探討程式設計之前,讓我們先掌握 Linux 作業系統的基礎,學習如何在命令提示字元(CMD)中靈活運用指令,並了解位元與位元組之間的差異。這樣的學習路徑雖然乏味但有助於打下穩固的基礎,一起在電腦新手村獲得經驗值吧!
    你可能也想看
    Google News 追蹤
    Thumbnail
    *合作聲明與警語: 本文係由國泰世華銀行邀稿。 證券服務係由國泰世華銀行辦理共同行銷證券經紀開戶業務,定期定額(股)服務由國泰綜合證券提供。   剛出社會的時候,很常在各種 Podcast 或 YouTube 甚至是在朋友間聊天,都會聽到各種市場動態、理財話題,像是:聯準會降息或是近期哪些科
    Thumbnail
    C#是一種開源、跨平台、面向對象的編程語言,具有類型安全、泛型、模式匹配等特性。廣泛應用於桌面和Web應用程序、遊戲開發、移動應用、雲計算等領域。全球數十萬家公司像微軟、Unity Technologies、Stack Overflow等使用C#支持其業務。C#還提供豐富的進階學習資源和主題。
    Thumbnail
    想要進入工程師的世界,首先要先學會架設自己的Build code環境,有了編譯環境,接下來就可以安心的撰寫你想要的C語言程式啦! 如果你不知道該從何下手,那不妨先照著本篇文章的步驟做,Violet一步一步教你並解釋每個步驟的意義,很快你就會得到一個能編譯C語言程式碼的虛擬基環境哦!
    Thumbnail
    在開發應用程式時,經常會遇到需要調整圖片大小以節省空間或加快加載速度的情況。本教學將介紹如何使用 C# 語言來壓縮圖片並調整其大小,以便在應用程式中使用。
    Thumbnail
    這篇文章將會從基本概述到射線偵測應用的詳細步驟,講述運用射線改變特定圖層中,射線命中的物件顏色。
    Thumbnail
    分類 △單精度浮點數、單精度浮點值(float) △雙精度浮點數、雙精度浮點值(double) △長雙精度浮點數、長雙精度浮點值(long double) 有效位數是什麼? 儲存形式 不精確的原因 範圍與有效位數的差別 浮點數不被建議使用的原因 精確問題 速度問題 結論
    Thumbnail
    說明 重點 △定義變數 △文字的定義 △文字與數字的差別 △整數與浮點數 △signed(有號)與unsigned(無號)的區別 △e是什麼符號? 分類 △字元 △字串 △短整數 △整數 △長整數 △超長整數 △單精度浮點數 △雙精度浮點數 △長雙精度浮點數 應用 宣告與輸出 運算符 結論
    Thumbnail
    前言 輸出 printf 格式控制字元、格式控制符(format char) 前言 輸出控制字元、輸出控制符 轉義字元、轉義符 格式控制字元、格式控制符 輸入 scanf gets gets與scanf差異
    Thumbnail
    auto(自動)、register(暫存器)、static(靜態)、extern(外部),以作用範圍(scope)、存儲時期(life time)、連結(linkage)的不同作為區別。
    Thumbnail
      雖然Dart 語言本身支援跨平台的編譯方式,但在實務開發時還是不免需要使用外部非Dart語言所提供的函式庫進行功能開發且由於C 語言是最為廣泛且通用的程式語言,因此Dart語言也有提供支援與C語言函式庫互通性的方式;本篇主要是以MSVC作為C的編譯器來實作說明如何引用C語言會遇到的作法。
    第n項的費式數列為何? #include int main() { int a0=0, a1=1, a2=1, i=3, fib, n; scanf("%d", &n); if (n==0) printf("0\n"); else if (n printf("1\n"); els
    Thumbnail
    *合作聲明與警語: 本文係由國泰世華銀行邀稿。 證券服務係由國泰世華銀行辦理共同行銷證券經紀開戶業務,定期定額(股)服務由國泰綜合證券提供。   剛出社會的時候,很常在各種 Podcast 或 YouTube 甚至是在朋友間聊天,都會聽到各種市場動態、理財話題,像是:聯準會降息或是近期哪些科
    Thumbnail
    C#是一種開源、跨平台、面向對象的編程語言,具有類型安全、泛型、模式匹配等特性。廣泛應用於桌面和Web應用程序、遊戲開發、移動應用、雲計算等領域。全球數十萬家公司像微軟、Unity Technologies、Stack Overflow等使用C#支持其業務。C#還提供豐富的進階學習資源和主題。
    Thumbnail
    想要進入工程師的世界,首先要先學會架設自己的Build code環境,有了編譯環境,接下來就可以安心的撰寫你想要的C語言程式啦! 如果你不知道該從何下手,那不妨先照著本篇文章的步驟做,Violet一步一步教你並解釋每個步驟的意義,很快你就會得到一個能編譯C語言程式碼的虛擬基環境哦!
    Thumbnail
    在開發應用程式時,經常會遇到需要調整圖片大小以節省空間或加快加載速度的情況。本教學將介紹如何使用 C# 語言來壓縮圖片並調整其大小,以便在應用程式中使用。
    Thumbnail
    這篇文章將會從基本概述到射線偵測應用的詳細步驟,講述運用射線改變特定圖層中,射線命中的物件顏色。
    Thumbnail
    分類 △單精度浮點數、單精度浮點值(float) △雙精度浮點數、雙精度浮點值(double) △長雙精度浮點數、長雙精度浮點值(long double) 有效位數是什麼? 儲存形式 不精確的原因 範圍與有效位數的差別 浮點數不被建議使用的原因 精確問題 速度問題 結論
    Thumbnail
    說明 重點 △定義變數 △文字的定義 △文字與數字的差別 △整數與浮點數 △signed(有號)與unsigned(無號)的區別 △e是什麼符號? 分類 △字元 △字串 △短整數 △整數 △長整數 △超長整數 △單精度浮點數 △雙精度浮點數 △長雙精度浮點數 應用 宣告與輸出 運算符 結論
    Thumbnail
    前言 輸出 printf 格式控制字元、格式控制符(format char) 前言 輸出控制字元、輸出控制符 轉義字元、轉義符 格式控制字元、格式控制符 輸入 scanf gets gets與scanf差異
    Thumbnail
    auto(自動)、register(暫存器)、static(靜態)、extern(外部),以作用範圍(scope)、存儲時期(life time)、連結(linkage)的不同作為區別。
    Thumbnail
      雖然Dart 語言本身支援跨平台的編譯方式,但在實務開發時還是不免需要使用外部非Dart語言所提供的函式庫進行功能開發且由於C 語言是最為廣泛且通用的程式語言,因此Dart語言也有提供支援與C語言函式庫互通性的方式;本篇主要是以MSVC作為C的編譯器來實作說明如何引用C語言會遇到的作法。
    第n項的費式數列為何? #include int main() { int a0=0, a1=1, a2=1, i=3, fib, n; scanf("%d", &n); if (n==0) printf("0\n"); else if (n printf("1\n"); els