マクロをつかえば自作関数の引数にアドレスを渡す参照渡しの方法を使わなくてもとても簡単にmain関数内で定義された変数を直接、自作関数にかけて格納されている数値を変更することができます

マクロで自作関数を作製する

アレサ「マクロの


○○と記述したら☆☆を記述したとみなす


という性質を利用して


自作関数を作製することができます。

 

実際にマクロをつかって自作関数を


つくりながら、その作成方法をまなんでいきます。


それでよいですか? ソーラーさん」」


ソーラー「 あ~い、いいよ~~~~


自作関数・・・


自分で関数を作るか・・ マグロでつくれるの? 」


アレサ 「マグロでつくれるのは お・刺・身ですの


それと同じくらい簡単に


マクロをもちいて 自分で関数を作製することができます」


ソーラー 「では、マクロで自作関数つくっちゃお」


アレサ「それではっ


入力した数値に1を加える関数


f(a)=a+1をマクロをつかって作製してみましょう。


でも とっても簡単ですので あっという間におわってしまいそうです。


マクロの定義    #define f(a) a+1

             ⇧

こちらの記述で自作関数f(a)=a+1は作製完了することができます。」


ソーラー「わおっ簡単


どこかで自作関数を作ったときは


もっといろいろ気を付けないといけない箇所があったね。」


アレサ「はいっ 以前のエピソードで自作関数を作製した時と比べて


マクロを使った場合は 


とても簡単に自作関数を作製できるようになっています。」


ソーラー「


#define f(a) a+1を


マクロの仕組み


      ○○と記述したら☆☆を記述したとみなす


で考えてみるなら


f(a)と記述したら a+1とみなすっていうこと・・かな?


つまり


f(a)がプログラム中に現れたら


数式a+1におきかえて考えるということかな(^_-)-☆」


アレサ「はいっ まったく そうなんです。


マクロとは


    ○○と記述したら☆☆を記述したとみなす


という意味なのですが


このマクロの定義


#define f(a) a+1 


の場合では


f(a)という関数でも何でもない普通の文字の単語が記述されたら、


関数でも何でもない普通の文字の単語のa+1と


みなされおきかえられる


ということではなく


f(a)を a+1とみなす


ということを 表しています。


ソーラー「つまり このマクロの定義において


f(a)、a+1は ただの英単語でなく


関数を表しているということなんだね。」


アレサ「はいっ そして


コンピュータに


f(a)が関数と認識されるか、英単語と認識されるかは


f(a) の(a)があるかないかにかかわっています


関数名は f(a)でも function(a) でも


apple(a)でもよいのですが


関数と認識されるためには


(a)=(引数)の表記が必要なわけですの。


(a)=(引数)の表記がなければ


普通の英単語とコンピュータに認識されるわけですの。


それでは


実際にプログラムを構成して


マクロによってつくられた自作関数の働き方をみていきましょう。」


#include<stdio.h>


#define f(a) a+1


int main(void){

printf("%d\n",f(1));

return 0;

}


コンパイル結果

2


アレサ


「このプログラムでは


マクロの定義 #define f(a) a+1


により


f(a)がa+1とみなされていますので


f(a)にa=1を代入したら


a+1に1が代入したとみなされ


f(1)=2が


コンパイル結果に表示されるというわけです。」


ソーラー「マクロ いいかんじじゃないか(´▽`*)


これ とっても つかえるんじゃないかな。」



アレサ「その通りですね。


でも すこしだけ注意点もあります。


今 マクロによって作製した自作関数


f(a)=a+1


の aに1を代入したものを10倍してみます。


#include<stdio.h>


#define f(a) a+1


int main(void){

printf("%d\n",10*f(1));

/* f(a)に1を代入し10倍しています*/

return 0;

}

コンパイル結果

11


ソーラー 「 ???


あれ?


f(a)= a+1のaに1を代入したものを


10倍したのなら


f(1)= 2を10倍することになるので


コンパイル結果は


20?になるんじゃないかなあ?」


アレサ「そこが マクロの自作関数では異なってくるところなんです。。


マクロでf(a)は a+1とみなされるのですが


この マクロの自作関数f(a)に数値をかけあわせる


10*f(a)が行われる場合


10*f(a)=10*(a+1)でなく 


10*f(a)=10*a+1と


f(a)だった部分に素直にa+1が代入されます。


そのため

10*f(1)=10*1+1=11となり


コンパイル結果は

11となるわけです。」


ソーラー「ほんとに そのまんまf(a)だった部分に


a+1が代入されるわけなんだ。」


アレサ「ですので


このマクロで作製された自作関数f(a)にa=1を代入して


10で割る場合も


f(a)/10=(a+1)/10ではなく

f(a)/10=a+1/10となりますので


f(a)にa=1を代入しても


f(1)/10=2/10=0ではなく

f(1)/2=1+1/10=1となり


コンパイル結果は


以下の⇩のプログラムのように


0ではなく1となります。


🍊🍊🍊🍊🍊🍊🍊🍊🍊

int型(整数)(この場合、正確にはlong型)同士の割り算では


小数点以下の数値である


2/10=0.5は切り捨てられ0に

1/10=0.1も切り捨てられ0になります。

🍊🍊🍊🍊🍊🍊🍊🍊🍊




#include<stdio.h>


#define f(a) a+1


int main(void){

printf("%d\n",f(1)/10);

return 0;

}

コンパイル結果

1


ソーラー「素直な代入のされ方で なんか新鮮だね」





🌞  🌞


#include<stdio.h>


#define f(a) a+1


int main(void){

printf("%d\n",f(1));

return 0;

}


このマクロを使ったプログラムでは面白い点があります


どこかおわかりになられますか?


#include<stdio.h>


#define f(a) a+1


int main(void){

printf("%d\n",f(1));

return 0;

}



をじっとみてみて。



わかったかな?




🐤



          🐤



#include<stdio.h>


#define f(a) a+1


int main(void){

printf("%d\n",f(1));

return 0;

}


このプログラムにおいて


aは変数宣言されていないのですが


変数aとして機能しています


変数aに数値を代入することもできます


aはint型 か float型か決められてないため


変数aには整数値、実数値 両方を代入することができます。


今のプログラムで変数aに実数値5.0を代入してみると


#include<stdio.h>


#define f(a) a+1


int main(void){

printf("%f\n",f(5.0));

/*"%d出力変換指定子を%f出力変換指定子に

変更するのを忘れずに*/

return 0;

}


コンパイル結果

10.000000


がでてきます(*^-^*)」

  • Twitterで共有
  • Facebookで共有
  • はてなブックマークでブックマーク

作者を応援しよう!

ハートをクリックで、簡単に応援の気持ちを伝えられます。(ログインが必要です)

応援したユーザー

応援すると応援コメントも書けます