ホーム » スタッフ » 斉藤徹 » 変数の取り扱い

2009年4月
« 3月   5月 »
 1234
567891011
12131415161718
19202122232425
2627282930  

最近の投稿(電子情報)

アーカイブ

カテゴリー

変数の取り扱い

今日は、変数の扱いの説明として、変数・関数と引数などを中心に話す。

変数の概念

  • 大域変数(global変数)
    • 大域変数は、どこからでも触れる変数で、極力使わない….など…
  • 局所変数(local変数)
    • forループなどのブロック内での変数宣言例など…
//大域変数を使うために起こるトラブル例
int  i ;
void foo() {
for( i = 0 ; i < 2 ; i++ )
printf( "A" ) ;
}
void main() {         // このプログラムは、AAAAと表示されない。
for( i = 0 ; i < 2 ; i++ )
foo() ;
}

関数との値の受け渡し

関数と呼び出し側の値の受け渡しということで、値渡し(Call by Value)・ポインタ渡し(Call by Pointer)などの解説。

基本的にC言語では、関数の実引数(real argument)が、仮引数(pseudo argument)に コピーされる値渡しが原則で、関数から複数の値の変化を知りたい場合に、 ポインタ変数のアドレスを使ったポインタ渡しを行うと説明する。

void foo( int *p ) {   // ポインタ渡しの例
(*p)++ ;
printf( "%d" , (*p) ) ;
}
void main() {
int a = 123 ;
foo( &a ) ;
foo( &a ) ;
}

関数の処理によって値が変化することを副作用と呼び、 副作用は自分の持っているものが想定外に変化するのであれば、 不気味な現象でもあり、極力副作用は小さい方がいい。 だからこそ、変化してほしい値だけをポインタで渡して書き換えてもらう….といった説明を行う。

演算子の前後の()について質問があったので、演算子の優先順位の説明を行う。 ついでだし、右結合・左結合といった話や、趣味の悪い「コンマ演算子」なども 雑学系のネタとして紹介する。

プロトタイプ宣言とプリプロセッサ

この話の中で「なぜ関数実体を読み出し処理より前に書くのか?」との質問がでる。
# 通常私のコーディングは実体を先に書くボトムアップ記述

基本的にコンパイルは、先頭から命令解析が行われるので、 関数の実体が先にあった方が、関数を呼び出す時に引数や帰り値が何なのか、 分かっていて都合が良いことを説明。 「トップダウン記述」であれば、呼び出し処理を先に書きたいけど、そういうときは プロトタイプ宣言が必要であることを説明する。

これに関連して、プログラム中の#行が、「プリプロセッサ行」であり、 「命令解析前の命令の書き換え処理」が行われると説明し、 "#include <stdio.h>" では、stdio.h というヘッダファイルを読み込み、 そのファイルには、printf(),scanf()のプロトタイプ宣言が書いてあることを説明する。