C 語言核心語法不多,關鍵在於「熟練運用」。本文整理七大基礎語法結構的實戰範例,涵蓋 bool 變數、字元處理、常數定義、數學函式、特殊字元、for 迴圈進階用法與函式設計,適合快速複習與查漏補缺。
#include <stdio.h>
#include <stdbool.h>
int main(void) {
float input;
bool isTrue = (scanf("%f", &input) == 1);
while (isTrue) {
printf("you typed %.0f\n", input); /* 強制轉 int 用 %.0f 或 (int)input */
isTrue = (scanf("%f", &input) == 1);
}
return 0;
}
重點:C99 引入 <stdbool.h>,bool 實為 _Bool 別名,配合 scanf 回傳值判斷輸入有效性。
scanf("%c") 會讀取換行符char beep;
while (scanf("%c", &beep) == 1) {
printf("you typed a %c\n", beep); /* 會輸出空行 */
}
getchar() 或 fgets()int ch;
while ((ch = getchar()) != EOF) {
putchar(ch); /* 逐字元回顯,正確處理換行 */
}
補充:gets() 已被 C11 移除(緩衝區溢位風險),請改用 fgets()。
#include <stdio.h>
#include <limits.h>
#include <float.h>
#define PI 3.1416
#define TEXT "hello world"
#define HTML 'H'
int main(void) {
const int china = 345;
printf("%d, %d, %d, %d\n", INT_MAX, china, FLT_MAX_10_EXP, CHAR_MIN);
return 0;
}
關鍵:#define 為前置處理器文字替換;const 有型別檢查與作用域;<limits.h>/<float.h> 提供平台相關極限值,增強可移植性。
#include <stdio.h>
#include <math.h>
#define PI 3.1415926
int main(void) {
for (int i = 0; i < 21; i++) {
float cosValue = 1 - i / 10.0;
int blankNum = (int)(180 / 5 / PI * acos(cosValue));
for (int j = 0; j < blankNum; j++) putchar(' ');
putchar('*');
for (int j = 0; j < (73 - 2 - 2*blankNum); j++) putchar(' ');
putchar(i != 20 ? '*\n' : '*');
}
return 0;
}
#include <stdio.h>
int main(void) {
double factorial = 1.0, e = 0;
for (int i = 1; i <= 50; i++) {
factorial *= i;
e += 1.0 / factorial; /* 前 10 項已足夠精度,50 項為示範 */
}
printf("%f\n", e); /* 2.718282 */
return 0;
}
\a \b \r \t#include <stdio.h>
int main(void) {
float salary;
printf("\aPlease enter your salary: "); /* \a 蜂鳴 */
printf("$______\b\b\b\b\b\b"); /* \b 退格覆蓋底線 */
if (scanf("%f", &salary) == 1) {
printf("\t$%.2f per month is $%.2f per year", salary, salary*12);
printf("\rGEE!WAH\n"); /* \r 回行首覆蓋 */
}
return 0;
}
輸出效果:GEE!WAH$23.40 per month is $280.80 per year(\r 導致前綴被覆蓋)。
for (int k = 1, printf("%d:hi\n", k);
printf("k=%d\n", k), k*k < 26;
k += 2, printf("now k=%d\n", k)) {
printf("k is %d in loop\n", k);
}
double arr1[8], arr2[8];
for (int i = 0; i < 8; i++) scanf("%lf", &arr1[i]);
arr2[0] = arr1[0];
for (int i = 1; i < 8; i++) arr2[i] = arr2[i-1] + arr1[i]; /* 前綴和 */
int max;
while (scanf("%d", &max) == 1) {
double sum1 = 0, sum2 = 0;
for (int i = 1; i <= max; i++) {
sum1 += 1.0/i;
(i % 2 == 0) ? (sum2 -= 1.0/i) : (sum2 += 1.0/i); /* 交替調和級數 */
}
printf("sum1=%lf sum2=%lf\n", sum1, sum2);
}
int square(int s);
void echo(void);
int main(void) {
for (int i = 0; i < 10; i++)
printf("square %d = %d\n", i, square(i));
echo();
return 0;
}
int square(int s) { return s*s; }
void echo(void) { puts("a function without input"); }
void one_three(void);
void two(void);
int main(void) {
puts("start");
one_three();
puts("done");
return 0;
}
void one_three(void) { puts("one"); two(); puts("three"); }
void two(void) { puts("two"); }
| 語法 | 常見錯誤 | 正確做法 |
|---|---|---|
| scanf("%c") | 殘留換行符 | 用 getchar() 或 fgets() |
| gets() | 緩衝區溢位 | 已棄用,改用 fgets(buf, sizeof(buf), stdin) |
| float 精度 | 累積誤差大 | 財務/科學計算用 double 或定點數 |
| for 逗號運算子 | 邏輯難讀 | 僅用於簡單初始化/遞增,複雜邏輯拆開寫 |
| 函式原型 | 隱式宣告 | C99 起必須先宣告,習慣寫在標頭檔 |
建議將上述範例逐一敲寫、編譯、觀察輸出,並嘗試修改參數驗證行為,方能內化為肌肉記憶。