前回(2020/05/15)の内容 文字と文字列 「文字列」は、「"」に挟まれた、「文字」の並び 文字列に含まれる文字の個数が、文字列の長さ 「"" (空文字列)」 (文字が)何も含まれていない文字列 空文字列の長さは 0 になる 「文字」は、ASCII Code 表にある文字(半角英数字記号) 基本は、キーボードのキーを一度押すと入力されるもの キーボードの[A]キーを押すと、「a」という文字が入る 「文字」では、基本は 1 byte で、一つの「文字」を表す => ASCII Code 表に記載されている文字 エスケープシーケンス : 「\」エスケープ文字 「\」から始まる「文字の並び」で、それで一つの「文字」を表す \n => 「\」と「n」の二文字で、一つの「文字」である「改行」を表す \t => タブ \" => 「"」文字一つを表す 文字列の中に、「"」を含めるときに、 エスケープシーケンスが必要 \\ => 「\」文字一つを表す。 条件分岐 : if 構文の利用 引数の値(文字列)によって、振舞いを変更する関数を作る => if 構文を利用する 構文 : if ( 「条件式」 ) { 「条件成立時の命令」 } else { 「不成立時の命令」 } 「if 構文」を利用すると 二つの命令のどちらか一方が実行される 条件が成立しないと、やっていけない命令 => 条件判定が不可欠になる 条件式 : 「真(条件が成立)」 または 「偽(条件が不成立)」 の値を取る式 例 : 「!strcmp(A,B)」は、 文字列 A, B が 同じ時に「真」 で その他は「偽」 となる 注意 : strcmp を利用するときには、 #include も必要 やりたい事が三つ以上あったら ? if 構文は、一つの条件を利用して、二つの場合の場合分けが可能 => 三つだったらどうするか ? if 構文を利用しないと「一つの場合」しか扱わない 「if 構文を一つ」利用すると「一つの条件」で、「二つの場合」が扱える 条件を一つ加えて if 構文を使うと、場合が一つ増える => 3 = 1 + 2 = 1 + 1 + 1 if 構文と(一緒に条件)を二つ使えばよい 例: 1) "abc" => ABC 2) "XYZ" => xyz 3) その他 => そのまま 三通り以上の場合分けをしたい場合は、 if 構文を、「入れ子」にする事により、実現可能 n + 1 通りの分類は、 n 個の if 構文(と条件)で記述可能 四通り 上に加えて "lmn" => "ZZZ" 1) "abc" => ABC 2) "XYZ" => xyz 3) "lmn" => "ZZZ" 4) その他 => そのまま if 構文が重なる(入れ子にする)ときには、 インデント(字下げ)を行い、if 構文の範囲が明確になるようにする => 複数の if 構文を組み合わせると、インデントが深くなる => 読みにくい else の中身が、一つの if 構文の場合は else if を利用して、(結果的に 「{」と「}」の組み合わせが減るので..) インデントの深さをさぼっても、わかりやすい書き方が可能になる [2020/05/22] 再帰 関数の定義の中で、自分自身を呼び出す事が可能 => 再帰呼び出し ( [数学] 帰納的定義 ) もし、 再帰呼び出しを、「無条件」に行うと、 無限ループ 「無限ループ」が目的なら、OK => 稀な例 (ゲーム機、OS etc..) => 「無限」=「必要なだけ何回でも繰り返せる」 => うまく条件を設定して、「必要なくなった」事が提示できれば、 必要なだけ繰り返す事ができる 関数定義の本体の所に自分自身を呼び出す(再帰呼び出し)によって、 同じ命令を繰り返す事ができる 繰り返し(再帰呼び出し)を途中で終了するために、 if 構文を利用して、条件判断を行う 再帰呼び出しを利用した、繰り返し 命令 C() を繰り返すには、 再帰的に定義された関数 f() を次の様に定義 void f(char *S) { if ( S に関する条件 ) { なにもしない } else { C(); -- 繰り返したい命令 f( S の値変更 ); -- 再帰呼び出し } } => S に変更を繰り返して、S に関する条件が成立するまで C() を繰り返し実行する [目的] A = 123 23 3 このために fA("123")=A となる関数 fA を定義したい A -> A1 + A2 A1 = 123 => printf ( "123" ); printf ( "\n" ); ---------------------- A2 = 23 => fA("23") = fA( "123" + 1 ) 3 fA("") => なにもしない なにもしない (S が "") fA(S) = { printf ( S ); printf ( "\n" ); fA(S + 1); void fA(char *S) { if ( !strcmp ( S, "" ) ) { } else { printf ( S ); printf ( "\n" ); fA( S + 1 ); } } == [目的] B = 3 23 123 このために fB("123")=B となる関数 fB を定義したい B -> B1 + B2 B = 3 B1 23 ---------------------- 123 B2 B1 = 3 => fB( "23" ); 23 B2 = 123 => printf ( "123" ); printf ( "\n" ); fB("") => なにもしない なにもしない (S が "") fB(S) = { fB(S + 1); printf ( S ); printf ( "\n" ); void fB(char *S) { if ( !strcmp ( S, "" ) ) { } else { fB( S + 1 ); printf ( S ); printf ( "\n" ); } }