前回(2020/06/05)の内容 複雑な数学パズルを、再帰を用いて解決する 順接/条件分岐/再帰 => 万能性 原理的に解く事ができるものは、解ける 解くプログラムを作成する事ができる 再帰的に問題を解くパズル ハノイの塔 高さ N のハノイの塔の問題を解くには 高さ N-1 のハノイ塔を移動し サイズ N の円盤を移動 高さ N-1 のハノイ塔を移動 => 問題をより簡単な問題に分割 再帰 => 数学的に「正しく問題を解く」事が証明できる プログラムが動いたから OK だけでなく => ある特殊な条件ではうまく行く事が保証される 作成されたプログラムが、「任意の場合」でもうまくゆく事を 証明する事ができる => 数学の能力が要求される 砂漠の旅人 「数学」と「情報」の関係 プログラムを作成して問題を解く 「アルゴリズム」:問題を解くための手順 数学的な「ものの考え方」 問題を解く鍵(アルゴリズム)になる 数学の概念でアルゴリズムにつながる考え方 計算 色々モデル(数学概念:線形空間/収束/分類/帰納法/背理法/etc..) C 言語における『文字』 cf. 『文字列』: C 言語の表現上の「文字列」を『文字列』であらわす 「"」で挟さまれた「文字」の並びで表現 例 : 「"abc"」は、三つの「文字」「a」,「b」,「c」からなる「文字列」を表す => 『文字列』は、長さをもっており、この例では長さ 3 になる 『文字』: C 言語の表現上の「文字」 「'」で挟まれた、一つの「文字」で表現 例 : 「'a'」は、一つの「文字」「a」を表す 『文字』は、長さはない ( 常に 1 と考えてもよいが、意味がない ) 注意 : 「"a"」は、長さ 1 の『文字列』で、「'a'」は『文字』なので、異なるもの C 言語では、『文字』と『文字列』は、まったく違うもの 文字の入力と出力 『文字』の出力 cf. 『文字列』の出力 printf 関数を使う 例: printf ( "abc\n" ); => 画面に「abc」と改行が表示される エスケープシーケンス : 「\n」は、 「改行」一文字を表す putchar ( 'a' ); => 画面に対して、「文字」「a」を出力する # 同じ「出力(画面への表示)」機能 # 出力対象(『文字』と『文字列』)が異なる # => 異なる関数(putchar,printf)を利用する必要がある 文字の表現 文字は「'」で挟む (cf. 「文字列」は「"」で挟む) 当分は、半角のみ、日本語の「文字」は扱わない 半角 : 英数、大文字小文字、簡単な記号 => ASCII Code 表の対象 # 実は、C 言語では、「全角の文字」(日本語の漢字)も扱える # 色々な制約 : この講義では扱ない # !! 文字コードによって結果異なる # !! Windows は SJIS / Ubuntu は UTF-8 # !! => Windows と Ubuntu で結果が違う ## 「全角文字を含む文字列」は「表示目的」で利用する 文字の出力 putchar( 文字 ); を使う 「putchar ( 'a' );」 で文字('a')が出力される 改行文字は '\n' で表す : putchar ( '\n' ) で改行する エスケープシーケンスは、「文字」の表現にも利用される 「'\n'」は、「一文字の改行」を表す『文字』を表している 文字の「入力」 「出力」=> 画面になにを表示する機能 「入力」=> キーボードからキーを押して、そのキーに対応する『文字』を プログラム内で扱えるようにする機能 「getchar()」とすると、キーボードからの入力を待つ キーボードからキーを押して、さらに[Enter]キーを押すと そのキーに対応する『文字』とさらに'\n' が入力される [プログラム] printf ( "キーボードから、一文字入力し、さらに [Enter]キーを押してください 「" ); ^^^^^^^^^^^^^^^^^^^^^^^^^^(1)^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ putchar ( getchar() ); ========= キーボーから入力 : 入力内容がエコーバック ~ printf ( "」\n" ); ++++++++++++++++++ [出力] キーボードから、一文字入力し、さらに [Enter]キーを押してください 「a ^^^^^^^^^^^^^^^^^^^(1)^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^= = : 「a」と「改行」が表示 : キーボードからの入力 ('a'+[Enter]) a」 ~ : 「a」という文字が表示されている : getchar() で入力された『文字』を出力 ++ : 閉じかっこと改行が表示 getchar() によって、「プログラムの実行時」に、 キーボードから入力された『文字』をプログラム内で利用できる [プログラム] printf ( "キーボードから、文字列を入力し、さらに [Enter]キーを押してください \n" ); ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ それぞれ、一文字入力し、出力をする putchar ( getchar() ); ここで、初めて入力待ちになり、 キーボードから「"abc\n"」が入力される 最初の文字「'a'」が getchar でとりだされ、出力 => 'a' のみ出力 putchar ( getchar() ); getchar() が呼ばれて、「入力」が要求されるが、 すでに、"abc\n" が入力済で、かつ、そのうちの 先頭の一文字「'a'」は、一つ前の getchar でとりだされているので、 ここでは、次の「'b'」が取り出され、それが表示される => 'b' のみ出力 putchar ( getchar() ); => 'c' のみ出力 !!! ここで、まだ、「改行」が残ったまま、食い残しが残っている printf ( "\n" ); => 改行 [出力] キーボードから、文字列を入力し、さらに [Enter]キーを押してください ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ abc ==== : 文字列「"abc\n"」: 改行も含め 4 文字 abc 「putchar ( getchar() );」とすると、入力した文字が出力される 文字の計算 cf. 『文字列』には +1 する事ができた => 先頭の一文字が失われ、長さが 1 短い文字列になる 例 : "abc" + 1 => "bc" 『文字』 + 1 => 次の『文字』になる 'a' + 1 => 'b' 'A' + 1 => 'B' '1' + 1 => '2' !!! '1' + '1' は '2' にならない !!! 1 + 1 も '2' ではない ( 2 ) !!! 「1」と「'1'」は違う物 !!! 「数値」と「数字」 !!! 「数字」 => '0' 〜 '9' !!! 「数値」 => 無限に存在する じゃ、 'z' + 1 '9' + 1 は... ? 『文字』の「次」は 「ASCII コード表順」の次になるので 'z' + 1 => '{' となる。 逆に、『文字』に「-1」する事により(ASCII コード表順の) 前の『文字』になる == C 言語では、『文字』が扱える プログラム中で表現ができる : 'a' で、「文字」「a」を表す事ができる 出力ができる : puthar ( 'a' ) で「a」が画面に表示される 入力ができる : getchar() でキーボードから「文字」が入力できる 計算ができる : +1 で次の『文字』、-1 で前の『文字』になる !!! 『文字』と『文字列』は別物 ( "a" と 'a' ) 『文字』と『文字列』の関係 『文字列』「"abc"」は、三つの「文字」「a」,「b」,「c」からなる => 長さは 3 になる 「文字」「a」は、C 言語では、「'a'」なので、この関係がどうなっているか 『文字列』から、その一部である『文字』を取り出す方法 # 『文字列』を『文字』に分解する方法 # !!! 分解 => 合成もあるが、二周目 「*」演算子 ( ポインター剥ぎ / 間接参照演算子 ) 『文字列』の先頭に「*」を付けると、「先頭の『文字』」が取り出せる 例 : *"abc" => 'a' => 先頭以外の文字は ?? 『文字列』「"abc"」の二文字目: 『文字』「'b'」 !!! 『文字列』の計算 !!! "abc" +1 => "bc" => * ( "abc" + 1 ) 「[]」演算子 *( X + i ) <-> X[i] X : 何か ( 文字列 ) i : 整数値 例: *"abc" <-> *( "abc" + 0 ) <-> "abc"[0] <-> 'a' *( "abc" + 1 ) <-> "abc"[1] <-> 'b' *( "abc" + 2 ) <-> "abc"[2] <-> 'c' 「空文字列」へ「*」をつけるとどうなるか ? => 結果は、「null 文字」「'\0'」になる *"" => '\0' !!! 空文字列は「""」で、「null 文字」は「'\0'」の事 !!! => 全然違う イメージとして、 "abc" は、{ 'a', 'b', 'c', '\0' }となるもの !!! 『文字列』の最後には必ず「null 文字」がいる !!! => 「null 文字」が『文字列』の終わりを表す