首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

C 語言結構體指針陷阱:scanf 讀取 double 型別導致成績輸出為 0.000000 的根因與修復

     編輯:程式設計疑難解答

問題現象

編寫學生成績管理程式,使用結構體指針操作學生數組。輸入學號、姓名、成績後,查找最高分學生輸出時,成績欄位始終顯示 0.000000。

代碼片段(問題版)

struct Student {
    int number;
    char name[20];
    double scores;
};

void StuInfo(struct Student *p) {
    for (int i = 0; i < 3; i++) {
        scanf("%d%s%f", &(p+i)->number, &(p+i)->name, &(p+i)->scores); // 錯誤在這裡
    }
}

根因分析

核心錯誤:scanf 格式字串中對 double 型別使用了 %f 而非 %lf。

  • %f 對應 float(4 字節)
  • %lf 對應 double(8 字節)
  • 傳入 &(p+i)->scores 是 8 字節地址,但 scanf 按 4 字節寫入,導致高 4 字節殘留垃圾值,解讀為極小數值(約 0.0)

修正代碼

void StuInfo(struct Student *p) {
    for (int i = 0; i < 3; i++) {
        // %lf 對應 double;name 為數組名即地址,無需 &
        scanf("%d %s %lf", &(p+i)->number, (p+i)->name, &(p+i)->scores);
    }
}

補充優化建議

  1. 去除 & 前綴:(p+i)->name 已是 char*,加 & 會變成 char(*)[20],雖然地址相同但類型不匹配,建議移除。
  2. 輸入驗證:檢查 scanf 返回值,確保讀取成功。
  3. 緩衝區處理:若混合讀取字串與數字,注意換行符殘留問題,可在 %s 前加空格或使用 fgets + sscanf。

知識點延伸

型別scanf 格式printf 格式位元組數
float%f%f4
double%lf%f / %lf8
long double%Lf%Lf16

記住:「scanf 讀 double 必用 %lf,printf 印 double 可用 %f」這一口訣,能避開 90% 的此類 Bug。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved