WeHelp
C 語言可以直接呼叫作業系統提供的 System Call 且速度極快,用來開發基礎系統程式非常適合。
  1. C 系統程式
  2. C 檔案寫入、讀取
  3. Process 程序管理
  4. Thread 執行緒管理
  5. IPC 程序間通訊
  6. PIPE 程序間通訊
  7. FIFO 程序間通訊
  8. 共享記憶體通訊
  9. Socket 程序間通訊
  10. TCP 網路連線
C 系統程式
## C 語言與 System Call 的關係 ### 1. 什麼是 System Call? System Call(系統呼叫)是**使用者程式向作業系統核心請求服務的介面**。 一般應用程式不能直接存取硬體或核心管理的資源,例如: - 開啟、讀取、寫入檔案 - 建立與終止程序 - 配置記憶體 - 建立網路連線 - 取得時間 - 操作裝置 - 進行程序間通訊 因此,程式必須透過 System Call 請求核心代為執行。 例如在 Unix/Linux 中,常見的系統呼叫包括: ```c open(); read(); write(); close(); fork(); execve(); wait(); mmap(); ``` --- ### 2. C 程式如何使用 System Call? C 程式通常不會直接撰寫處理器的特殊指令來進入核心,而是使用作業系統提供的函式介面。 例如: ```c #include <fcntl.h> #include <unistd.h> int main(void) { int fd; char buffer[100]; ssize_t n; fd = open("data.txt", O_RDONLY); if (fd < 0) { return 1; } n = read(fd, buffer, sizeof(buffer)); if (n > 0) { write(STDOUT_FILENO, buffer, n); } close(fd); return 0; } ``` 這段程式透過 `open()`、`read()`、`write()` 和 `close()` 操作檔案。 其流程大致如下: ```text C 程式 ↓ C 函式庫或系統呼叫包裝函式 ↓ 處理器執行特殊指令,切換到核心模式 ↓ 作業系統核心處理請求 ↓ 返回結果給使用者程式 ``` 例如,Linux 中的 `read()` 通常是 C 函式庫所提供的包裝函式。它會將參數放到指定的位置,執行系統呼叫指令,讓 CPU 從 User Mode 切換到 Kernel Mode,最後由核心讀取資料並返回結果。 --- ### 3. C 函式庫與 System Call 並不完全相同 需要區分兩者: #### System Call 是核心提供的低階介面,例如: ```c read() write() openat() mmap() ``` #### C 標準函式庫 是 C 語言或平台提供的高階函式,例如: ```c printf() fopen() fread() malloc() memcpy() ``` 有些函式會使用 System Call,有些則完全在使用者空間執行。 例如: - `printf()` 可能透過 `write()` 將資料輸出到終端機 - `fopen()` 通常會進一步使用 `open()`,並建立使用者空間的檔案串流 - `malloc()` 可能使用 `brk()` 或 `mmap()` 向核心取得記憶體,但大部分配置動作由 C 函式庫自行管理 - `memcpy()` 通常只是在使用者空間複製記憶體,不需要 System Call 所以,System Call 是作業系統核心的介面;C 函式庫則提供較方便、較高階的使用方式。 --- ## 為什麼 C 適合做系統程式開發? ### 1. 可以接近硬體與記憶體 C 提供: - 指標 - 位元運算 - 位址操作 - 結構與聯合 - 明確的資料大小控制 - 記憶體配置與釋放 例如可以透過指標存取記憶體位置: ```c int value = 10; int *ptr = &value; *ptr = 20; ``` 系統程式經常需要處理: - 記憶體位址 - 暫存器 - 記憶體映射裝置 - 核心資料結構 - 封包與檔案格式的二進位資料 C 能在高階程式設計與低階硬體操作之間取得平衡。 --- ### 2. 效能高、執行成本低 C 通常會被編譯成接近機器碼的原生程式,因此: - 執行速度快 - 記憶體使用量較低 - 沒有大型執行時期環境的必要依賴 - 可精確控制資料結構與執行流程 作業系統核心、驅動程式、嵌入式系統和編譯器通常都非常重視效能與資源使用量,因此 C 很適合這些用途。 --- ### 3. 可以精確控制記憶體 C 不會自動替程式管理所有資源,程式設計者可以控制: ```c char *buffer = malloc(1024); if (buffer != NULL) { /* 使用 buffer */ free(buffer); } ``` 這種控制對系統程式很重要,因為系統軟體必須管理: - 堆積記憶體 - 堆疊記憶體 - 記憶體映射 - 緩衝區 - 快取 - 記憶體對齊 但這也代表 C 程式設計者必須小心處理記憶體洩漏、懸空指標和緩衝區溢位等問題。 --- ### 4. 與作業系統介面緊密結合 許多作業系統的 API 本身就是以 C 形式提供,例如 POSIX API: ```c pid_t pid = fork(); if (pid == 0) { execl("/bin/ls", "ls", NULL); } ``` Linux、Unix、Windows 等系統也都提供大量 C 風格的 API。C 的函式、指標、結構和整數型別很容易對應到作業系統定義的資料結構與呼叫慣例。 --- ### 5. 可移植性相對良好 C 程式通常需要由不同平台的編譯器重新編譯,但只要使用標準 C 或可攜式的系統介面,同一份程式可以移植到不同平台。 例如: ```c #include <stdio.h> int main(void) { printf("Hello, world!\n"); return 0; } ``` 這段程式幾乎可以在不同作業系統上編譯執行。 不過,若使用 Linux 特有的 System Call 或 POSIX API,例如 `fork()`、`epoll()`,可移植性就會受限。因此系統程式通常需要區分: - 標準 C 介面 - POSIX 介面 - 特定作業系統介面 - 特定硬體介面 --- ### 6. 歷史與生態系統完整 Unix 作業系統本身大量使用 C 實作,許多核心、工具程式和系統函式庫都以 C 為基礎。因此 C 與 Unix/Linux 的系統程式設計有深厚的歷史關係。 常見的系統軟體包括: - Linux 核心 - Unix 工具 - Shell - 編譯器 - 資料庫 - 網路伺服器 - 裝置驅動程式 - 嵌入式韌體 這些領域都有成熟的 C 編譯器、除錯器、函式庫和工具鏈支援。 --- ## C 與其他語言的比較 C 的優勢是: - 低階控制能力強 - 效能高 - 執行環境簡單 - 可直接與硬體及作業系統介面互動 - 適合實作核心、驅動程式和嵌入式系統 但 C 也有缺點: - 缺乏內建的記憶體安全機制 - 指標錯誤可能導致程式崩潰 - 容易發生緩衝區溢位 - 記憶體需要手動管理 - 並行程式設計較容易出錯 因此,現代系統程式也可能使用 C++、Rust、Go 或其他語言;不過 C 仍是許多作業系統核心與低階軟體的重要基礎。 ## 總結 C 語言本身不是 System Call,但它提供了非常適合呼叫 System Call 的程式設計能力。C 函式庫通常會將 System Call 包裝成較容易使用的函式,而程式則透過這些函式與作業系統核心溝通。 C 適合系統程式開發,主要是因為它同時具備: 1. 接近硬體的能力 2. 高效能與低執行成本 3. 精確的記憶體控制 4. 與作業系統 API 的良好整合 5. 廣泛的編譯器與工具支援 6. 良好的平台移植基礎 因此,C 成為連接「應用程式」與「作業系統核心」之間的重要語言。
相關學習地圖、教學課程
C 語言,系統程式
掌握基礎的 C 語法,以及進階的系統程式開發能力。