博士「ここをチェックじゃ」

初日のしめは「変数」じゃ。
関数を使う上でかなーり重要じゃぞ!!


困った顔のぷうさん

やっと終わりが見えた…。

このプログラムを元に関数を使って応用していくぞい。

博士

まずは実行文をみるのじゃぞ。

実行文

#include <stdio.h>
main()
{
   int kazu1=50,kazu2=60;
   int tasizan,hikizan;

   tasizan=kazu1+kazu2;
   hikizan=kazu1-kazu2;

   printf("tasizan=%d hikizan=%d\n",tasizan,hikizan);
}

実行結果

tasizan=110 hikizan=-10

博士「ここをチェックじゃ」

一応実行結果も載せておいたのじゃが・・・見たかの?そこで問題じゃ。
上のプログラムの足し算、引き算の計算の部分を関数でできるかできないか。


ぷうさん「?」

さっきみたいにやればいいんじゃない?


困った顔の博士

そうじゃ。じゃが、戻り値は一つだけなんじゃぞ。


困った顔のぷうさん

そっかー。


博士「×」

それに関数の引数に書いた変数は関数の中だけで通用するのじゃ。
つまり{ }の中で宣言した変数はその{ }の中だけしか値を持っておらぬのじゃ。

例え、同じ名前の変数が宣言されていても、別個の物であって値は入らぬのじゃ。


ぷうさん「×」

つまり、同じaでもmainで宣言したaと関数内で宣言したaとは別物って事か。


博士

そうなんじゃ。それもその関数での処理が終わると、それに割り当てられた記憶領域は解放されてしまうから残っていないわけじゃ。

そこで、外部変数というものを使うわけじゃ。

ぷうさん「?」

外部変数??


博士「ここをチェックじゃ」

そう!関数の内部で宣言するものを『自動的変数(ローカル変数)』という。
それに対して、関数の外部で宣言するものを『外部変数(グローバル変数)』というんじゃ。


ぷうさん「(^^♪」

字そのものだね。


博士「(^^♪」

外部変数は宣言後全ての関数で辺用するんじゃよ。


ぷうさん

ふ~ん


博士

mainの上で宣言しておけば忘れる事もないじゃろ。
次のプログラムを見ればー一目瞭然じゃ。

実行文

#include <stdio.h>
void keisan(int kazu1,int kazu2);
int tasizan=0,hikizan=0;
main()
{
   int kazu1=30,kazu2=50;
   printf("main1 tasizan=%d hikizan=%d\n",tasizan,hikizan);
   keisan(kazu1,kazu2);
   printf("main1 tasizan=%d hikizan=%d\n",tasizan,hikizan);
}
void keisan()
{
   tasizan=kazu1+kazu2;
   hikizan=kazu1-kazu2;
   printf("keisan tasizan=%d hikizan=%d\n",tasizan,hikizan);
}

実行結果

main1=tasizan=0 hikizan=0
keisan=tasizan=80 hikizan=-20
main2=tasizan=80 hikizan=-20

チェックポイント

ぷうさん「OK」

外部変数はみんなで使う公共物
自動的変数は私物ってとこだね


博士

そこでじゃ、関数内で宣言した変数に戻ってじゃ・・
その関数から出ると記憶領域が解放される、つまり関数内にいたときの値はなくなると言ったの?


ぷうさん

うん。


博士「Good!」

普通intで宣言しているのが自動的変数といって、autoを省略しているんじゃ。
・・・正式にはauto int 変数名と宣言すべきなんじゃがの。

関数が呼ばれる度に変数の記憶領域が割り当てられ、終了するとその領域は解放される。
つまり不定なんじゃ。
ま、宣言時に初期化されていれば、関数が呼ばれる度に初期化ってことなんじゃが。

関数の処理が終わっても消滅しない「静的変数」

博士「ここをチェックじゃ」

外部変数とは反対に関数の処理が終わっても消滅せずに次に呼ばれるまで党えておいてくれる変数があるんじゃ。

それを『静的変数』といって、intのまえにstaticをつけて宣言するんじゃ。
つまり、static int 変数名じゃな。
これは初めに一回だけ記憶領域を割り当てられ、存在し続けるんじゃ。
じゃから一端その関数から出てもその値はそこに存在しているというわけじゃ。

宣言時に初期化しなくてもその変数の内容は0で初期化されておるしの。
宣言時に初期化していたらそれ以上はしないしの。


ぷうさん「?」

じゃ、2度目以降その関数が呼ばれたときは、そこのところは無視されるわけ?


博士「Good!」

まあ、そう覚えておいてよいじゃろ。
また初期化されては、静的関数の意味がないからの


ぷうさん「OK」

あっ、そうかぁ・・・じっと静かに卵を(値)を温めてるわけか!


博士

そんなところじゃな。
それを見るには次のプログラムをじっくりと見るんじゃな。

実行文

#include <stdio.h>
int kansu1(int kazu);
int kansu2(int kazu);

main()
{
   int i;
    for (i=1;i<=5;i=i+1) {
      printf("kansu1=%d ",kansu1(i));
      printf("kansu2=%d\n",kansu2(i));
   }
}

int kansu1(int kazu)
{
   int goukei=0;
   goukei=goukei+kazu;
   return (goukei);
}

int kansu2(int kazu)
{
   static int goukei=0;
   goukei=goukei+kazu;
   return (goukei);
}
博士「ここをチェックじゃ」

関数kansu2で静的変数を扱っておるぞい。

実行結果

kansu1=1 kansu2=1
kansu1=2 kansu2=3
kansu1=3 kansu2=6
kansu1=4 kansu2=10
kansu1=5 kansu2=15

チェックポイント

ぷうさん「(^^♪」

な~るほど!!
静的変数の方は前の合計を覚えていてそれに足してくれるわけだ。


困った顔のぷうさん

自動的変数は一回でると忘れて・・・まるで私みたいだ・・・・auto delete機能搭載・・・なんちゃって・・・・


困った顔の博士

おいおい、大丈夫かの?
骨折り抵のくたびれ儲けにしないでほしいのぉ・・・。


ぷうさん「怒」

さあ・・わっかりまっしぇ~ん・・
(別に忘れたくて忘れてるんじゃないんだし。)


博士

じゃあ、最後にまとめをしてこの辺にしておこうかの。
あまり詰め込んでも消化しきれないと逆効果じゃからの。


ぷうさん「(^^♪」

やったっ☆

関数と変数 まとめ







関数の基本形

int 関数名(int 引数,・・・・)   //プロトタイプ

main()
{
   関数名(引数,・・・・);   //関数を呼ぶ
}

int 関数名(int 引数,・・・・)   //関数の始まり
{
   関数の処理;
   return (戻り値);   //戻り値の指定
}   //関数の終わり

変数の適用範囲

  • { }の中で宣言した変数は、{ }の中だけで通用する
  • 関数の外部で宣言する外部変数なら、宣言後全ての関数内で通用する
  • 静的変数を宣言すると、値を保持する
  • 関数の引数は、値のコピーが渡ってくる
博士

とまあ、こんなところじゃな?

ん?もう寝ておるのか?こんなところじゃ風邪ひいてもわしゃ知らんぞ!
・・・おいっ!起きろっ!・・・・・・
やれやれ・・わしも疲れたわい。まあほっといて寝るとするか・・・
何かと馬鹿は風邪をひかんと言うしの・・・・。

///こうしてぷうさんの学習C言語、略して学Cの第一日目の夜が更けていくのだった。

ぷうさん

ムニャ‥ムニャ‥・クソジジイ もうあたまがパンク じょうたいだって!!‥・ムリ‥ムニャムニャ‥‥

///さて、果して本一冊やり遂げれるか、ぶうさん?!それとも、三日坊主か?!

///それでは、また明日お会いしましょう!

その六 関数と変数へ

一日目 C言語の基礎 目次

零日目へ

ぷうさんの七日間戦争 一日目

二日目へ