| 結構 | 圖形描述 | 對應 C 語言構造 |
|---|---|---|
| 順序 | 上下堆疊的矩形框 | 語句 1; 語句 2; ... |
| 選擇 (分支) | 主框分為左右/上下子框,條件寫在分界線上 `if-else`:雙分支 `if`:單分支 (另一側空) | `if (cond) { ... } else { ... }` `switch (expr) { case ... }` |
| 循環 | 主框頂部標註循環條件,主體在下方 `while`:頂部判斷 `do-while`:底部判斷 (N-S 圖通常統一頂部判斷,註明類型) `for`:初始化/條件/迭代在頂部標註 | `while (cond) { ... }` `do { ... } while (cond);` `for (init; cond; iter) { ... }` |
┌─────────────────────────────────────────────────────┐
│ 函數: process_file() │
├─────────────────────────────────────────────────────┤
│ [順序] FILE *fp = NULL; int line_count = 0; │
├─────────────────────────────────────────────────────┤
│ [選擇] fp = fopen("data.txt", "r") │
│ ┌─────────────────────┬─────────────────────────┐ │
│ │ 是 (fp != NULL) │ 否 (fp == NULL) │ │
│ ├─────────────────────┼─────────────────────────┤ │
│ │ [順序] │ [順序] │ │
│ │ // 唯讀打開成功 │ fp = fopen("data.txt", │ │
│ │ │ "w") │ │
│ │ │ [選擇] fp != NULL │ │
│ │ │ ┌──────┬──────┐ │ │
│ │ │ │ 是 │ 否 │ │ │
│ │ │ ├──────┼──────┤ │ │
│ │ │ │寫入初│ 返回 │ │ │
│ │ │ │始數據│ 錯誤 │ │ │
│ │ │ │ │ 碼 │ │ │
│ │ │ └──────┴──────┘ │ │
│ └─────────────────────┴─────────────────────────┘ │
├─────────────────────────────────────────────────────┤
│ [選擇] fp != NULL (統一入口) │
│ ┌─────────────────────┬─────────────────────────┐ │
│ │ 是 │ 否 │ │
│ ├─────────────────────┼─────────────────────────┤ │
│ │ [循環] while │ [順序] return -1; │ │
│ │ (fgets(buf,...)) │ // 打開/創建失敗 │ │
│ │ ┌───────────────┐ │ │ │
│ │ │ [順序] │ │ │ │
│ │ │ line_count++ │ │ │ │
│ │ │ // 其他處理 │ │ │ │
│ │ └───────────────┘ │ │ │
│ └─────────────────────┴─────────────────────────┘ │
├─────────────────────────────────────────────────────┤
│ [順序] fclose(fp); │
├─────────────────────────────────────────────────────┤
│ [順序] return line_count; │
└─────────────────────────────────────────────────────┘
#include
#include
#include
/* 返回文件行數,失敗返回 -1 */
int process_file(void) {
FILE *fp = NULL;
int line_count = 0;
char buffer[1024];
/* 1. 嘗試唯讀打開 */
fp = fopen("data.txt", "r");
/* 2. 若不存在,創建並寫入初始數據 */
if (fp == NULL) {
fp = fopen("data.txt", "w");
if (fp == NULL) {
perror("Failed to create data.txt");
return -1; // 創建失敗
}
/* 寫入初始數據 (示例) */
fprintf(fp, "Initial line 1\n");
fprintf(fp, "Initial line 2\n");
fprintf(fp, "Initial line 3\n");
/* 刷新緩衝區確保寫入磁盤,以便後續讀取 */
fflush(fp);
/* 重新定位到文件開頭以便讀取 */
rewind(fp);
}
/* 3. 讀取並處理 (計算行數) */
while (fgets(buffer, sizeof(buffer), fp) != NULL) {
line_count++;
/* 這裡可添加其他處理邏輯:解析、過濾、統計等 */
}
/* 4. 檢查讀取錯誤 (非 EOF) */
if (ferror(fp)) {
perror("Error reading file");
fclose(fp);
return -1;
}
/* 5. 關閉文件 */
fclose(fp);
return line_count;
}
int main(void) {
int lines = process_file();
if (lines >= 0) {
printf("File processed successfully. Line count: %d\n", lines);
} else {
printf("File processing failed.\n");
}
return 0;
}
| 維度 | N-S 圖 | 傳統流程圖 | 程式碼 |
|---|---|---|---|
| 結構化強制 | ✅ 天然結構化 | ❌ 允許任意跳轉 | ✅ 語法強制 |
| 可讀性 (高層邏輯) | ✅ 極佳,一眼看到巢狀結構 | ⚠️ 箭頭交叉難閱讀 | ✅ 細節最豐富 |
| 繪製/維護成本 | ⚠️ 手繪難,工具支援少 | ✅ 工具豐富 | ✅ 即代碼本身 |
| 適用階段 | 設計階段/文檔/教學/審查 | 舊系統遷移/簡單流程 | 實現/維護/除錯 |