先日は
にて演算子について書きました。
読み飛ばし
まず、入力時に極当たり前に発生するものとしては、
■ スペースキー
■ TABキー
を文字配列のデータの入力時に押した時に生じる 【 読み飛ばし 】 があります。
例えば、Hello,Wold!だと、文字列がつながっているので、問題なくバッファできるのでENTERキーを押した後に入力した文字列が表示されますが、これが、 【 Hello World! 】 になると、Helloの部分で表示が終了してしまいます。
改行文字の影響
printfでは、字列で改行を指定する 【 改行文字 】 が使用できます。改行文字は、
■ 改行文字 :\n (WINDOWSでは¥n)
を使用しますが、文字配列で文字数を担保した場合だといいのですが、char型で1文字のみを取得する 【 文字型 】 で変数を宣言して、表示を行うprintf()関数側で改行を入れると文字が弾かれて次の入力が発生して、そこで文字の入力が完結するような処理になってしまうことがあります。1文字の入力でもだと scanf("%c", &chr1); で対応できそうですが、改行がい入る場合には、これだとおかしな挙動になるので、 scanf("%*c%c", &chr1); に書き換える必要がでてきます。
入力異常による影響
これは、他の言語だとエラー対策としてコードを書く内容になりますが、C言語の場合、エラーがでずにコードが実行されるので、方が違うデータの入力がされて値が出ると言う状態がjは発生します。Pythonだと、int型に固定されている処理についてはstr型だとエラーになるので、input()関数で入力した変数を演算に用いるとエラーがでますが、C言語の場合、intで指定したものであっても、キー入力したものはそのまま受け付けるので、文字列の入力ができてしまい、その後に0が帰ってきます。
これは、特性と考えて他の言語と同様に文字列の判定を実装しておかしな値を使用できないようなコードにしておく必要があります。
バッファーオーバーラン
この言葉は、セキュリティー関連でみかけるものだと思いますが、C言語でscanf()関数を使った場合でも注意する必要があります。
バッファーのオーバーランとは
■ バッファオーバーラン
メモリ上に確保した領域よりも大きなデータが渡されているのに、
それを見逃して領域からデータがあふれてしまう状態
になります。
C言語では 【 NULL文字 (\0) 】 が見つかるまで文字を出力し続けるようになっているので、文字配列で指定した文字数よりも大きなデータを入力してもそれが反映されて表示されます。
当然、これは、正常な挙動ではありませんし、あふれたデータがバッファに残って後で不具合を起こす可能性もあるので注意が必要です。
その為、この特性を踏まえた上で、コード内で影響がでないような処理を実装することになります。
C言語では、メモリーの初期化と開放をして管理をするような扱い方をするので、コード内でそれを行うような状態になっている(Pythonとかだとガーベージコレクションがあるので、これを実行するようなコードを書くとメモリー内のデータの消去が出来ます。基本的に自動管理をしていますが、コードで消去することもで可能です。)のですが、バッファがあふれることもあるので、そうした事も織り込んだ上でコー度を書く必要があります。
簡素なコードだと影響がでないので、scanf()関数を試す程度だと影響が出ることはありませんが、アプリケーションを作る場合には注意が必要になります。
データ参照
scanf()関数は、コマンドラインでの入力した文字列をバッファに貯めて使用するようなものになっていましたが、
■ コード内のデータ
■ 外部ファイルのデータ
のように既に確定したデータを参照して使用するものも存在します。この時にsscanf()を使うことになります。これは、open()などと併用すると利用範囲が広がりますが、Pythonで入力のパフォーマンスを考える時にコンソールではなく別の入力方法が使用されていることがありますが、その場合の読み込みがこの 【 データの読み込み 】 になります。
これも入力なので、標準入力なども使用できますが、C言語ではsscanf()関数が用意されています。これもstdio.hの中に収録されているので、別途何かを読み込むこともなく使用することが出来ます。
プログラング言語を使用して処理を実装する際には、
■ 代入
■ 計算
■ 比較
などが発生します。プログラミング言語を使用すると序盤から変数が登場するので必然的に代入を使用することになります。
代入
代入は、中学校の数学では極当たり前に使用するものになりますが、この概念は小学校6年生の算数で登場します。
■ リンゴが5個
■ バナナゴが3個
■ イチゴが2個
ある場合にこの合計を出す場合、どうすればいいのか?を考えるような問題として登場し、その考え方を扱う時に代入の概念月状します。この場合、
■ ×5
■ ×3
■ ×2
このカリキュラムでは、
【 問 】
かごの中にりんごが5個、バナナが3個、イチゴが2個あります。
これを全部足した時の数はいくつになりますか?
のような文章題の形で登場します。この場合、
状態を分けて考えるので、先程のじような形になりましが、頭文字を使って
■ リ×5
■ バ×3
■ イ×2
のようにして考えて計算をすることになります。この考え方は、
■ 変数
■ 処理
の仕組みなので、この3つの果物は、個別の値を格納した変数と考えることが出来るのですが、処理としては、
■ 3つの変数の宣言
■ 値の代入
■ 3つの変数の加算処理
で成立しています。その為、この条件で考える場合、それぞれの値を個別のものに紐付けをして考えることになります。
これ、対象の頭文字に対して値を紐付けることになりますが、先程のような数式式ではなく 【 等式 】 に置き換えて考えると、
■ リ×5
■ バ×3
■ イ×2
のようになります。この時に 【 リに対して5を当てはめている 】 ので 【 代入している 】 のと同じ状態になります。
その為、式と解の間に等号を置くと一致の判定を示しているものになりますが、この状態で考えると 【 代入をしている 】 状態になります。プログラミング言語では、この
【 対象物 】 = 【 値 】
の形で宣言しますが、プログラミング言語では、使用するデータを変数名を使って管理するので、
【 変数名 】 = 【 値 】
と言う形で指定します。C言語のばあいだと、型を指定することで容量の指定も行うので、
型名 変数名=値
のような形になっていますが、ここで使用されている 【 = 】 のことを 【 代入演算子(代入演算子) 】 といいます。
■ 代入演算子 : 【 = 】
その為、数式で使用する等号とプログラミング言語で使用する=は異なるので注意有為が必要です。
プログラミング言語では、
■ 代入演算子 : 【 = 】
■ 等号 : 【 == 】
となっているので、変数の初期化をする際の
int a=1
のような記述の際に使用するのが代入演算子で、ifなどを使って判定をする時に 【 一致 】 を示す時に使用するのが等号になります。
のようなコードになりますが、
のようにコンパイルして実行すると
のように計算結果を得ることが出来ます。この時の
の部分が先程のの数の指定の部分いなります。このアルファベットでの表記ですが、これは中学校1年生のの数学の項のカリキュラムで登場するものになりますが、中学校以降の数学では、 【 値を自由に代入できる箱のようなもの 】 を用いて、 【 変化のあるものを扱える数式 】 を構築する方法を学びますが、これを使うと、小学校高学年で登場する
■ 数列
■ 比例
の法則性をを
■ 数列 : 一般項
■ 比例 : 変数xの関数
のように 【 式 】 の形で示すことができるようになります。
のようにして、
のよにコンパイルをして実行すると
のようになりますが、C言語の場合、
のように表示をする際にも 【 変数の代入 】 が発生するので代入を頻繁に使用することになります。
これは、Pythonだとformatメソッドを使った時の記述に似ているのですが、表示をする際にはこのような表記になります。
計算
コンピューターの始まりは、計算機になります。計算機が登場する前には、計算師という計算をする人を使うと並列処理をしても膨大な念残には対応できず、ヒューマンエラーが出るので、これを解消するために 【 自動計算機 】 が考案され使用されるようになります。歯車で動くシステムから、電気を使ったものに変わりますが、
のような形で動くものを電磁石を使用して再現することで動作するリレー式や真空管などを使ったものも登場しますが、その後、アナログ回路を組めるようになると速度も向上していきます。コンピューターの発展の中で 【 アナログシンセのパッチのような方法で処理をするもの 】 も存在していましたが、ノイマン型以降はそうしたものはなくなります、アナログ回路は巨大になる特性があったのですが、これを小型化出来るような集積技術の登場によってコンパクトなサイズになり、電卓のサイズもビジネス用の机を筐体とした自作PCのような物々しいサイズ(電卓の卓は、卓上の意味ではなく卓そのものを指している状態)ものから、卓上で使える電卓に変わっていきます。これが計算機の進化ですが、コンピューターではプログラムを用意して実行できるので判定なども存在していますから、電卓とは少し違っているわけですが、コンピューターの始まりは自動計機なので、計算を行う機材になっています。その計算を様々なものに適応することで複雑な処理を行っているわけですが、処理を行う差異には計算を用いることになります。
日本の義務教育では、小学校低学年で四則演算を学習して桁にも対応できるようになっていますが、分数と少数点数も低学年の間に理解をするようなカリキュラムになっています。その為、小学校4年生になると、3年生の学習内容が理解が出来ていることが前提でカリキュラムが進みますから、この段階で、
■ 四則演算
■ 少数点数
■ 桁の変化
■ 分数
■ 筆算の使い方
を理解した状態になっていると思います。その為、コンピューターで四則演算を使用するとしても算数で登場したものをそのまま使うだけですから、それほど難しくない作業になると思います。
小学校だとコーディングをする機械は少ないかも知れませんが、Scratchを使うことになると思いますが、この時に、
■ 増える : 足し算
■ 減 る : 引き算
と言う処理を使用すると座標の制御ができますが、 【 条件に応じて計算を用いることになる 】 ので、コードを書く際には計算で使用する演算子を用いることになります。
計算をする場合には、数式を作ればいいのですが、C言語では、
■ 四則演算
■ 剰余(割り算の余り)
■ + : 加算(足し算)
■ ー : 減算(引き算)
■ * : 乗算(掛け算)
■ / : 除算(割り算)
■ % : 剰余(割り算の余り)
■ 乗除算演算子
■ * : 乗算(掛け算)
■ / : 除算(割り算)
■ % : 剰余(割り算の余り)
■ 加減算演算子
■ + : 加算(足し算)
■ ー : 減算(引き算)
に分けることが出来ますが、算数の計算と同じように乗除算が先に行われ、その後に加減算が行われる仕組みになっています。乗除算が先に行われるのでその計算結果で発生する剰余も優先順位が高く、加減算よりも先に処理が行われるようになっています。
■ + : a+b
■ ー : a-b
■ * : a*b
■ / : a/b
■ % : a%b
比較
■ 範囲の指定
■ 大きさの比較
■ 大なり : a<b
■ 以上 : a≦b
■ 以下 : a≧b
■ 小なり : a>b
■ 比較演算子
■ イコール : a==b
■ ノットイコール : a!=b
■ 大なり : a<b
■ 以上 : a<=b
■ 以下 : a>=b
■ 小なり : a>b
のような記述になっています。イコールは等号になりますが、aとbが異なる場合も存在するので、これを示す時に数学では、ノットイコール(≠)の記号を用います。プログラミング言語では、この判定をする際に 【 != 】 を用いることになります。
プログラミング言語では、演算子を用いて処理を行いますが、基本的にこの 【 演算子 】 についてはどのプログラミング言語でも記述は同じなので、一度覚えるとそのまま使用することが出来ます。
処理について
プログラミング言語を学習すると、
■ 順次
■ 反復
■ 分岐
を使用することを学習雨しますが、順番に工程通りに処理をする方法を順次と言います。この構造は直列回路にモジュールを配置した構造と同じなので、回路を組んだ場合には、処理が順番に行われるようになっています。この構造は、マインクラフトのレッドストーン回路でも同じですが、工程通りに何かを作る場合や、予定表通りに物事を行うのもこれと同じになります。
この状態は加算処理と同じなので、処理を追加する構造になっていますが、小学校2年生の算数で
【 同じ数を複数回足す場合には掛け算をすればいい 】
ということを学習雨します。この構造は足し算の反復になるので、この構造がループ処理の基本構造になりますが、処理を行う場合でも、同じ処理を繰り返す場合が発生します。この際にループ処理を実装することで、記述を簡素にすることが出来ます。
この構造だと一度だけの処理を繰り返せるようになるので、通電が発生した後に処理が切れるような回路(パルスで一度だけ動くようなイメージ)のものが閉回路で繰り返して実行されるような状態にすることができる(これは、タイマー回路などで実装された処理が繰り返されている状態)になりますが、この構造物は直列回路なので、回路内に実装されたものを実行することしか出来ません。これを同時進行にする場合、同じモジュールを併設することになりますが、これがクラスター処理になります。
そして、これとは別に回路内で同じように同時進行をする場合には並列回路を作ることになりますが、これを行うことで閉回路内でふくすの処理を同時進行することが出来るようになります。これもクラスター処理と同じ考え方になりますが、中学校の物理で登場する直列回路と並列回路については、こうした違いがあります。
直列回路と並列回路では【 同時に実行する 】事は出来ても 【 切り替えて使う 】 ことが出来ません。つまり、複数の回路を作ってスイッチで実行する対象物を指定するようなことが出来ない使用になっています。
このスイッチを使用して切り替える際にリレーのような役割をするものを用意することになりますが、プログラミング言語でこのリレーのような切替器の役割をするのが分岐の役割になります。この場合、並列回路のように複数の回路が合って、その分岐部分に切替器があるような状態になっているわけですが、プログラミング言語で使用する分岐では、 【 条件による判定 】 で動く使用になっています。その為、条件分岐とも言いますが、これを用いることで、定数で指定した処理で動くものではなく、 【 条件で挙動を制御できる構造物 】 を作ることが出来るようになります。
ちなみに、マイクラのレッドストーン回路のような二値論理を使ったものの場合、論理ゲートを使用した処理で判定を実装することになりますが、複数の入力の組み合わせがどうなっているのか?で判定を作って処理の実行条件を作ることになります。これがブール値を使った時の考え方になりますが、マインクラフトの場合、信号強度が使えるので、ブロックの出す信号強度を取得すれば十六進数の1桁分の値を取得できます。ブロックごとにこの中の特定の範囲までの数値が出力されるので、この信号をコンパレーターで取得すると距離の情報に変換できるので、これをマルチプレクサーで取得して数値を得たり、コンパレーターで判定を入れることで数値の条件を構築することが出来るようになっています。
これがブール値と数値での判定ですが、プログラミング言語でも 【 比較 】 を行うことで判定を用意できるので、【 目的としている状態 】 を用意しておいて現状と比較することで一致と不一致の判断が出来る用意なっています。Pythonではこの判定を行う際にifを使用しますが、C言語でもifを使用することでその判定を行うことが出来るようになっています。
分岐を使う場合には、
if (条件式) 文 ;
で判定をこおなうことが出来ます。C言語では、条件式に変数を入れておくとその値で判定を行うことが出来ますが、この際の処理はブール値なので、
■ True
■ False
での判定になります。ブール代数と同じように1と0と考えることも出来ますが、変数を用意して変数の値と一致するような条件を用意する場合、 【 - 】 で数値を減算します。この方法で判定が出来るのですが、変数aの値が5出会った場合にTrueになって処理が実行されるような条件だと、if()の引数の中に入るのは、a - 10 になります。
流石に、これだと覚えにくいので他の言語と同じような 【 等号の表記 】 を使用することもできるようになっています。
等号の表記
小学校1年制の算数でも等式は登場するので、
■ 足し算の式
■ 計算結果
が同じ場合、 【 式 】 = 【 解 】 のような形で 【 等式 】 を作り、右辺と左辺が同じことを示す状態のものを扱いますが、この時に使用するのは 【 = 】 になります。
幼少期のプログラミングでコードを書かかないものを使う理由は 【 タイピングで差が出てしまう 】 のもありますが、算数の理解の阻害になる要素を排除しているというのもあります。
ちなみに、プログラミング言語の場合だと 【 = 】 は代入演算子なので、 【 値の代入 】 で使用するものになります。このあたりの考え方を義務教育と関連付けて行う場合には、小学校高学年以降のカリキュラムで登場するものになりますから代入の意味合いも学んでいないと理解しづらいと思います。
現在の小学校のカリキュラムだと 【 変数と代入 】 のような考え方が算数の中に含まれているので、このカリキュラムで行っている内容をそのまま使えるようになっていますが、この段階では変数は出てきませんから、Scratchのように文字列で指定できるものを扱うような方法だと代入先と数値の関係性を算数と関連付けて扱うことが出来るようになっています。
このようにプログラミング言語では、 【 = 】 は代入演算子になっていますが、実際に行う 【 比較 】 の意味での 【 等号 】 はどのような表記になっているのかと言うと、比較演算子をしようすることになっているので、 【 == 】 のように=が2つ並ぶ形になっています。演算子はほとんどのプログラミング言語で共通しているので、プログラミング言語を学習すると他の言語でも同じように使用されているので、この部分の違いがあるかの確認と動作の際の確認をするだけで対応できるようになりますが、Pythonでも等号は==なので、このあたりも共通しています。
比較については、 【 範囲 】 で行うものなので、不等号を使って判定をしますが、この処理の方法は小学校高学年で登場します。これを座標平面上に表示した図形として扱う方法を中学校の数学で学習しますが、この上限と下限の範囲指定に関数を使う方法を高校の数学で学習します。この範囲はデータの条件抽出なので、連立不等式も処理も集合演算を数式を使って行っている状態になりますが、その時にデータの状態の表記をグラフを使って行うことになります。この時にデータの総数はハニの形が複雑になるとどうやって計算すればいいのわからなくなりますが、図形に置き換えるとこれが 【 面積 】 であることが解ります。この時の面積を出すにしても三角関数が混ざるだけでどうやって面積を出せばいいの解らなくなりますが、このような関数で範囲指定をした時のデータの範囲を簡単に計算する時に使用するのが 【 積分 】 になります。
中学校の算数のカリキュラムは、
■ 連立不等式
■ 積分の要素がグラフで作れる
■ ス関数の組み合わせで図形を作れる
ということの基礎部分に触れている状態になっているわけですが、カリキュラムの中で算出している
■ 面積
■ 体積
は多次元化した空間の中に存在するデータの範囲選択とそのデータの総数になります。なので、その変域の指定方法と算出方法を扱えるようにするためのものがカリキュラムとして用意されています。
プログラミング言語の場合、
■ 代入演算子 : =
■ 比較演算子 : =
のような扱いになっているので、これを使い分けることになります。その為、
a=1
の場合、代入なので、変数aに1を代入すると言う表記になり
a==1
の場合、変数aの値と1が一致する条件を示したものになります。
一致と不一致
前述のように一致をする場合には数学と同じように等号を使えばいいのですが、条件によっては、【 ≠ 】 のようにその値ではない条件も存在します。この場合、幾何を使う場合だと、論理ゲートでNOT回路を挟むとその条件を除去できるのですが、コードで書く場合には、等号とは逆の動きをする記述を用いることになります。この判定ですが、
■ イコール : a==b
■ ノットイコール : a!=b
を使い分けることになります。
演算子
条件分岐を実装する時にifを使用しますが、この際に演算子を使った判定を行います。その場合、
■ 判定用の値
■ 対象の値
の2つを用意してその比較をすることになりますから、この時の比較の結果がどうなっているのか?を扱う際に演算子を用いることになります。
この比較については、前述のように小学校で登場した 【 不等号 】 での判定になりますから
■ 大なり : a<b
■ 以上 : a≦b
■ 以下 : a≧b
■ 小なり : a>b
の判定を行うことになります。プログラミング言語では、この判定を比較演算子で行いますが、判定は全く一緒なので、
■ 比較演算子
■ 大なり : a<b
■ 以上 : a<=b
■ 以下 : a>=b
■ 小なり : a>b
のような表記になります。比較演算子は 【 不等号が先にくる 】 と覚えておくと使用する時に間違わずに済みます。