マクロについて

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
saka

マクロについて

#1

投稿記事 by saka » 6年前

マクロの関数でerror:expected expression before '{' tokenとエラーがコンパイル時にでます。
min3はa,b,cの中で最小の値を出力する関数です。
このエラーの原因はなんでしょうか?
よろしくお願いします。

コード:

 
#include <stdio.h>

#define min3(a, b, c) { \
  if(((b) < (a)) && ((b) < (c))){\
    return(b);\
  }else if(((c) < (a)) && ((c) < (b))){\
    return (c);\
  }else{\
    return (a);\
  }\
}

int main(void){
  int result1,result2,result3;

  result1 = min3(1,2,3);
  result2 = min3(2,1,3);
  result3 = min3(2,3,1);


  printf("%d %d %d\n",result1,result2,result3);

  return 0;
}

YuO
記事: 947
登録日時: 13年前
住所: 東京都世田谷区

Re: マクロについて

#2

投稿記事 by YuO » 6年前

関数形式マクロは,根本的には単純な文字列置き換えでしかありません。
書かれているコードの,min3のみ展開すると,

コード:

#include <stdio.h>
 

int main(void){
  int result1,result2,result3;
 
  result1 = { 
  if(((2) < (1)) && ((2) < (3))){
    return(2);
  }else if(((3) < (1)) && ((3) < (2))){
    return (3);
  }else{
    return (1);
  }
};
  result2 = { 
  if(((1) < (2)) && ((1) < (3))){
    return(1);
  }else if(((3) < (2)) && ((3) < (1))){
    return (3);
  }else{
    return (2);
  }
};
  result3 = { 
  if(((3) < (2)) && ((3) < (1))){
    return(3);
  }else if(((1) < (2)) && ((1) < (3))){
    return (1);
  }else{
    return (2);
  }
};
 
 
  printf("%d %d %d\n",result1,result2,result3);
 
  return 0;
}
のようになります。
代入の右辺に複文を指定するはできないため,そこにおいてエラーが出ています。
オフトピック
手作業で展開したため,展開結果に間違いがあるかもしれませんが,原因部分に間違いはないはずです。
関数形式マクロで戻り値を返したいならば,置換後が文ではなく式になるように書かないといけません。
また,複文に置き換える場合は,ifに直接ぶら下げた時に直後の;によってelseがエラーにならないように,do { /* マクロ本体 */ } while (0)のように書くのがidiomになっています。
オフトピック
可能ならばinline関数使え,という話ではありますが。

かずま

Re: マクロについて

#3

投稿記事 by かずま » 6年前

式で簡単に書けます。比較は 2回で十分です。

コード:

#include <stdio.h>
 
#define min3(a, b, c) ((a) < (b) ? (a) < (c) ? (a) : (c) \
		                         : (b) < (c) ? (b) : (c))
 
int main(void)
{
    int res1 = min3(1, 2, 3);
    int res2 = min3(1, 3, 2);
    int res3 = min3(2, 1, 3);
    int res4 = min3(2, 3, 1);
    int res5 = min3(3, 1, 2);
    int res6 = min3(3, 2, 1);
 
    printf("%d %d %d %d %d %d\n", res1, res2, res3, res4, res5, res6);
    return 0;
}
テストは、できればすべての場合を尽くしましょう。

返信

“C言語何でも質問掲示板” へ戻る