2016-01-25 28 views
0

使用宏3個值我試圖用我發現這裏的SO宏觀,但是,這個代碼給出了一些錯誤:排序用C

#include <stdio.h> 
#include <math.h> 

#define SWAP(a,b) do {\ 
int tmp = a; \ 
    a = b; \ 
    b = tmp;} while(0)\ 

#define SORT(a,b,c) \ 
if(a > b) { SWAP(a,b) } else if(a > c) { SWAP(a,c) } else if (b>c) { SWAP(b,c) } 

int main() 
{ 
    int a = 5, b = 2, c = 4; 

    printf("a = %d, b = %d, c = %d\n", a, b, c); 

    SORT(a,b,c); 

    printf("a = %d, b = %d, c = %d\n", a, b, c); 

    return 0; 
} 

然而,當我從SWAP宏刪除do while,它的工作原理,但給人的2,5,4代替2,4,5

隨着SWAP宏do ... while循環,我的代碼給我的錯誤:

Untitled2.c||In function ‘main’:| 
Untitled2.c|10|error: expected ‘;’ before ‘}’ token| 
Untitled2.c|18|note: in expansion of macro ‘SORT’| 
Untitled2.c|10|error: expected ‘}’ before ‘else’| 
Untitled2.c|18|note: in expansion of macro ‘SORT’| 
Untitled2.c|10|error: expected ‘;’ before ‘}’ token| 
Untitled2.c|18|note: in expansion of macro ‘SORT’| 
Untitled2.c|10|error: expected ‘}’ before ‘else’| 
Untitled2.c|18|note: in expansion of macro ‘SORT’| 
Untitled2.c|10|error: expected ‘;’ before ‘}’ token| 
Untitled2.c|18|note: in expansion of macro ‘SORT’| 
Untitled2.c|23|error: expected declaration or statement at end of input| 
||=== Build failed: 6 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===| 

編輯:

修改了代碼,但結果是錯誤的,該代碼給我2,5,4,而不是2,4,5

#include <stdio.h> 
#include <math.h> 

#define SWAP(a,b) do {\ 
int tmp = a; \ 
    a = b; \ 
    b = tmp;} while(0); 

#define SORT(a,b,c) \ 
if(a > b) { SWAP(a,b); } else if(a > c) { SWAP(a,c); } else if (b>c) { SWAP(b,c) } 


int main() 
{ 
    int a = 5, b = 2, c = 4; 

    printf("a = %d, b = %d, c = %d\n", a, b, c); 

    SORT(a,b,c); 

    printf("a = %d, b = %d, c = %d\n", a, b, c); 

    return 0; 
} 
+3

很容易看出,無論如何你只能執行一次交換。用一個交換對三個值(升序)進行排序是不可能的。試試吧:(2,3,1) – Ctx

+0

你可以這個技巧來交換'a^= b; b^= a; a^= b;' – razzak

+0

你爲什麼不能用函數而不是宏來做這個任何理由? – Lundin

回答

4

您在SORT宏中的SWAP(a,c)SWAP(b,c)之後缺少;

而且,這裏

#define SORT(a,b,c) \ 
    if(a > b) { SWAP(a,b) } else if(a > c) { SWAP(a,c) } else if (b>c) { SWAP(b,c) } 

使用else是錯誤的。爲了三個valueas abc排序,應該是

#define SORT(a,b,c) \ 
    {       \ 
     if((a) > (b)) { SWAP(a,b); } \ 
     if((a) > (c)) { SWAP(a,c); } \ 
     if((b) > (c)) { SWAP(b,c); } \ 
    } 

編輯

新增()abc,因爲他們可能代表了複雜的表達式。

+0

這不是「你不需要別的東西」,而是「這是錯誤的」。 – Ilya

+0

@Ilya Yeap ...錯誤的表情。 :)我會更新它。 –

+0

你應該在你的宏中放置一個'do {...} while(0)'外殼,否則你會冒風險。 –

1

你必須在第一宏末尾一個額外的連續字符\。因爲您有while (0),所以在SWAP()之後您需要分號。

這樣宏的行爲就好像它們是功能

#define SWAP(a, b) \ 
    do {   \ 
     int d;  \ 
     d = a;  \ 
     a = b;  \ 
     b = d;  \ 
    } while (0) 

#define SORT(a, b, c)  \ 
    do {     \ 
     if (a > b)   \ 
      SWAP(a, b); \ 
     else if (a > c) \ 
      SWAP(a, c); \ 
     else if (b > c) \ 
      SWAP(b, c); \ 
    } while (0) 

do { ... } while (0)目的是在SWAP的情況下終止多語句宏用分號,當然它也提供了一個範圍爲臨時變量d。但是對於範圍,您可以使用大括號{ ... },但在宏調用結束時添加分號會創建空語句,因此do { ... } while (0)是解決此問題的好技巧。

+0

但是還是有我提到的錯誤 – mirx

1

你需要用分號來結束while循環:while(0);

+0

好吧,我想通了,但仍然是錯誤的結果 – mirx

2

你需要一個分號終止do-while循環。

b = tmp;} while(0); 
        ^here 

您的swap邏輯也是錯誤的。其定義爲:

if(a > b) { SWAP(a,b) } if(b > c) { SWAP(b,c) } if (a>b) { SWAP(a,b) } 

但是......

整個馬可的事情是相當混亂。您最好直接使用if-else語句或使用簡單的inline函數。

宏是簡單的文本替換,並有許多固有的問題: - 它們不是類型安全的。 - 有副作用的宏參數會導致意想不到的問題。考慮:

#define SQR(x) ((x)*(x)) 

SQR(x++); 

一般來說,避免宏,除非你真的沒有任何其他的選擇。

+0

好吧,我想通了,但仍然是錯誤的結果 – mirx

+0

@mirx查看更新。 –

+1

通常的風格是**不在**宏中的do {/ * ... * /}之後使用分號。這迫使您在宏_call_之後放置一個分號。基本上,'do {/ * ... * /} while(0)'結構只有在宏調用之後強制程序員放置分號纔有用,因此添加分號宏觀內部本身就是失敗的目的。 –

1

讓檢查您的排序宏:

a=5, b=2, c=4

if(a > b) { 
    SWAP(a,b) 
} else if(a > c) { 
    SWAP(a,c) 
} else if (b>c) { 
    SWAP(b,c) 
} 

一個更大然後是b - >它們將被交換。
a=2, b=5, c=4
其餘的是else。因此它不會執行任何其他操作

0

在第9行中,如果在調用條件時終止了循環,則添加宏以進行排序,正如您稍後使用的其他條件。 因此,您應該像使用所有條件一樣。 更好的建議在這裏使用遞歸方法進行分類:)