マクロで定義された自作関数をつかってmain関数内で定義された変数、配列、構造体、構造体の配列に格納されている数値を変更してみましょう ポインタ渡しの方法に比べてプログラムがとても簡単になります

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

アレサ「ではでは次のプログラムはいかがですか?」


#include<stdio.h>


#define f(a) a=a+1


int main(void){

int b=2;

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

printf("%d\n",b);


return 0;

}


アレサ

「このプログラムではmain関数で定義された変数bを


#define f(a) a=a+1


で定義された 自作関数f(a)のa に代入しています」


ソーラー「むむ?


こ、これは・・・


なにやら すごいことがおきるような・・・


気がするね・・・。


まずは


そもそも f(a)と記述されたらa+1とみなす


というのがマクロ


だったんだけど・・・


変数bをaの部分に代入して


f(b)=b+1


とできるかは


C言語の作者次第かな?


数値1が代入できたのなら


変数bをaの部分に代入できるんじゃないかな?」



アレサ「そうですね  


ではプログラムをコンパイルしてみます。


#include<stdio.h>


#define f(a) a=a+1


int main(void){

int b=2;

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

printf("%d\n",b);


return 0;

}


コンパイル結果

3

3


アレサ「main関数で定義された変数bを


自作関数で定義された変数aに代入できています」


ソーラー


「こ、こ、こ、こ、こ、こ🐓


こ、こ、こ、こ、こ、こ🐓


この結果は すごいことがおきてるよ


そうだよね。」


アレサ「はい  そうですの(´▽`*)」



ソーラー「


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

         printf("%d\n",b);



のコンパイル結果が


3

3


となっているところなんだ。


みなさんは どうおもわれますか?


ちょっと観察してみてよ。


このコンパイル結果は 革命的なことなんだよ」











ソーラー「


🐣 main関数で定義された変数bを 🐥



🐤 自作関数で定義された変数aに代入 🐦



って


値渡しのことだったよね


値渡しとは


次のプログラムのように


#include<stdio.h>


void f(int a) {

a=a+1;

}


int main(void){

int b=2;

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

printf("%d\n",b);


return 0;

}

コンパイル結果

3

2


のように



自作関数f(a)の変数aに 変数bを代入したとき


main関数で定義された変数bの格納している数値2の値だけが


変数aに渡されるので


main関数で定義された変数bは自作関数の操作を受けず


main関数で定義された変数bに格納されている値は


変化しないというものでした


それは


このプログラムの


printf("%d\n",b);


のコンパイル結果が


2になっていることからも分かります。


main関数内で最初に初期化されたときの


int b=2;のまま


bの値は2のまま変化していません。」


アレサ「ところが今のプログラムでは


#include<stdio.h>


#define f(a) a+1


int main(void){

int b=2;

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

printf("%d\n",b);


return 0;

}


コンパイル結果

3

3


        🐣 main関数で定義された変数bを 🐥



🐤 自作関数で定義された変数aに 🐦



代入した結果


main関数で定義された変数bは自作関数の操作を受けて


main関数で定義された変数bに格納されている値は


b=2から

b=3に変化しているのです ね」


ソーラー「これはすなわち




            🍎マクロをつかえば🍎




自作関数の引数にポインタ変数ptxを用い


そのポインタ変数ptxにmain関数で定義された変数aのアドレスを渡す


            参照渡しをおこない


main関数で定義された変数aのアドレスの場所にある数値をあらわす


'ptx'に操作を加えて


ようやく


        変数aに格納されている数値を変更する



というようなことを行わなくても



  main関数で定義された変数aを自作関数の引数である変数xに


直接代入するだけで


変数aに直接、自作関数の操作を加え


main関数内で定義された変数aに格納されている数値を


変更することができるということなんです。」


アレサ「これは すなわち


main関数内で定義された変数aに格納されている数値を


変更するのに


ポインタ変数を使う必要がないことをあらわしています」


ソーラー「こ、これは 思わぬ発見だったね


もうポインタ変数をつかわなくても


main関数で定義された変数aに格納されている数値を


自作関数によって変更することが


できるんだね。」


アレサ「ほんとうです これまで 


変数aのアドレスを自作関数の引数であるポインタ変数に参照渡し


配列hairetuのアドレスを自作関数の引数であるポインタ変数に参照渡し


構造体Cubeの構造体変数cube1のメンバ変数のアドレスを

自作関数の引数であるポインタ変数に参照渡し


構造体Cube型の配列strのアドレスを自作関数の引数であるポインタ変数に参照渡し


して自作関数の操作を加えることによって


変数a


配列hairetu


構造体Cubeの構造体変数cube1のメンバ変数


構造体Cube型の配列str


に格納されている数値を変更していました。




          プリプロセッサ マクロ



によって


あっさり 変更が可能になったんです」


ソーラー「Shyoeeeeeeeeeeeeえええ~~~~~


ma,まさか ここで そんなことがおこるとは


おもわなかったよ


今まで さんざんやりつくしてきたんだったあ」


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

作者を応援しよう!

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

応援したユーザー

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