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

PAT 甲級 1018 A+B 和 C:大整數邊界測試、C99 變長數組與 long long 格式化輸入輸出完整解析

     編輯:關於C語言

A+B > C 判定:32 位整數溢出邊界、VLA 使用與格式化輸入輸出陷阱

題目給定區間 [-2^31, 2^31] 內的三個整數 A, B, C,判斷 A+B > C。測試用例包含邊界值 2147483647、-2147483648,直接用 int 相加會溢出(有符號溢出 UB),必須用 64 位類型 long long 計算。本文解析 C99 變長數組 (VLA) 在 OJ 環境下的支持情況、long long 掃描/打印格式化、邊界測試用例構造。

一、 核心邏輯與數據類型選擇

// A, B, C 讀入 int (32位足夠存儲輸入範圍)
// 但 A+B 可能溢出 int,必須提升至 long long (64位) 計算
long long sum = (long long)A + (long long)B;
int result = (sum > C) ? 1 : 0; // 比較時 C 隱式提升為 long long

二、 完整代碼實現 (C99 VLA 版)

#include 

int main() {
    int T;
    scanf("%d", &T); // 測試組數 ≤ 10
    
    // C99 變長數組 (VLA):大小由運行時變量 T 決定
    // 注意:VLA 分配在棧上,T≤10 極小,安全。大數組請用 malloc。
    int results[T]; 
    
    for (int i = 0; i < T; i++) {
        int A, B, C;
        scanf("%d %d %d", &A, &B, &C);
        long long sum = (long long)A + B; // 強制提升至少一個操作數
        results[i] = (sum > C) ? 1 : 0;
    }
    
    for (int i = 0; i < T; i++) {
        printf("Case #%d: %s\n", i + 1, results[i] ? "true" : "false");
    }
    return 0;
}

三、 關鍵技術點深度解析

1. 有符號整數溢出是未定義行為 (UB)

int a = 2147483647; // INT_MAX
int b = 1;
int c = a + b; // UB! 編譯器可假設不發生,導致優化錯誤
// 正確:
long long c = (long long)a + b; // 2147483648

2. long long` 格式化輸入輸出

操作格式字符串示例
scanf` 讀取%lld` 或 %lli`scanf("%lld", &x);
printf` 輸出%lld`printf("%lld\n", x);
無符號 unsigned long long`%llu`scanf("%llu", &x);

本題輸入範圍在 int 內,故用 %d 讀入 int 變量,計算時轉 long long,避免格式化字符串不匹配風險。

3. C99 變長數組 (VLA) 在 OJ 的支持性

  • 優點:語法簡潔,避免 malloc/free,自動釋放。
  • 風險:分配在棧上,大尺寸導致棧溢出;不支持初始化列表 (int a[n] = {0} 錯誤);C11 將其改為可選特性,部分編譯器 (MSVC) 不支持。
  • 本題適用:T ≤ 10,極小,棧壓力可忽略,PAT OJ (GCC) 完美支持。
  • 移植性寫法:int *results = malloc(T * sizeof(int)); 用完 free(results);。

4. 邊界測試用例構造

ABCA+B結果說明
1233false相等不大於
2345true正常
2147483647021474836462147483647trueINT_MAX 邊界
0-2147483648-2147483647-2147483648falseINT_MIN 邊界
-2147483648-1-2147483649-2147483649true負溢出測試 (需 long long)

四、 進階:無條件分支寫法 (可選)


五、 總結:避坑檢查清單

  1. ✅ 讀入用 int + %d,計算提升 long long。
  2. ✅ 比較 sum > C 時 C 自動提升,無需手動轉換。
  3. ✅ VLA results[T] 僅用於極小 T,大數據用 malloc。
  4. ✅ 輸出格式完全匹配 Case #X: true/false,大小寫、冒號、空格、換行。
  5. ✅ 循環變量 i 從 0 開始,輸出 i+1 對應 Case 編號。

核心收穫:看似簡單的 A+B 比較,實則考察有符號溢出 UB 規避、整數提升規則、C99 VLA 工程權衡、格式化輸入輸出精確匹配。養成「讀入用輸入類型、計算用足夠寬類型、比較自動提升、輸出嚴格匹配」的防禦性編程習慣,可避免 90% 的整數邊界 Bug。

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