前回の内容 scanf scanf with format cf. printf : print with format 書式付きの出力 書式付きの入力 printf/scanf : 書式という共通性 / I/O (入力/出力) printf : すごくやくにたつし、ぜひ、常用してほしい sacnf : printf と同じくらい、強力だが、 色々ときをつける事があって、扱いが難しい => つかうなら限定した形でなれ なれてきたら、色々な機能を利用してほしい ! 失敗の影響力が違う ! => printf の失敗して、表示がおかしくなるだけ ! scanf の失敗 ! 入力なので、この後のプログラムの振る舞いに影響 ! (「ポインター」を扱うので、影響の仕方が特殊) scanf ( 書式, 入力するデータを保存する変数の指定 ) while 構文 形式: while ( 条件式 ) { 繰り返す命令 } 意味: 「条件式」が成立(真である)している間、「繰り返す命令」を繰り返す 流れ: まず、条件をチェック、 偽であれば、それでなにもしない 真であれば、「繰り返す命令」を実行する その後にまた、条件をチェックする 以下、上と同様 !! 条件のチェック回数は、実行回数 + 1 条件を毎回チェックするが、 条件の内容が変化していなければ、 一度もやらない ( いきなり偽 ) か、 無限に繰り返す ( 最初に真で、その後も真のまま ) 普通は、 条件式の中に、変数を含め、 「繰り返す命令」の中で、 その変数の値が(いつかは..)変化するようにする N 回繰り返すというイデオム int v; v = 0; while ( v < N ) { 繰り返す命令 <= N 回数繰り返される v = v + 1; } v = 1; while ( v <= N ) { 繰り返す命令 <= N 回数繰り返される v = v + 1; } cf. 概論 A では、再帰呼び出しを利用して繰り返しを実現 while 構文 : 効率が良い <= 原理から、「代入文」が不可欠 コマンドライン引数 main 関数 ( 概論 A は、void : 引数なし.. ) 実は、(いくつか..) 引数をもっている 最初の二つ int argc; コマンドライン引数の個数 + 1 char *argv[]; コマンドライン引数の文字列そのもの => この表現の意味は、後日説明 導入の段階では、使い方だけ コマンドライン引数 コマンドを実行する時に、実行ファイル名の後に指定する文字列 コマンドライン引数は空白文字で区切られている (間に空白文字[列]をおいて) 複数指定できる 例: ./p-005.exe abc 12345 @@@ ^^^^^^^^^^^ ^^^ ^^^^^ ^^^ 1 2 3 実行ファイル名 argc -> 4 argv[1] -> "abc" argv[2] -> "12345" argv[3] -> "@@@" argv[0] -> "./p-005.exe" (実行した命令) => データを入力する時に、 (scanf / getchar() 等の) 入力関数を用いて.. 入力してもよいが、 最初から、コマンドライン引数で、データを入力するというアプローチが便利 多用する.. 課題状況 2021/10/08 20211008-01 20211008-02 2021/10/01 20211001-01 済 20211002-02 <= ファイル I/O 2021/09/24 20210924-01 済 20210924-02 済 20210924-03 <= ファイル I/O 2021/09/17 20210917-01 済 20210917-02 済 20210917-03 済 20210917-04 == 数学の問題を解く ( 関数の値を求める ) 例: 関数 f(x) が f(x)=x^2 定積分 : f(x) の [0,2] の間、積分した結果を求める 解析的に解く 不定積分 F(x) を求める、 f(x) = x^2 F(x) = (1/3)x^3 + C ( C は積分定数 ) F(2)-F(0) = (1/3) [ 2^3 - 0^3 ] = 8/3 数学科が数学で学ぶのはこちら => 答えが正確にもとめられる ( よい方法.. ) <= この方法は、不定積分関数を求めることができないとダメ 不定積分関数が不明な場合 例 : 統計学で利用するガウス分布 e^(x^2) 数値的に解く 工学の学科の人が学ぶ方法 不定積分が直接(数学的に..)できない場合も、 近似値を計算する事ができる 誤差を含むけれど、応用範囲が広い 二分法 連続関数の中間値の定理 関数 f(x) が、区間 [a,b] で連続とし、 値 y0 f(a) < y0 < f(b) : y0 が中間(f(a)とf(b))の値 => ある c ( a < c < b ) があり f(c) = y0 なる | / y0|-* |/| +--------- a c b 二分法 f(x) が区間 [a,b] 連続とし、 y0 が区間 [f(a),f(b)] の中にある このとき、 f(c) = y0 となる c を [a,b] の中から探したい !! 中間値の定理からこのような c の存在が保証されている !! これから、答えを「探す」 !! 「探す」時に、「答えが『有る』という保証」がないと困っちゃう !! => 「困っちゃう」=もし、なかったら、いつまでたっても、終わらない !! x,y,z が整数 n > 2 整数の時に !! x^n + y^n = z^n !! となる x,y,z,n の組は存在しない !! 証明されるまえは、 !! このような組が存在するかもしれない !! プログラムで、しらみつぶしを試す !! => 結果的に終わらない !! 探すプログラムを作る時には、 !! 答えがある事が保証されていないと、 !! プログラムが終了しない時にこまる !! => 答えの「存在の証明」が不可欠 !! => 「存在証明」は数学でしかできない 二分法 0. m =(a+b)/2 1. [a,b] が十分に狭い場合 ( ε以下 ) には、 答えとして、m を近似値とする 2. f(m) を計算する 3. もし、 f(m) y0 | / y0 | / | / | / +--------------- a m b f(m) > y0 => [a,b] ではなく、[a,m] の間にある f(m) < y0 => [a,b] ではなく、[m,b] に間にある もともとの区間に対し、 その半分の区間を考え、 答えが、その二つの区間のどちらか一方にある ということを調べ、 答えのある範囲を狭めてゆく => 二分法 二分法を利用すると、 (少なくても一つの答えが含まれている区間がわかりさえすれば..) 連続関数の 0 点の答えを数値計算でもとめる事ができ 要求される条件 その関数がその区間で連続である 例: 5 次以上の代数方程式は、公式が存在しない 一般的は解析的には解けない 数値計算(二分法をつかえば..)を使えば、 このような場合でも、近似値が求められる