質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

3回答

2157閲覧

最大値を求める関数形式マクロ

ssspwp

総合スコア31

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2017/11/27 16:59

C

1#define _CRT_SECURE_NO_WARNINGS 2#include<stdio.h> 3 4#define max(x,y) x>y?x:y 5 6int main() 7{ 8 int a, b, c, d; 9 10 printf("4つの整数を入力してください。\n"); 11 printf("整数a:"); scanf("%d", &a); 12 printf("整数b:"); scanf("%d", &b); 13 printf("整数c:"); scanf("%d", &c); 14 printf("整数d:"); scanf("%d", &d); 15 16 printf("最大値は%dです。\n",max(max(a,b),max(c,d))); 17 printf("最大値は%dです。\n",max(max(max(a,b),c),d)); 18 19 return 0; 20}
4つの整数を入力してください。 整数a:1 整数b:2 整数c:3 整数d:4 最大値は2です。 最大値は4です。

なんで最大値が2になるのでしょうか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

このようなトラブルを避けるため、マクロ定義では 必ず パラメータ名(ここではx,y)と式全体を括弧()で括ってください。

C

1// 修正前 2#define max(x,y) x>y?x:y 3 4// 修正後 5#define max(x,y) ((x)>(y)?(x):(y))

なんで最大値が2になるのでしょうか?

修正前のマクロ定義では、max(max(a,b),max(c,d))は次のステップで展開されます:

C

1max(max(a,b),max(c,d)) 2max(a>b?a:b,c>d?c:d) 3a>b?a:b>c>d?c:d?a>b?a:b:c>d?c:d

最終形は人間には読めたものではありませんが、少しだけ見栄えを整えます:

C

1a>b ? a : b>c>d ? c : d ? a>b ? a : b : c>d ? c : d

読みやすさのため、コンパイラが実際に解釈する単位で括弧を追記して整形します:

C

1(a>b) 2 ? a 3 : ((b>c>d) 4 ? c 5 : (d 6 ? ((a>b) 7 ? a 8 : b) 9 : (c>d) 10 ? c 11 : d) 12 )

あなたの意図しない単位で区切られていることが読み取れると思います。あとはご自身で変数値を当てはめてください。

投稿2017/11/27 17:14

yohhoy

総合スコア6191

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ssspwp

2017/11/27 17:16

すばやい回答ありがとうございます!
guest

0

-Eオプション等でマクロがどう展開されるか表示できます。
今回表示してみたところ
a>b?a:b>c>d?c:d?a>b?a:b:c>d?c:d
となりました。

#define max(x,y) (x)>(y)?(x):(y)

で4が表示されるようにできました。

ただし、

max(++a, --b)

などと副作用のある式を渡すと容易に壊れます

基本的に関数形式マクロを使わず、普通の関数(もしくはconstexpr関数)を用いてコンパイラの最適化に任せた方が無難です。

投稿2017/11/27 17:45

asm

総合スコア15147

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

yohhoyさんの素晴らしい回答が付いているなか回答するのも恐縮ですが...
細心の注意を払ったとしても、マクロは期待しない挙動を引き起こすことがあります。

C

1#include <stdio.h> 2 3#define MAX(x,y) ((x)>(y)?(x):(y)) 4int max(int x, int y) { 5 return x > y ? x : y; 6} 7 8int main(void) { 9 int x1 = 3, y1 = 4; 10 int x2 = 3, y2 = 4; 11 printf("MAX: %d\n", MAX(++x1, ++y1)); 12 printf("max: %d\n", max(++x2, ++y2)); 13 return 0; 14}

実行結果

MAX: 6 max: 5

通常の関数に置き換えられるなら、マクロは積極的に採用しない方がよいです。

投稿2017/11/27 17:35

LouiS0616

総合スコア35660

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問