? asked in 電腦與網際網路程式設計 · 1 decade ago

請問:C程式語言撰寫之程式執行後產生之輸出?

問題如下:

想請問程式之輸出及演算過程說明,

1.

我算過我的答是16,

可是出題者的正確答案為25,

想知道我的問題在哪裡?

#define PLUS(a, b) a+b

#define MINUS(a, b) a-b

#include 小於 stdio.h 大於

main( )

{

int m1 = 3, m2 = 5;

m1 = PLUS(m1, m2)*MINUS(m2, m1);

printf( 雙引號 %d 倒斜線 n 雙引號, m1);

}

2.

本題出題者的答案為1 2 1

我算的答案為 2 2 2

#include 小於 stdio.h 大於

#define MAX(a, b) (a 小於 b ? b : a)

#define PRINT1(x) printf( 雙引號 %d 雙引號 , x)

#define PRINT3(x, y, z) PRINT1(x), PRINT1(y), PRINT1(z)

main()

{

int m1 = 1, m2 = 3;

PRINT3( MAX( m1++, --m2), m1, m2);

}

ps:程式中之 大於 , 小於 , 雙引號 , 倒斜線為數學符號,

1 Answer

Rating
  • 1 decade ago
    Favorite Answer

    首先注意!!!

    #define 巨集所代表的意義跟函式不太相同

    它是將所 define 的東西完全複製到 code 裡取代前面的東西

    所以在第一道題目中

    m1 = PLUS(m1, m2)*MINUS(m2, m1);

    在經過取代後會變成

    m1 = a+b*b-a ;

    發現了嗎?

    這時候程式會遵循先乘除後加減的原則

    導致 m1的結果變為 m1= 3+ 5*5 - 3=25

    也就是跟你預期的結果不一樣

    這是在使用巨集時相當容易犯的一個錯誤

    最簡單的解決方法是將巨集定義成

    #define PLUS(a, b) (a+b)

    #define MINUS(a, b) (a-b)

    也就是在 a+b 和 a-b 的前後加上括號

    如此巨集在整個貼過去以後也可以保證先做 a+b a-b的動作

    事實上更正確的定義方式是, 每個變數也都要用括號包起來

    也就是

    #define PLUS(a, b) ((a)+(b))

    #define MINUS(a, b) ((a)-(b))

    第二題也是一樣的道理

    PRINT3( MAX( m1++, --m2), m1, m2);

    在展開後會變成

    PRINT1(MAX(m1++, --m2)), PRINT1(m1), PRINT1(m2)

    所有PRINT1再展開變成

    printf(" %d ", MAX(m1++, --m2)), printf(" %d ", m1), printf(" %d ", m2)

    最後MAX展開變成

    printf(" %d ", (m1++<--m2 ? --m2 : m1++)), printf(" %d ", m1), printf(" %d ", m2)

    注意到上面這行有什麼奇怪的地方嗎??

    沒錯!! 巨集在複製的過程中, 把 ++ 跟 -- 這兩個運算子也複製進去了!!

    導致整個結果發生嚴重的錯誤

    此處我引用ptt c_and_cpp版置底文中的 新手十誡 第十條內容

    macro 定義出的「偽函式」至少缺乏下列數項函式本有的能力:

    (1) 無法進行參數型別的檢查。

    (2) 無法遞迴呼叫。

    (3) 無法用 & 加在 macro name 之前,取得函式位址。

    (4) 呼叫時往往不能使用具有 side effect 的引數。例如:x++, --x

    錯誤反例:

    #define MACRO(x) (((x) * (x)) - ((x) * (x)))

    MACRO(++x) 展開來後變成 (((++x) * (++x)) - ((++x) * (++x)))

    =====================

    希望對你有幫助^^

    2009-12-07 15:15:35 補充:

    printf(" %d ", (m1++<--m2 ? --m2 : m1++))

    這段中

    由於一開始 m1++是小於 --m2 的, 所以又執行了一次 --m2

    所以最後結果 m1=2 , m2=1

    Source(s): myself
    • Commenter avatarLogin to reply the answers
Still have questions? Get your answers by asking now.