從簡單求和到 I/O 函數深度解析
經典累加循環分析
int k, s = 0;
for (k = 1; k <= 10; ++k)
s = s + k;
// 結果:s = 55 (1+2+...+10)
++k vs k++ 在獨立語句中無區別:兩者都將 k 加 1。區別僅在表達式中:++k 先加後用,k++ 先用後加。
三大字符輸出函數對比
| 函數 | 功能 | 換行行為 | 返回值 | 適用場景 |
| putchar(c) | 輸出單字符 | 不自動換行 | 成功返回字符,失敗返回 EOF | 逐字符處理、高性能輸出 |
| puts(str) | 輸出字符串 | 自動補全換行 | 成功非負,失敗 EOF | 整行輸出、調試信息 |
| printf(fmt, ...) | 格式化輸出 | 按格式符控制 | 輸出字符數,失敗負值 | 複雜格式、多類型混合輸出 |
代碼示例
#include <stdio.h>
int main() {
char c = 'A';
char str[] = "Hello World";
// putchar:單字符
putchar(c); putchar('\n'); // 輸出: A\n
// puts:字符串+自動換行
puts(str); // 輸出: Hello World\n
// printf:萬能格式化
printf("Char: %c, String: %s, Int: %d\n", c, str, 65);
// 輸出: Char: A, String: Hello World, Int: 65
// printf 也能輸出字符串
printf("%s\n", str); // 等同於 puts(str) 但不自動換行
return 0;
}
對應輸入函數
| 輸出函數 | 對應輸入函數 | 特點 |
| putchar | getchar | 單字符,帶回顯,需回車確認 |
| puts | gets (已棄用) | 整行讀取,危險:無緩衝區保護 |
| printf | scanf | 格式化讀取,功能最強但最複雜 |
安全替代方案
// 替代 gets:fgets(指定緩衝區大小)
char buf[100];
fgets(buf, sizeof(buf), stdin);
// 去除末尾換行符
buf[strcspn(buf, "\n")] = '\0';
// 替代 scanf 讀字符串:scanf 寬度限制
char name[20];
scanf("%19s", name); // 最多讀 19 字符,留 1 位給 \0
最佳實踐建議
- 調試輸出:優先用
puts 或 printf("...\\n")
- 高性能字符處理:用
putchar/getchar
- 格式化需求:必須用
printf/scanf
- 避免 gets:已從 C11 標準移除,極易導致緩衝區溢出漏洞