本文整理自《C程式設計的抽象思維》第2章的編程練習題解答,涵蓋了圓柱體積計算、評分系統、數組排序判斷、埃拉托斯特尼篩法求素數、直方圖輸出、數組去零、動態記憶體分配等經典C語言程式設計問題。這些練習不僅鞏固了基礎語法,更展示了模組化設計、指標運算與演算法思維的實際應用。
題目要求輸入圓柱的半徑與高度,計算並輸出其表面積與體積。程式採用模組化設計,將輸入、計算、輸出分離為三個函式,主函式僅負責協調流程,體現了「高內聚、低耦合」的設計原則。
#include <stdio.h>
#include <math.h>
#include <stdbool.h>
#define PI 3.1415926
void input(double *r, double *h) {
double a, b;
printf("請輸入半徑和高度:");
scanf("%lf %lf", &a, &b);
*r = a;
*h = b;
}
void count(double r, double h, double *s, double *v) {
*s = (2 * PI * r) * h; // 側表面積
*v = PI * r * r * h; // 體積
}
void output(double s, double v) {
printf("圓柱的表面積:%lf\n", s);
printf("圓柱的體積:%lf\n", v);
}
int main() {
double r, h, s, v;
input(&r, &h);
count(r, h, &s, &v);
output(s, v);
return 0;
}
注意:表面積公式僅計算了側表面積,若需總表面積應加上兩個底面積 2 * PI * r * r。
模擬評分系統,輸入n位評委分數,去除最高分與最低分後計算平均值。程式示範了陣列遍歷、極值查找與指標參數傳遞。
#include <stdio.h>
#include <math.h>
#include <stdbool.h>
#define MaxJudges 100
double Mean(double array[], int n) {
int i;
double total = 0.0, max, min;
max = min = array[0];
for(i = 0; i < n; i++) {
total += array[i];
if(max < array[i]) max = array[i];
if(min > array[i]) min = array[i];
}
return ((total - min - max) / (n - 2)); // 修正:分母應為 n-2
}
void ReadScore(double scores[], int n) {
for(int i = 0; i < n; i++) scanf("%lf", &scores[i]);
}
int main() {
int n;
double array[MaxJudges];
scanf("%d", &n);
ReadScore(array, n);
printf("平均值為:%lf\n", Mean(array, n));
return 0;
}
輸入一個整數數組,判斷其是否按非遞減順序排列。使用布林函式 IsSorted 封裝邏輯,主函式負責輸入輸出。
#include <stdio.h>
#include <math.h>
#include <stdbool.h>
bool IsSorted(int *a, int n) {
for(int i = 1; i <= n - 1; i++) {
if(a[i] < a[i-1]) return false;
}
return true;
}
int main() {
int n, array[1000];
scanf("%d", &n);
for(int i = 0; i < n; i++) scanf("%d", &array[i]);
if(IsSorted(array, n)) printf("TRUE\n");
else printf("FALSE\n");
return 0;
}
經典演算法實作,時間複雜度 O(n log log n)。程式中 N 定義為 1,000,000 但實際只輸出到 1000,篩選上限 n = (int)sqrt(N) 應改為 sqrt(1000) 更合理。
#include <stdio.h>
#include <stdbool.h>
#include <math.h>
#define N 1000000
bool isprime[N];
void initPrime() {
int n = (int)sqrt(N);
for(int k = 0; k < N; k++) isprime[k] = true;
isprime[0] = isprime[1] = false;
for(int i = 2; i <= n; i++) {
if(isprime[i]) {
for(int j = i * i; j < N; j += i)
isprime[j] = false;
}
}
}
int main() {
initPrime();
for(int i = 2; i <= 1000; i++)
if(isprime[i]) printf("%d\n", i);
return 0;
}
輸入 n 個整數,按十分位分組(0-9, 10-19, ..., 100),以星號顯示各組頻率。展示了 switch 分支統計與格式化輸出技巧。
#include <stdio.h>
#include <stdbool.h>
#include <math.h>
void printStar(int n) {
for(int i = 1; i <= n; i++) putchar('*');
printf("\n");
}
int main() {
int a[11] = {0}, b[1000];
int n, t, i;
scanf("%d", &n);
for(i = 0; i < n; i++) {
scanf("%d", &b[i]);
t = b[i] / 10;
if(t >= 0 && t <= 10) a[t]++;
}
for(i = 0; i < 11; i++) {
printf("%3d: ", i * 10);
printStar(a[i]);
}
return 0;
}
將數組中所有非零元素前移,零元素後移,返回零的個數。演算法使用雙指標思想,時間複雜度 O(n),空間複雜度 O(1)。
#include <stdio.h>
#include <stdbool.h>
#include <math.h>
void swap(int *a, int *b) {
int t = *a; *a = *b; *b = t;
}
int RemoveZeroElements(int a[], int n) {
int num = 0, j;
for(int i = 0; i < n; i++) {
if(a[i] != 0) {
if(i != num) swap(&a[i], &a[num]);
num++;
}
}
return n - num; // 返回零的個數
}
void printArray(int *a, int n) {
for(int i = 0; i < n; i++) printf("%d ", a[i]);
printf("\n");
}
int main() {
int a[] = {65,0,95,0,0,79,82,0,84,94,86,90,0};
int n = sizeof(a) / sizeof(a[0]);
printArray(a, n);
int zeronum = RemoveZeroElements(a, n);
printArray(a, n - zeronum);
printf("zero numbers: %d\n", zeronum);
return 0;
}
使用哨兵值 -1 結束輸入,動態更新最大最小值。展示了 while(~scanf(...)) 的輸入迴圈寫法。
#include <stdio.h>
#include <stdbool.h>
#include <math.h>
void solve() {
double n, min, max;
printf("Enter the elements of the array, one per line.\n");
printf("use -1 to signal the end of the list.\n");
printf("? ");
scanf("%lf", &n);
max = min = n;
printf("? ");
while(~scanf("%lf", &n) && n != -1) {
if(n < min) min = n;
if(max < n) max = n;
printf("? ");
}
printf("The range of value is %lf-%lf\n", min, max);
}
int main() {
solve();
return 0;
}
根據輸入的大小 n,使用 malloc 動態分配記憶體,填充 0 到 n-1,使用後釋放記憶體,示範了動態記憶體管理的標準流程。
#include <stdio.h>
#include <stdbool.h>
#include <math.h>
#include <stdlib.h>
int *indexArray(int n) {
int *p = (int *)malloc(n * sizeof(int));
for(int i = 0; i < n; i++) p[i] = i;
return p;
}
int main() {
int *ip, n;
scanf("%d", &n);
ip = indexArray(n);
for(int i = 0; i < n; i++) printf("%d ", ip[i]);
printf("\n");
free(ip);
return 0;
}
這組練習題涵蓋了C語言程式設計的核心技能:函式模組化、指標與陣列操作、動態記憶體管理、經典演算法實作、格式化輸入輸出。通過這些練習,可以建立扎實的程式設計基礎,為進階資料結構與演算法學習打下基礎。