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

C語言奇技淫巧:利用 printf 返回值實現無運算符加法

     編輯:關於C語言

腦洞大開:不用 `+` `-` `*` `/` 也能算加法?

在 C 語言中,若禁用算術運算符實現兩數相加,常規思路是位運算模擬全加器。但標準庫函數 `printf` 的特殊副作用——返回輸出字符總數,配合格式控制符的動態寬度特性,能構造出一個極其巧妙的「零運算符加法器」。

核心代碼 (C99 標準)

#include <stdio.h>

int main() {
    int a = 9;
    int b = 3;
    // 輸出 a+b 個空格,printf 返回輸出字符數 = a+b
    printf("%d\n", printf("%*s%*s", a, "", b, ""));
    return 0;
}

運行結果

12          ← 輸出 12 個空格 (肉眼不可見)
12          ← 外層 printf 打印內層返回值 12

在線運行驗證 (ideone.com)

機制深度拆解

1. `%*s` 動態寬度輸出字符串

格式串 `%*s` 中:

  • * 表示**寬度由對應參數提供** (而非寫死在格式串)
  • s 表示輸出字符串參數
  • 此處字符串參數為空串 ""

效果: `printf("%*s", a, "")` → 輸出 **a 個空格** (寬度 a,內容為空,左補空格)。

2. 串聯兩個 `%*s` 實現疊加

printf("%*s%*s", a, "", b, "");
// 等效於:
printf("%*s", a, "");  // 輸出 a 個空格
printf("%*s", b, "");  // 緊接輸出 b 個空格
// 總共輸出 a+b 個空格

3. `printf` 返回值特性

`printf` 返回成功輸出的字符總數 (負值表示輸出錯誤)。

內層 `printf` 輸出 `a+b` 個空格 → 返回 `a+b`。外層 `printf("%d\n", ...)` 打印該返回值。

3. 完整求值順序

printf("%d\n",  printf("%*s%*s", a, "", b, "") );
              ▲                 ▲
              │                 └─ 先執行:輸出 a+b 空格,返回 a+b
              └─ 後執行:打印返回值 a+b 並換行

為什麼這符合「無運算符」限制?

全程**零算術運算符** (`+` `-` `*` `/` `%` `++` `--` 等均未使用)。

遞歸推廣:任意多數求和

int sum_n(int n, ...) {
    va_list ap;
    va_start(ap, n);
    int total = 0;
    // 構建動態格式串 "%*s%*s...%*s" (n個)
    // 此處略過構建細節,核心思想相同
    // 利用 printf 返回值累加
    va_end(ap);
    return total;
}

副作用與局限性 (必讀)

  1. 控制台輸出污染:會實際向 stdout 寫入 `a+b` 個空格,大數值會刷屏、影響性能、干擾管道/重定向。
  2. 非負整數限制:寬度參數為負值行為未定義 (通常視為大正數),不適用負數相加。
  3. 整數溢出:`a+b > INT_MAX` 時寬度參數溢出,行為未定義。
  4. 線程安全/重入:依賴全局 stdout 鎖,高併發場景不可用。
  5. 純娛樂/教學價值:**絕不可用於生產代碼**。標準加法 `a+b` 編譯器優化為單條 `ADD` 指令,納秒級完成;此法涉及格式解析、緩衝區寫入、系統調用,慢 106 倍量級。

同類「標準庫副作用編程」拓展

  • `strlen` 計數:`strlen(strcat(strcpy(buf, "a"), "b"))` 獲取長度和 (構造字符串長度為 a+b)。
  • `scanf` 返回值:`scanf("%*c%*c", &a, &b)` 類似思路 (極其不推薦)。
  • 位運算標準解:遞歸/迭代 `(a ^ b) + ((a & b) << 1)` 至進位為 0,才是面試標準答案。

總結

這個技巧展示了 C 語言標準庫函數「副作用」與「返回值」的組合威力,更揭示了 **`printf` 格式引擎的圖靈完備潛力** (配合 `%n` 甚至能構造任意寫入)。作為技巧收藏與面試談資極佳,**切記:工程上請老誠實寫 `a + b`**。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
操作是否算術運算符說明
變量賦值 `=`否賦值運算符,允許
函數調用 `()`否後綴運算符,允許
格式串 `%*s`否格式控制,非運算符
參數傳遞 `,`否分隔符,非運算符
返回值傳遞否表達式求值規則