首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C/C++ 表達式陷阱大全:奇數判斷、浮點精度、整型溢出、十六進制符號擴展

     編輯:關於C語言

C/C++ 表達式陷阱大全:奇數判斷、浮點精度、整型溢出、十六進制符號擴展

看似簡單的表達式往往隱藏著與直覺不符的行為。本文總結四類經典陷阱,給出正確寫法與底層原理解析。

一、判斷奇數:n % 2 == 1 是錯的

問題:負數取模在 C/C++ 中結果為負(-3 % 2 == -1),導致負奇數判斷失敗。

正確寫法:

// 方法 1:不等於 0
if (n % 2 != 0)  // 正負奇數均為真

// 方法 2:位運算(最高效)
if (n & 1)       // 末位為 1 即奇數,無分支預測失誤

原理:二進制最低位決定奇偶,& 1 直接提取該位,編譯器通常優化為單指令。

二、浮點精度:2.0 - 1.1 != 0.9

現象:

printf("%.20f\n", 2.0 - 1.1);  // 0.89999999999999991118

原因:十進制 0.1、1.1 等無法用二進制浮點數精確表示(類似 1/3 無法精確用十進制表示)。

解決方案:

  1. 輸出格式化:printf("%.2f", 2.0-1.1) → 0.90(僅顯示層面);
  2. 定點數/整數運算:金額以「分」為單位存儲 int cents = 200 - 110;
  3. 高精度庫:C++ boost::multiprecision::cpp_dec_float、Java BigDecimal("2.00").subtract(BigDecimal("1.10"))(**必須用字符串構造**,避免雙精度污染)。

三、長整型字面量溢出:24 * 60 * 60 * 1000 * 1000

代碼:

long weimiao = 24 * 60 * 60 * 1000 * 1000;  // 微秒數
long haomiao = 24 * 60 * 60 * 1000;         // 毫秒數
printf("%ld\n", weimiao / haomiao);         // 輸出 5 (預期 1000)

原因:字面量默認 int,**運算過程中**溢出(32位 int 上限 ~21億,實際需 864億),結果截斷後再賦給 long。

修正:至少一個字面量加 L 強制長整型運算:

long weimiao = 24L * 60 * 60 * 1000 * 1000;  // 正確輸出 1000

口訣:大數字面量運算,**首個常量加 L/LL**。

四、十六進制符號擴展陷阱

現象:

printf("%lx\n", 0x100000000L + 0xcafebabe);  // 輸出 cafebabe (預期 1cafebabe)

原因:

  1. 0xcafebabe 無後綴 → int(最高位 1 → 負數);
  2. long + int → int 先**符號擴展**為 32 位 0xffffffffcafebabe;
  3. 相加後低 32 位保留 cafebabe,高位丟失。

修正:第二個常量也加 L:

printf("%lx\n", 0x100000000L + 0xcafebabeL);  // 正確輸出 1cafebabe

總結口訣

  1. 奇數判斷用 n & 1;
  2. 金額計算用整數(分)或高精度庫(字符串構造);
  3. 大數字面量運算首項加 L;
  4. 十六進制/八進制常量參與混合運算時,**全部加後綴**防符號擴展。

這些陷阱雖小,卻能導致極難復現的 Bug。養成「看常量類型、想位模式、查標準行為」的習慣,是資深工程師的基本功。

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