程式語言層出不窮,多數在現有基礎上改良,本質上未給程式設計師帶來質變。不要被特定語言綁架,也無需過度迷戀。TIOBE 榜單排名僅供參考,C 語言長盛不衰自有其道理。
/* First Version */
#include <stdio.h>
int main(void)
{
int blanks = 0, tabs = 0, newlines = 0;
int c;
while ((c = getchar()) != EOF) {
if (c == ' ') blanks++;
if (c == '\t') tabs++;
if (c == '\n') newlines++;
}
printf("\nBlanks: %d\nTabs: %d\nNewlines: %d\n", blanks, tabs, newlines);
return 0;
}
註解與命名的重要性:良好的命名(blanks vs b)與必要的註解,能讓程式「見名知意」,大型專案維護時尤為關鍵。
/* Second Version */
#include <stdio.h>
int main(void)
{
int blanks = 0, tabs = 0, newlines = 0;
int c, done = 0, lastchar = 0;
while (done == 0) {
c = getchar();
if (c == ' ') blanks++;
if (c == '\t') tabs++;
if (c == '\n') newlines++;
if (c == EOF) {
if (lastchar == '\n') newlines++; // 檔案以換行結尾時修正
done = 1;
}
lastchar = c;
}
printf("\nBlanks: %d\nTabs: %d\nNewlines: %d\n", blanks, tabs, newlines);
return 0;
}
引入 done、lastchar 狀態變數,妥善處理 EOF 邊界條件。
/* First Version */
#include <stdio.h>
#define NONBLANK 'c'
int main(void)
{
int c, lastchar = NONBLANK;
while ((c = getchar()) != EOF) {
if (c != ' ') putchar(c);
if (c == ' ' && lastchar != ' ') putchar(c);
lastchar = c;
}
return 0;
}
/* Second Version */
int c, inspace = 0;
while ((c = getchar()) != EOF) {
if (c == ' ') {
if (inspace == 0) { inspace = 1; putchar(c); }
}
if (c != ' ') { inspace = 0; putchar(c); }
}
inspace 作為「開關」狀態,邏輯更清晰。
// First Version
int c;
while ((c = getchar()) != EOF) {
if (c == '\t') printf("\\t");
else if (c == '\b') printf("\\b");
else if (c == '\\') printf("\\\\");
else putchar(c);
}
// Second Version
int c, t;
while ((c = getchar()) != EOF) {
t = 0;
if (c == '\\') { putchar('\\'); putchar('\\'); t = 1; }
if (c == '\t') { putchar('\\'); putchar('t'); t = 1; }
if (c == '\b') { putchar('\\'); putchar('b'); t = 1; }
if (t == 0) putchar(c);
}
// Third Version
#define DOUBLELINE '\\'
int c;
while ((c = getchar()) != EOF) {
switch (c) {
case DOUBLELINE: putchar(DOUBLELINE); putchar(DOUBLELINE); break;
case '\t': putchar(DOUBLELINE); putchar('t'); break;
case '\b': putchar(DOUBLELINE); putchar('b'); break;
default: putchar(c);
}
}
switch 結構清晰,但並非所有場合都比 if 高效。語言提供多種表達方式,視場合與偏好選擇,以簡潔清晰為準則。
int c, inspace = 0;
while ((c = getchar()) != EOF) {
if (c == ' ' || c == '\t' || c == '\n') {
if (inspace == 0) { inspace = 1; putchar('\n'); }
} else {
inspace = 0;
putchar(c);
}
}
遇到空白字元時,僅在首個輸出換行,實現單字換行。
getchar/putchar 等基礎函式組合靈活,非必要勿重造輪子。while、if、for 等核心構造跨語言共通,程式設計本質是邏輯的排列組合。