錯誤代碼分析
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main() {
int N, i;
scanf("%d", &N);
srand((unsigned)time(NULL));
for (i = 0; i < N; i++)
printf("%lf", rand()); // 錯誤:%lf 對應 double,rand() 回傳 int
return 0;
}
為什麼輸出全是 0?
rand() 返回 int(0 ~ RAND_MAX)。
%lf 告訴 printf 從堆疊/暫存器讀取 double(8 位元組)。
- 實際傳入只有 4 位元組
int,剩下 4 位元組是垃圾值,組成的 double 位元模式極大機率解析為 0.0(或極小非正規數,印出 0.000000)。
正確寫法
printf("%d ", rand()); // 印整數
// 或
printf("%f ", (double)rand()); // 強制轉 double 再用 %f
// 若要 0.0~1.0 浮點數
printf("%f ", (double)rand() / RAND_MAX);
隨機數最佳實踐清單
- 只呼叫一次
srand()(通常在 main 開頭),用 time(NULL) 或更高解析度種子。
rand() 質質一般,關鍵應用(加密、科學模擬)請用 random() (POSIX) 或 C++11 <random>。
- 生成區間
[min, max] 整數:min + rand() % (max - min + 1)(注意模數偏差,嚴謹場景用拒絕採樣)。
- 格式字串必須與實際參數型別完全對應,開啟編譯器警告(
-Wall -Wextra -Wformat)可自動偵測此類錯誤。
修正後完整範例
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main() {
int N, i;
printf("輸入產生隨機數個數: ");
if (scanf("%d", &N) != 1 || N <= 0) return 1;
srand((unsigned)time(NULL));
for (i = 0; i < N; i++) {
printf("%d ", rand());
if ((i + 1) % 10 == 0) putchar('\n');
}
putchar('\n');
return 0;
}