先週のC言語の制御構文のシメとして、switch-case文の説明をしてから、 変数の寿命とスコープの説明を行った。
switch-case文の説明では、以下の例は期待通りの動きをしない…といった例も交えて説明。 ただし、double誤差問題や文字列のポインタ関連なので、以後の授業で改めて説明が必要だろう。
// double誤差問題
double x ;
for( x = 0.0 ; x <= 1.0 ; x += 0.1 )
switch( x ) {
case 0.3 : printf( "A" ) ; // 0.299999...と0.3は違う値になるかも
break ;
}
// 文字列の比較の問題
char str[ 10 ] ;
scanf( "%s" , str ) ;
switch( str ) { // strの先頭番地と"yes","no"の先頭番地の比較
case "yes" : printf( "はい" ) ; break ;
case "no" : printf( "いいえ" ) ; break ;
}
変数の寿命とスコープ
最初に、以下の様なプログラムが期待通りに動かない説明をして、 大域変数を共用することの問題を話す。
int i ; // 大域変数(global variable)
void foo() { // Aを2回表示
for( i = 0 ; i < 2 ; i++ )
printf( "A" ) ;
}
void main() {
// foo(Aを2回表示)を2回呼び出すつもり
for( i = 0 ; i < 2 ; i++ )
foo() ;
}
こういったトラブルを避けるためには、局所変数を使えば良い。
局所変数を使って、目的の処理…。改良版はココをクリックで表示。
最近の構造型プログラム言語であれば、 変数には寿命(変数が、作られる/消える、タイミング)と、 スコープ(変数が使える範囲)がある。
#include <stdio.h>
// 静的大域変数(スコープ全体,寿命:起動から終了)
int x = 123;
void foo() {
// 動的局所変数(スコープ:foo内部,寿命:foo呼出から戻るまで)
int y = 234 ;
// 静的局所変数(スコープ:foo内部,寿命:起動から終了)
static int z = 345 ;
x++ ; y++ ; z++ ;
printf( "%d %d %d¥n" , x , y , z ) ;
}
void main() {
foo() ; // 124,235,346が表示
foo() ; // 125,235,347が表示
}
関数の引数
関数の引数の受け渡しの説明。
返り値の型 関数名( 仮引数の宣言 ) {
何らかの処理 ; // 関数に入ると仮引数が局所変数で作られ、
return 式 ; // 実引数が代入される。
}
void main() {
関数名( 実引数 ) ; // 実引数は仮引数にコピーされる。
}
値渡し、ポインタ渡しなどの説明をしたいけど、時間なので次週に説明。 残り時間では、BCPL→B言語→C言語(K&R-C→ANSI-C)→C++といった C言語の変遷を簡単に紹介。