C 語言基礎(include、define、變數與資料型態)
課程目標
- 理解預處理指令: 學會使用
#include
引入標頭檔案與#define
定義常數與巨集,並了解其在編譯前的作用。 - 掌握變數與資料型態: 能夠宣告各種基本資料型態的變數,包括整數、浮點數、字元與字串,並熟悉其使用方式與範圍。
- 認識基本輸入輸出: 瞭解如何使用
printf()
與scanf()
進行簡單的資料輸出與輸入(可作為後續課程的鋪墊)。
第1部份
1. 預處理指令
1.1 #include
指令
- 用途:
用來引入外部函式庫或自訂標頭檔,讓程式能夠使用已有的函數與定義。 - 常見用法:
#include <stdio.h>
:引入標準輸入/輸出函式庫,提供printf()
、scanf()
等常用函數。#include "my_header.h"
:引入專案中自訂的標頭檔,通常包含常數、函式原型或資料結構定義。
- 附加說明:
在自訂標頭檔中建議加入標頭防護(Header Guard),例如:
這樣可以避免同一個標頭檔被重複引入,減少編譯錯誤。#ifndef MY_HEADER_H #define MY_HEADER_H // 內容... #endif
1.2 #define
指令
用途:
用來定義常數或建立簡單的巨集(macro),在編譯前將指定符號替換為對應的值或程式碼。範例:定義常數
#define MAX_LENGTH 100 printf("Max length: %d\n", MAX_LENGTH);
這裡
MAX_LENGTH
在編譯時會被替換成100
。範例:定義巨集
#define add(a, b) ((a) + (b)) printf("Result: %d\n", add(3, 4));
注意: 使用括號包住參數與整個運算式,可以避免運算順序的錯誤,確保巨集能正確執行。
2. 變數與資料型態
2.1 基本概念
- 變數:
在 C 語言中,變數用於儲存資料,每個變數在宣告時必須指定其資料型態。 - 資料型態:
決定變數能儲存哪種類型的資料以及其可能的範圍,常用的有整數、浮點數、字元與字串。
2.2 常見資料型態與宣告範例
- 整數型態:
int num = 5; // 整數 unsigned int amount = 36; // 無號整數
- 浮點型態:
float pi = 3.14159; // 單精度浮點數 double precisePi = 3.141592653589793; // 雙精度浮點數
- 字元型態:
char letter = 'A'; // 單一字元
- 字串:
字串以字元陣列形式儲存:char str[] = "Hello, C!";
2.3 資料型態範圍(參考 <stdint.h>
)
資料型態 | 等效型態 | 範圍 |
---|---|---|
char |
int8_t |
-2^7 ~ 2^7-1 |
unsigned char |
uint8_t |
0 ~ 2^8-1 |
short |
int16_t |
-2^15 ~ 2^15-1 |
unsigned short |
uint16_t |
0 ~ 2^16-1 |
int |
int32_t |
-2^31 ~ 2^31-1 |
unsigned int |
uint32_t |
0 ~ 2^32-1 |
long |
int64_t |
-2^63 ~ 2^63-1 |
unsigned long |
uint64_t |
0 ~ 2^64-1 |
float |
float |
約 -3.4E+38 ~ 3.4E+38 |
double |
double |
約 -1.7E+308 ~ 1.7E+308 |
- 附註:
使用<stdint.h>
可以讓我們指定固定大小的整數型態,這對於跨平台程式設計尤為重要。
3. 基本輸入與輸出操作簡介
雖然本堂課的重點在於預處理與變數宣告,但了解基本的輸入輸出操作對後續課程非常重要。
3.1 輸出操作— printf
- 功能:
用於格式化並輸出資料到螢幕。 - 範例:
printf("Hello, World!\n"); printf("The number is: %d\n", num);
- 注意:
根據資料型態選用正確的格式符,例如%d
用於整數,%f
用於浮點數,%c
用於字元,%s
用於字串。
3.2 輸入操作— scanf
- 功能:
用於從鍵盤讀取格式化資料,需傳入變數的地址。 - 範例:
int num1, num2; printf("Enter two integers: "); scanf("%d %d", &num1, &num2);
- 提示:
檢查scanf()
的回傳值,以確保輸入成功,這是撰寫穩健程式的重要技巧。
4. 範例程式:簡易變數宣告與輸出
以下範例綜合展示了 #include
、#define
、變數宣告與基本輸出:
#include <stdio.h>
// 定義常數
#define MAX_VALUE 100
int main() {
// 變數宣告
int num = 42;
float pi = 3.14159;
char letter = 'C';
char greeting[] = "Hello, C Language!";
// 輸出變數內容
printf("Number: %d\n", num);
printf("Pi: %f\n", pi);
printf("Letter: %c\n", letter);
printf("Greeting: %s\n", greeting);
printf("Max value (from define): %d\n", MAX_VALUE);
return 0;
}
- 討論重點:
- 觀察
#define
如何將符號MAX_VALUE
替換成具體數值。 - 學習如何依據資料型態正確地使用不同格式符。
- 觀察
第2部份
1. 輸出操作詳解— printf()
1.1 格式化字串與格式符
基本格式符:
%d
:輸出整數。%f
:輸出浮點數(預設輸出小數點後6位)。%c
:輸出單一字元。%s
:輸出字串。
範例:
printf("整數:%d\n", 42); printf("浮點數:%f\n", 3.14159); printf("字元:%c\n", 'A'); printf("字串:%s\n", "Hello, C!");
1.2 格式化細節
- 可使用修飾符控制輸出寬度與精度,例如
%8.2f
表示輸出總寬度8,且小數點後2位。 - 學生可嘗試修改格式,觀察輸出效果的不同。
2. 輸入操作詳解— scanf()
2.1 基本語法與使用方式
- 基本語法:
scanf("格式化字串", &變數);
- 關鍵點:
- 必須傳入變數的地址(例如
&num
)。 - 格式化字串必須與變數型態相符。
- 必須傳入變數的地址(例如
2.2 輸入錯誤處理
- 檢查回傳值:
scanf()
會回傳成功讀取的變數個數。若回傳值不符預期,代表輸入錯誤。- 範例:
int num; printf("請輸入一個整數:"); if (scanf("%d", &num) != 1) { printf("輸入錯誤!\n"); }
- 練習討論:
- 學生應討論如何在錯誤輸入後給予適當提示,並可能要求使用者重新輸入。
2.3 注意,windows 下中文可能出現亂碼,請依照以下程式碼修正
#include <stdio.h>
#ifdef _WIN32 //判斷windoes
#include <windows.h>
#endif
int main(void) {
#ifdef _WIN32 //判斷windoes
// 輸出中文亂碼修正
SetConsoleOutputCP (65001);
#endif
printf("hello clang ㄏㄏ!\n");
return 0;
}
或者用在終端機數入
chcp 65001
3. 綜合範例:計算橢圓面積
3.1 程式說明
- 目的:
利用scanf()
讀取使用者輸入的兩個浮點數(代表橢圓的長軸與短軸),使用預先定義的巨集計算橢圓面積,再透過printf()
輸出結果。 - 關鍵概念:
- 巨集
calculate_ellipse_area(ra, rb)
使用括號確保運算順序正確。 - 輸入錯誤處理能提升程式穩定性。
- 巨集
3.2 範例程式
#include <stdio.h>
#define PI 3.14159
#define calculate_ellipse_area(ra, rb) ((ra) * (rb) * (PI))
int main() {
float axis1, axis2;
printf("請輸入橢圓的長軸與短軸(以空格分隔):");
if (scanf("%f %f", &axis1, &axis2) != 2) {
printf("輸入錯誤!\n");
return 1;
}
printf("橢圓面積為:%f\n", calculate_ellipse_area(axis1, axis2));
return 0;
}
3.3 編譯與執行
- 使用 Clang 編譯器:
clang -o ellipse ellipse.c
- 執行程式:
./ellipse
- 學生可藉由修改程式、重新編譯與執行,加深對輸入輸出及巨集運算的理解。
第3部份
1. 運算子概述
1.1 算術運算子
- 基本運算子:
+
、-
、*
、/
、%
(取餘數) - 範例:
int a = 10, b = 3; int sum = a + b; // 加法:13 int diff = a - b; // 減法:7 int prod = a * b; // 乘法:30 int quot = a / b; // 除法:3 (整數除法) int rem = a % b; // 餘數:1
1.2 賦值與自增/自減運算子
- 賦值運算子:
=
、+=
、-=
、*=
、/=
、%=
- 自增/自減:
++
、--
- 範例1:
int x = 5; x += 3; // x 現在為 8 等同 x = x + 3 x++; // x 現在為 9 等同 x = x + 1
- 範例2:
int x = 5; int y; y = x++; // x 現在為 6; y 現在為 5 y = ++x; // x 現在為 7; y 現在為 7
1.3 關係與邏輯運算子
- 關係運算子:
==
、!=
、>
、<
、>=
、<=
- 邏輯運算子:
&&
(且)、||
(或)、!
(非) - 範例:
int m = 10, n = 20; if ((m < n) && (n != 0)) { printf("條件成立\n"); } else { printf("條件不成立\n"); }
1.4 位元運算子
- 常用位元運算子:
&
(位元且)、|
(位元或)、^
(位元互斥)、~
(位元非)、<<
(左移)、>>
(右移) - 範例:
unsigned int num = 5; // 二進位:0000 0101 unsigned int shifted = num << 1; // 結果:10 (0000 1010)
2. 表達式與運算子優先順序
2.1 運算子優先順序
- 運算子在複雜表達式中有固定的優先順序。例如,乘法與除法的優先順序高於加法與減法。
- 範例:
int result = 3 + 4 * 2; // 結果為 11,而非 (3+4)*2 = 14
- 使用括號:
- 為避免混淆,建議使用括號明確指定計算順序。
int result = (3 + 4) * 2; // 結果為 14
2.2 表達式計算示例
- 分析以下表達式:
int a = 5, b = 2, c = 3; int result = a + b * c - (a - c) / b;
- 先計算
b * c
與(a - c)
,再依據運算子優先順序進行後續運算。
- 先計算
3. 型態轉換(Type Casting)
3.1 隱性與顯性型態轉換
- 隱性轉換:
編譯器自動將一種型態轉換為另一種,例如將整數轉換為浮點數進行運算。 - 顯性轉換:
使用強制型態轉換符號(type)
明確指定轉換方式,避免不預期的結果。
3.2 型態轉換範例
- 整數除法問題:
int a = 7, b = 2; float result = a / b; // 結果為 3.000000,因為 7/2 為整數除法
- 使用顯性轉換:
float result = (float)a / b; // 結果為 3.500000
轉換範例表
類型 | 轉換後類型 | 範例 |
---|---|---|
int + float |
float |
5 + 2.5 → 5.0 + 2.5 = 7.5 |
char + int |
int |
'A' + 1 → 65 + 1 = 66 |
short + int |
int |
1000 + 2000 → 3000 |
int / int |
int |
10 / 4 → 2 |
int / float |
float |
10 / 4.0 → 2.5 |
char 傳遞到函數 |
int |
printType('A') → printType(65) |
4. 綜合範例:計算圓的面積與周長
4.1 程式說明
- 目的:
利用運算子、表達式及型態轉換,計算圓的面積與周長,並正確輸出結果。 - 公式:
- 面積:A = PI * r * r
- 周長:C = 2 * PI * r
- 其中
r
為半徑。
4.2 範例程式
#include <stdio.h>
#define PI 3.14159
int main() {
float radius;
printf("請輸入圓的半徑:");
if (scanf("%f", &radius) != 1) {
printf("輸入錯誤!\n");
return 1;
}
// 計算面積與周長,使用顯性轉換確保運算精確
float area = PI * radius * radius;
float circumference = 2 * PI * radius;
printf("圓的面積為:%f\n", area);
printf("圓的周長為:%f\n", circumference);
return 0;
}
5. 課堂互動與練習
- 練習題目: 請撰寫一個 C 程式,要求使用者分別輸入圓柱體的半徑與高度,計算表面積與體積。
6. 本堂課小結
運算子與表達式:
透過本堂課學習了各類運算子及其優先順序,並理解了如何利用括號明確指定計算順序。型態轉換:
掌握了隱性與顯性型態轉換的概念,學會在需要時使用(type)
進行強制轉換,確保運算結果的精確性。綜合應用:
通過計算圓的面積與周長的範例,整合了運算子、表達式與型態轉換的知識,並鞏固了基本運算的概念。