本文整理自實際教學中的 C 語言考試題庫,涵蓋基礎運算、流程控制、函數設計、陣列字串、結構體、指標、遞迴等核心知識點。每題附帶完整代碼與邏輯解析,適合備考複習與面試熱身。
int gcd(int a, int b) {
while (b) { int t = a % b; a = b; b = t; }
return a;
}
int lcm(int a, int b) { return a / gcd(a, b) * b; } // 先除後乘防溢位
核心:輾轉相除法(歐幾里得演算法),時間複雜度 O(log min(a,b))。
void countCase(const char *s, int *upper, int *lower) {
for (; *s; ++s) {
if (*s >= 'A' && *s <= 'Z') ++*upper;
else if (*s >= 'a' && *s <= 'z') ++*lower;
}
}
注意:避免使用 gets(已棄用),改用 fgets。
long long sumSequence(int a, int n) {
long long term = 0, sum = 0;
for (int i = 0; i < n; ++i) {
term = term * 10 + a;
sum += term;
}
return sum;
}
技巧:利用 term = term*10 + a 迭代生成每一項。
long long factorialSum(int n) {
long long fac = 1, sum = 0;
for (int i = 1; i <= n; ++i) {
fac *= i;
sum += fac;
}
return sum;
}
優化:單迴圈累積階乘值,避免重複計算。
bool isPrime(int x) {
if (x < 2) return false;
for (int i = 2; i * i <= x; ++i) // 僅需試除至 √x
if (x % i == 0) return false;
return true;
}
優化:試除上限為 √x,並可跳過偶數進一步加速。
typedef struct { double a, b, c; } Triangle;
double area(Triangle t) {
if (t.a + t.b <= t.c || t.a + t.c <= t.b || t.b + t.c <= t.a)
return -1; // 不合法
double p = (t.a + t.b + t.c) / 2;
return sqrt(p * (p - t.a) * (p - t.b) * (p - t.c));
}
typedef struct { double x, y, r; } Circle;
bool overlap(Circle c1, Circle c2) {
double dx = c1.x - c2.x, dy = c1.y - c2.y;
double distSq = dx*dx + dy*dy;
double rSum = c1.r + c2.r;
return distSq < rSum * rSum; // 避免 sqrt,比較平方值
}
void caesarEncrypt(char *s) {
for (; *s; ++s) {
if (*s >= 'a' && *s <= 'z') *s = (*s - 'a' + 1) % 26 + 'a';
else if (*s >= 'A' && *s <= 'Z') *s = (*s - 'A' + 1) % 26 + 'A';
}
}
修正原碼錯誤:原碼 'Z' -> 'Z' 明顯錯誤,應為 'Z' -> 'A'。
typedef struct { double x, y; } Point;
double triangleArea(Point a, Point b, Point c) {
double ab = hypot(a.x-b.x, a.y-b.y);
double bc = hypot(b.x-c.x, b.y-c.y);
double ca = hypot(c.x-a.x, c.y-a.y);
if (ab+bc<=ca || ab+ca<=bc || bc+ca<=ab) return -1;
double p = (ab+bc+ca)/2;
return sqrt(p*(p-ab)*(p-bc)*(p-ca));
}
int *p;
{
int a = 10;
p = &a; // a 為區域變數,出作用域即銷毀
}
*p = 20; // 未定義行為:p 成為野指標,指向已釋放棧記憶體
教訓:絕不返回區域變數位址,或將指標指向已銷毀物件。
void printFirst100Primes() {
int count = 0;
for (int i = 2; count < 100; ++i)
if (isPrime(i)) printf("%d ", i), ++count;
}
void minmax10(const int a[10], int *min, int *max) {
*min = *max = a[0];
for (int i = 1; i < 10; ++i) {
if (a[i] < *min) *min = a[i];
if (a[i] > *max) *max = a[i];
}
}
double average10(const double a[10]) {
double sum = 0;
for (int i = 0; i < 10; ++i) sum += a[i];
return sum / 10;
}
int alternatingSum() {
int sum = 0;
for (int i = 1; i <= 100; ++i)
sum += (i % 2 ? i : -i);
return sum; // 結果 -50
}
double fractionSum(int n) {
double sum = 0;
for (int i = 1; i <= n; ++i)
sum += (double)i / (i + 1); // 強制浮點除法
return sum;
}
gets/scanf 緩衝區溢出、指標安全。建議對每題手寫代碼、編譯執行、設計邊界測試案例(空輸入、極值、非法輸入),方能內化為實力。