グローバル変数bを自作関数の引数の変数aに代入した場合も値渡しとなるためグローバル変数bは自作関数の操作を受けることはなくグローバル変数bに格納されている数値は変更されません。

#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;

}

コンパイル結果


EAZY IDECの場合

3

2


Visual Studioの場合


E0070 不完全な型は使用できません

C2664 'int printf(const char *const ,...)': 引数 2 を 'void' から '...' へ変換できません。


と表示されます。


このプログラムをVisual Studioで実行できないのは


自作関数の定義の


void f(int a) {

a=a+1;

}

の表記に

問題があるからなのです。


この自作関数の定義では


自作関数f(int a) に戻り値が格納されないよう


voidが記述されています。


さらに


return a;


などのように


戻り値を自作関数fに返すように記述もされていませんね



この状態で


f(b);


が実行されるとどうなるでしょうか?


f(b);


を実行すると


f(int a)


のint aに


main関数のブロック内で変数宣言された


変数bを代入されることになりますが


このとき


変数bの格納している値2だけが変数aに渡される


            💖値渡し💖


がおこなわれるのでしたね


ですので


a=a+1;


が実行されると


aの格納している値は


3


となります



f(b)


に戻り値が返されることはありません


自作関数f(b);


が実行されても


f(b)は戻り値をもつことがないので


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


を実行しようとしても


f(b)の持つ値が存在せず


ビルドエラーが生じてしまうというわけです。


そのことを


Visual Studioは


警告してくれているのですね。



この不完全なプログラムでも


何故か

EAZY IDECなら実行できてしまうというわけです。


そこで


自作関数f(int a) に


a=a+1;


がおこなわれたあとの


aの値


が戻り値として


返るよう


void f(int a) {

a=a+1;

}

の部分を


int f(int a) {

a = a + 1;

return a;

}


と記述し直します。


a=a+1;


が実行された後の


aの値が戻り値として f(int a)に戻るよう


return a;


を追加し


整数値である戻り値が格納されるよう戻り値を格納する型を


void型からint型に変更したというわけですね。



それでは改めてこの自作関数の定義が用いられたプログラムを実行してみましょう😊

👇

#include<stdio.h>


int f(int a) {


a = a + 1;

return a;

}


int main(void) {


int b = 2;


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

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


return 0;

}


コンパイル結果

EAZY IDECの場合

3

2


Visual Studioの場合

3

2



ソーラー 「ようやく


Visual Studioの場合でも


正しく


コンパイル結果が表示されるようになったね。


この訂正されたプログラムでは


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


が実行されています


(f(b)に注目してみましょう)


そのとき


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


f(b)


のように


自作関数fの引数部分の()内に代入し


変数bに格納している数値データ2を自作関数の引数である


変数aに値渡ししています。


つまり


自作関数内でint a;の実行により


作製された変数aという名前の付いたメモリ



main関数内でint b;の実行により


作製された変数bという名前の付いたメモリ


が独立して存在し


変数bという名前の付いたメモリに格納されている


数値データ2を


変数aという名前の付いたメモリに


渡しているのですね


f(b)


が実行されると


aに2が渡された状態の


a=a+1;


が実行されて


aに格納された値が3になったとしても


変数bは自作関数fの操作を受けることはなく


変数bに格納されている値は


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


のコンパイル結果をみてもわかるように


int b=2;


と変数宣言、初期化されたときの


b=2のまま変化することはありません。


a=a+1;


の実行後


return a;


が実行されると


f(b)には戻り値として3が返されることになります


ですので



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


の実行結果は


3


となります



めでたし めでたし


今度はプログラムを変形し


#include<stdio.h>


int b=2;//👈☀️ここに注目


int f(int a) {

a = a + 1;

return a;

}


int main(void){


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

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


return 0;

}


のように


int b;をプログラムの先頭にもっていき


変数bをmain関数の前で定義したなら


このプログラムのコンパイル結果はどうなるかな?」


アレサ「それはmain関数のローカル変数bの代わりに


グローバル変数bを設定するということですね」


ソーラー「そうなんです。変数bをグローバル変数にすれば


グローバル変数宣言

int b=2;

がおこなわれたのなら


そのグローバル変数bは


それより下の行の


自作関数内でも

main関数内でも


共通して


使用できることになります


このグローバル変数bを


f(b)


と自作関数f(int a)のint aに代入して実行した場合でも


グローバル変数bの持っている値2だけが


main関数のローカル変数aに値渡しされて


f(b)が実行された際


グローバル変数bは


自作関数fによる影響をうけることなく


グローバル変数bの格納している値は2のままとなるのでしょうか?


それとも


int f(int a) {

a = a + 1;

return a;

}



つまり自作関数


f(int a)



グローバル変数bが代入されることにより


b=b+1;


が実行されて


グローバル変数bの格納する値は


2から3に変化するのでしょうか?


それではコンパイル結果はどうなるかな?」


アレサ「どきどきっ💖


bのグローバル変数宣言,初期化を


int b=2;


とプログラムの先頭でおこなった場合


グローバル変数bの格納している値2だけが


自作関数の引数である変数aに値渡し


されるのでしょうか?


グローバル変数bは


main関数内で作製されたローカル変数bと違い


自作関数内でも

main関数内でも


共通して


使用できるので


グローバル変数bが自作関数f(int a)に代入された場合


b=b+1;


が実行されて


グローバル変数bの格納する値は


2から3に変化するようにもおもえます。」


ソーラー「ほんと たのしみだね


では グローバル変数bが用いられたプログラムを実行してみたいと思います」

👇

#include<stdio.h>


int b=2;//👈ここに注目


int f(int a) {

a = a + 1;

return a;

}


int main(void){


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

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


return 0;

}


ソーラー「コンパイルっ」


コンパイル結果

3

2



アレサ「printf("%d\n",b);


の実行結果に


2が表示されています😊」


ソーラー「


f(b)が実行されて


グローバル変数bを自作関数f(int a)の引数である変数aに


代入した場合も


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


のコンパイル結果をみてもわかるように


グローバル変数bに格納されている値2のみが


自作関数の引数である変数aに値渡しされるので


a = a + 1;

return a;


の実行においては


b=b+1;

return b;


が実行されることはありません


aに1が代入された状態で


a = a + 1;

return a;


が実行されることになります


ですので


グローバル変数bに格納されている値は


int b=2;


と変数宣言、初期化されたときの


b=2のまま


グローバル変数bに格納されている値は変化することはないんだ・・」


アレサ「このことは


グローバル変数宣言


int b=2;により


作製された変数bという名前の付いたメモリ



自作関数f内でint aにより


作製された変数aという名前の付いたメモリ


が独立して存在していることをしめしています。


変数bという名前の付いたメモリに格納されている


数値データ2を


変数aという名前の付いたメモリに


渡しているのみなので


aに2が代入された


a=a+1;


が実行されて


変数aの格納している値が3になったとしても


変数bという名前の付いたメモリに格納されている数値データは変化しませんね。


グローバル変数bは自作関数fの操作を受けることはなく


グローバル変数bに格納されている値は


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


のコンパイル結果をみてもわかるように


int b=2;


と変数宣言、初期化されたときの


b=2のまま変化することはないのですね。」











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

作者を応援しよう!

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

応援したユーザー

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

新規登録で充実の読書を

マイページ
読書の状況から作品を自動で分類して簡単に管理できる
小説の未読話数がひと目でわかり前回の続きから読める
フォローしたユーザーの活動を追える
通知
小説の更新や作者の新作の情報を受け取れる
閲覧履歴
以前読んだ小説が一覧で見つけやすい
新規ユーザー登録無料

アカウントをお持ちの方はログイン

カクヨムで可能な読書体験をくわしく知る