[前回の内容] for 構文/while 構文(/switch 構文) break 構文の範囲を終了して、次の文に移る !! for/while は繰り返しの先頭で判断をする !! 1. 繰り返し本体に入る前にチェックする !! => 繰り返し本体内では、そのチェックした条件が成立 !! 2. 抜けるとしたら、先頭で !! => break は、途中で抜ける事が可能 continue(ループのみ) 構文の「最後」に移動する => 次のループ(繰り返しのステップ)に入る => for 構文では、パラメータの更新を行い、 更に、while 構文と同様、条件チェックを行う => if 構文を利用して、continue は除去できる # continue : retry (skip) になっていて、なくてもよい # break; ループを途中で中断(quit)して抜けるための、常套手段 # => こちらも、if 構文を利用して、除去は可能だが、非自明 条件式の正体 前回までは「条件(論理式)」=>「命題」なんだろうと思っていた 実態は、単なる「整数値(0 => 偽 / 0 以外 => 真)」 => 計算したり、関数の引数にできる、関数の値にできる.. ! 関数の引数に渡す「条件式の値」は、関数内で「フラグ引数」として ! 扱われる ! => 条件判断の結果を、関数の外で判断し、関数の中で利用する ! => 条件判断の結果は、「どの命令を実行するか」という事 ! => コードの実行を、データで制御できる ! !! プログラムのシステム : コードがデータを処理する 条件式が「整数値」を持つ 様々な計算が可能 整数としての計算もできる(あまりお勧めしない..) 論理式としての計算も可能 論理演算子が使える (P,Q が共に条件式[論理式]) && 論理積 P&&Q => PとQの一方が0なら0、それ以外は1 || 論理和 P||Q => PとQの一方が0でないなら1、それ以外は0 論理表 P | Q | P&&Q | P||Q T T T(1) T(1) T F F(0) T(1) F T F(0) T(1) F F F(0) F(0) T : 真 ( 0 以外 ) F : 偽 ( 0 ) ||, && は、ショートカットの機能がある P&&Q の場合、P が 0 の時は、Qを評価せずに、全体を 0 とする P||Q の場合、P が 0 以外なら、Q を評価せず、全体を 1 とする 1. 効率が良い 2. Q に副作用がある場合は、意味が変わってくる [今回] ! (否定演算子) !P => P が 0 なら 1 で、それ以外は 0 論理表 P | !(P) | (P) == 0 T F(0) F(0) F(0) T(1) T(1) # !P の代わりに P==0 と書いても、同じ結果 # => やっぱり、P が条件式の時は、否定を表すのに !P の方が読みやすい # その一方、P が条件式でない場合は、 P==0 の代わりに !P を使うのは、読みにくくなるのでやめた方がよい == [データ構造] 今まで、プログラム構造 プログラム : 命令を組み合わせて、機能を実現する 組み合わせ方法: 順接/条件分岐/繰り返す A;B; / if 構文, switch 構文 / 再帰, while, for => コード(命令)の組み合わせで、データ(情報)を操作する コードの組み合わせができれば、データの加工の手段も決まる 最終的なゴール : 必要とする情報を得る プログラミングは、その目的とする情報を得るためのコード組み合わせと行う (コードの実行を、データで制御できる) => データの組み合わせで、目的が実現できる可能性がある [利点] プログラム : コードの並びは プログラマしか変更できない プログラミング時には変更可能だが、「実行時には変更できない」 データ: 実行時に決める事ができる(プログラミング時も可能だが..) プログラムの利用者が変更可能 データの方が、柔軟性があって、扱いやすい [観点] プログラムは、データを命令として処理して、 そのデータの組み合わせを命令の組み合わせと解釈する(インタープリター:通訳)物として側面がある => この側面(データを結果を求める処理の対象ではなく、コードを実行するための命令ととらえる)を進めると、柔軟性を増させる可能性がでてくる => C 言語(に限らず、いろいろな言語)が、「万能性を持つ」根拠になっている # 定義「言語 A が万能である」 # 他の任意の言語 B が記述できるプログラムと同じ機能を、言語 A でも実現できる # 例 : C 言語は万能なので、他の言語(python)で記述されたプログラムと同じ結果をもたらす、プログラムが作れる # [証明(概略)] # その言語で、他の言語のインタープリター(他の言語でかかれたプログラムと、その入力データを、ともに二つのデータとして扱い、プログラム部分を解釈して、入力データを処理する)が作れるから.. プログラムを書く上では、プログラムの構造(プログラムそのもの)も 大事だが、データ構造(間接的にプログラムの構造を定めうるもの)も大事 「プログラムをデータを中心に考える」という方針 利点:柔軟性があり、高度な処理可能 欠点:効率が悪い、理解が難しい 定義「データ構造」とは何か 「データの組み合わせ」と、その操作方法の事 複数のデータを一つのデータとしてまとめる役割がある 例: 平面上の点の座標: x 座標(整数型) と y 座標(整数型)の二つの整数型の組み合わせで、実現できる [sample-003.c] 「平面上の『点』」を扱いたい 扱う : 『点』を移動する 平行移動 点対称移動 面対象移動 この「操作」を「プログラムで実現する」というどういう事か 対象(『点』)を表す「データ」を作り、 その「データ」を変更する事によって、実現する [sample-001.c] 「銀行の振込」という『機能』を実現 現実の世界の情報を担う変数(kurino_account)を作り それの数値的な操作 間接的に行っている プログラムが「機能」する 1. プログラムのデータの計算が、現実の情報操作に対応をする プログラムを作る人の仕事 2. データと情報が結びついている プログラムを使う人の仕事 プログラム上のデータは、現実世界の情報を模している必要がある 対応関係の事をコーディングと呼ぶ => プログラマは、うまいコーディングを選択する必要がある 「うまい」 少ない操作/わかりやすい操作で、目的の機能が実現できる 例: 平面上の点 P 直交座標系 (x,y) で表現 => この表現で、表すと都合がよいことが多いから 「平行移動」が簡単に実現できる それぞれの座標の加算で実現できて、加算はコンピュータで、即実現できる 「回転移動」は、行列の掛け算が必要 一方 極座標 「回転移動」は、簡単 しかし、平行移動は簡単じゃない コーディングによって、プログラムの実現難易度が異なる コーディング 現実の情報をデータに対応づける規則 その対応づけるデータの構造の良しあしで、 そのデータ構造を操作するプログラムの難易度が異なってくる => データ構造の重要性