表示調整
閉じる
挿絵表示切替ボタン
▼配色
▼行間
▼文字サイズ
▼メニューバー
×閉じる

ブックマークに追加しました

設定
0/400
設定を保存しました
エラーが発生しました
※文字以内
ブックマークを解除しました。

エラーが発生しました。

エラーの原因がわからない場合はヘルプセンターをご確認ください。

ブックマーク機能を使うにはログインしてください。
35/37

第三十三話 マクロの世界


「では今度はマクロについても、少し教えておくかな」

 立花先輩は言った。

「マクロ、ですか? それってエクセルとかにもありますね?」

 西原さんが言う。

「ま、定義したとおりにって所は少し似ているけど、Cのマクロはかなり違うわよ」

 先輩はメモ帳を開いて、プログラムを書き始める。

「まず、プリプロセッサについて話しておこうかな。実はね、コンパイルの前に行われる前処理があるのよ」

「そうだったんですか」

「うん。特定の設定された文字列を別の文字列に変換するってやつ。頭に#文字がある命令がそうなのよ」

「えっ、それって……いつも行う#includeもそうですね」

「西原さん、鋭いねー。それも実はプリプロセッサ命令なのよ。それから気づいてない? インクルードの最後には、いつも行の最後に必ずつけないといけない『;』セミコロンが無いでしょ? これもプリプロセッサ命令の特徴なの」

「あ、言われてみれば……」

「で、インクルードのほかに、今回紹介するのは、#define命令ね。これはマクロを設定する命令よ。……よし、書き終えた」

 先輩が言うので、俺たちは画面を覗き込んだ。



#include <stdio.h>


#define MACRO_NUMBER 10


int main(void)

{

  int a = MACRO_NUMBER;

  printf("%d", a);

  return 0;

}



「これは画面に10を表示するってプログラムね」

「MACRO_NUMBERって全部大文字なんですね」

「それはマクロのお約束ね。別に言語規定で決められてるわけじゃないけど、大半のプログラマは従っているの。そうすると、他の普通の変数とかと区別できて、すぐマクロってわかるからね」

「a = 10って書くのと、どう違うんだろう?」

「うん。いい質問。このa = 10の10みたいに、コードの中に直接数字を書くのは、マジックナンバーって言って、避けるべきプラクティスなのよ。この例だとどっちもあまり変わらないけど、たとえばコード内の100箇所に同じ10の数字があったとして、あとで『実は20でしたー』ってなったと想像してみて」

「うっ。それは、コード内のすべての10を20に修正する羽目になると?」

「うん。そのまま書いてたらね、徹夜で泣く泣く修正作業が待ってるわ。でも、もしマクロを使って、a = MACRO_NUMBERって書いてたら、たとえ100箇所でも1000箇所でも、一行だけMACRO_NUMBER 20って書くだけですべて自動修正されるでしょ?」

「あ、そうか! それでマクロってあるんだ」

 俺は納得した。

「ふふっ。じつは定数使うほかの方法もあるんだけど、マクロを使うのがCでは一般的ね。これがマクロの使い方、第一段」

「他にもあるんですか?」と西原さん。

「うん。第二段として、マクロで関数っぽいのを作ることも出来るのよ」

「なぬっ」

「たとえば、max関数をマクロにしたら、こうなるかなー」



#define MAX(a,b) ((a)>(b)?(a):(b))



「カッコが多いな」

「Lispっぽくなるの」とサヤちゃん。

「これは、マクロ展開後に、算術優先順位の関係で、答えがおかしくなることがあるから、値を保護するために、カッコで優先順位を最高位に引き上げているのね」

「うーむ」

「あと、まだ説明してなかったけど、右側の a ? b : c って式は、三項演算子って言って、If文に似ているの。もしaの式がTrueを返すなら、bを、Falseを返すならcの中の式を実行するの」

「ふむ。だと、これだと、aがbより上なら、aを、下ならbを戻り値に返すってことかな?」

「そう。引数aとbのどちらが大きいかを比べる関数マクロね」

「関数とマクロを使うのは、どう違うんだろう」

「一つは、早さね。マクロだと、そのままコード上に中身が展開されるから、関数を呼び出したり返したりする手間が省ける分、速度が上がるの。もっとも、いちいちコード上にマクロは展開されるから、実行ファイルがその分大きくなる欠点もあるけど」

「なるほど」

「ただ、マクロには特有の問題もあるから注意してね。たとえば、こういうのとか」


int a = 10

int result = MAX(++a , 10);


「これだと、中の++aが、2回、実行されちゃうのよ」

「え? なんで?」

「マクロを二つの引数で置き換えると、こうなるよね。 result = ((++a)>(10)?(++a):(10)); ++は前に置いているから、1つ足してから戻り値が帰るから11になる。10より上だから、一番目の(++a)が選択されて、また++aが実行されて、12になるの」

「うわっ。なんという」

「これがa = 9だったら、後ろの方が選ばれるから1回のみでしょうね。マクロ特有の問題って、こういう事」

「どうすればいいんでしょう」と西原さんも心配そう。

「一番の簡単な解決法は、マクロ内では値を変えるような式を入れない! ややこしい事をしなければ、ややこしい結果にはならないの」

 そりゃ、そうだ。

「こういう問題点も理解した上で使うならば、マクロはとても便利よ。大規模なプログラムになると、制御にマクロを使っているのが多いから、コードを読んでみるといろいろ参考になるわよ」

 そういうと、先輩は話を終えた。

評価をするにはログインしてください。
この作品をシェア
Twitter LINEで送る
ブックマークに追加
ブックマーク機能を使うにはログインしてください。
― 新着の感想 ―
このエピソードに感想はまだ書かれていません。
感想一覧
+注意+

特に記載なき場合、掲載されている作品はすべてフィクションであり実在の人物・団体等とは一切関係ありません。
特に記載なき場合、掲載されている作品の著作権は作者にあります(一部作品除く)。
作者以外の方による作品の引用を超える無断転載は禁止しており、行った場合、著作権法の違反となります。

この作品はリンクフリーです。ご自由にリンク(紹介)してください。
この作品はスマートフォン対応です。スマートフォンかパソコンかを自動で判別し、適切なページを表示します。

↑ページトップへ