見出し画像

プログラム言語の"超"基本概念

ちょうど、今いる会社でも先輩エンジニア達によって、リモートワーク形式でZoom等を使って新人たちに教育をしている最中ですが、さすがに「あまりパソコン触ったことない」「プログラミング未経験で」という子たちに、教えることが本業ではないエンジニアたちがどこまで教えられるのか、少し心配です。


さて。
そんな新人たちのなかでも、未経験者であればプログラミング言語を「複雑」と思うかもしれません。けれども、プログラミング言語は英語をベースにガッチガチのルールを設け、1/1000くらいに難易度を落としたものなので、「変数の中に入れたいものを入れて、必要なところまで運搬する」という目的さえ忘れなければそれほど難しいものではありません。

だって、プログラム言語の本質は

 コンピュータが理解できるのは"0"と"1"(を操作するアセンブラ言語)
 「コンピュータができること」以上のことは命令できない

という大前提を超えるようなことは決してあり得ないからです。シンプルなことしかできないものを、複雑に組み合わせて、すごいことができるようにしているだけなのです(まぁ、それを紐解くのが面倒なんですけど)。

人間が理解できるように編集されたプログラム言語は、概ね

 可変長繰り返し :while
 固定長繰り返し :for
 条件分岐    :if/else
 連続した条件分岐:switch/case

の4処理によって構成されています(C言語ベースで記載していますが、基本概念はどの言語でも同じ)。

これに、

 関数の呼び出し
 関数処理の復帰

等が加わり、この他、プログラム言語の特性に合わせて

 拡張繰り返し  :for or foreach
 初回実行型可変長繰り返し:do while
 例外分岐    :try/catch/finally
 指定処理転送  :goto

等を考慮に加えればたいていのプログラム構造は把握したも同然となります。実際、単体テスト…と呼ばれるテスト工程では、上記の観点にまつわるものだけしかテストしませんし、これらのテストを実施するだけでプログラム動作の網羅性(カバレッジ)を満たすことが可能になります。

もちろん変数や関数、あるいはクラスのアクセスレベルを理解したり、配列や構造体、コレクションと呼ばれるモノや、あるいはDTO(Data Transfer Object)なども理解する必要はあります。しかしそれらは静的なもので、「処理」「動作」させるために必要な動的概念とはなり得ません。


新人や未経験者であれば、まず知っておくべきは動的な部分…すなわち

 プログラムって要するにどんなことができるの?

と言う部分の把握です。具体的な実現方法はおいおい知っていけばいいことですし、なによりこの基本概念が理解できていないと、たとえば「テスト工程」などで

 どんなテストを行えば品質が保証されるか?

と言う試験仕様書、あるいはチェックリストを作成するポイントで躓くことになります。裏を返せば、テスト不足などで問題を越してしまうエンジニアはこの観点を感覚でしか理解しておらず、理論的な理解が伴っていないことを意味します。

可変長繰り返し :while

while文は「条件を満たすまで延々と繰り返す」と言うモノです。
回数指定が無く、条件が満たされるまで何回でも繰り返すことができます。

画像1

一般的に、while文の記述は次のようになります。
これはどのプログラム言語でも大差はないでしょう。

while (条件式)
{
   // 条件が成立している間は実行が繰り返される部分
}

酷似したもので、do-while文と言うのもあります。こちらは、初回だけブロック内("{}"で囲まれた領域内)の処理を実行し、2回目以降は条件に従う…と言う制御文ですが、利用者が圧倒的に少なく、利用する人がいたりいなかったり、統一感が無く、濫用すると可読性を落としてしまうため、プロジェクトによっては利用禁止しているところもあります。注意してください(ちなみに私は、マイノリティが好きなので比較的利用したくなります)。


固定長繰り返し :for

for文は「指定回数分、繰り返す」と言うモノです。もちろん、作り方次第ではwhileと同じ使い方はできますが、一般的には推奨されません。回数の初期値があって、その回数を数えながら繰り返すことができます。

一般的に、for文の記述は次のようになります。
これはどのプログラム言語でも大差はないでしょう。

for (初期化式; 条件式; 変化式)
{
    // 条件が成立している間は実行が繰り返される部分
}

for文では「インデックス」と呼ばれる、回数を数えるための初期値が設定できます。使う使わないは自由です。条件式は、while文と基本的に同じ機能です。変化式は、初期化式で定義したインデックスに対してどのような変化を与えるかを定義します。もちろん、使う使わないは自由です。

たとえば

for (int i=0; i<3000; i++)
{
   // 条件が成立している間は実行が繰り返される部分
}

となっている場合は、「変数 i を、0から1つずつカウントアップして3000になるまで3000回繰り返す」と言う処理を意味します。別に

int i = 0;
for ( ; i< 3000; )
{
   // 条件が成立している間は実行が繰り返される部分
   i++;
}

と書いても、同じ処理となりますし、

int i = 0;
for ( ; ; )
{
  if (i< 3000) {
    // 条件が成立している間は実行が繰り返される部分
    break;
  }
   i++;
}

とすることも自由です。

int i = 0;
while (i<3000)
{
   // 条件が成立している間は実行が繰り返される部分
   i++;
}

と書いても同じ処理となります。そのあたりはプログラム言語の自由度がそうさせているだけで、私たちエンジニアの目線から見た場合、

 「それぞれの基礎制御文が作られた"目的"を考えた場合、
  どの制御文を用いることが正しい在り方なのか?」

を意識しておく必要があります。一般的に、プログラムは処理行が増えれば増えるほど、性能(処理速度)が劣化する傾向にあります。同じ目的を果たすのであれば、処理行は少ない方がいいのです。用途があるからこそ、こうした制御文が構築されているのですから、用途に応じた使い方を心がけるようにしましょう。


条件分岐    :if/else

for文は「評価式に書かれた条件を満たす場合と、満たさない場合で処理を分岐する」と言うモノです。おそらくは最も使われる基礎制御文ではないでしょうか。

画像2

if分には、一般的に

if (評価式)
{
  // 条件が成立している場合に実行される部分
} else {
  // 条件が成立していない場合に実行される部分
}

と言う書き方をしますが、当然、具体的にelseで実行させたい処理が無い場合は

if (評価式)
{
  // 評価式が成立している場合に実行される部分
}

と書くこともできます。
逆に複数の条件があって複雑に分岐したい場合は

if (条件式A)
{
  // 評価式Aの条件が成立している場合に実行される部分

} elseif (条件式B) {
  // 評価式Bの条件が成立している場合に実行される部分
} else {                      
  // どの評価式の条件も成立していない場合に実行される部分
}

else if句は何個でも連結することができますが、あまりに多いようであれば、不細工すぎて同業者に失笑されることもあります。

そもそも設計時点でこのような不格好なプログラムにしなくてもいいようにするのが鉄則ですが、稀にこうした作り方を余儀なくされることもあるので、覚えておくと良いでしょう。

 
連続した条件分岐:switch/case

switch-case文はその名の通り、スイッチを切り替えるイメージで作成するものです。電気回路のスイッチが人間の言う"ON/OFF"を回路の中では"1/0"と表現するように、数字による分岐しか行わないのが原則です。

一般に「多方向分岐」と表現されることが多く、if文とほぼ同じ分岐処理のように見えますが、その実はまったく違います。switch文の正式な機能は「条件を満たしたところから開始する」です(点線は、break句がある場合の処理です)。

画像3

if文のように「分岐」するのではなく、処理の「開始点」を指定するものでしかありません。if文のように分岐させて、特定の処理だけを実施したいのであれば、かならず break句を添えなければなりません。つまり、『if文と同じことができる』と言うだけで、『if文と同じ機能ではない』と言うことを理解しておいてください。

オブジェクト指向言語などではあまり使われることの無い制御文ですが、2進数や信号を取り扱うC言語中心のプログラムでは、利用機会もあると思います。


最後に

プログラムの処理は、各種の基礎演算子(算術演算、比較演算、代入演算、シフト演算、等)の他、while、for、if/else、switch/case、この4つの基礎制御文の組合せによって複雑な制御が可能になっています。

裏を返せば、これらにできることの本質をしっかり押さえておけば、コンピューターにできることであれば、大抵のことができるということでもあります。

ものすごく便利なライブラリも、標準関数たちも、その中を解いていけば、これらの基礎演算子と基礎制御文の組合せでできています。ライブラリ群や標準関数たちは「基礎を応用した」ただのショートカットと言ってもいいかも知れません。

それだけにこの基礎をきちんと理解し、自分のモノにすることが、「プログラミングを極めるうえでとても重要になってきます。


また、プログラミングを仕事にする人向けに言っておくと、各プログラム言語には、記述するための最低限覚えるべき書式はありますが、具体的な書き方は自由です。そのため、一般的にはプロジェクトごとに

 「コーディング規約」/「コーディングルール」
 「命名規則」/「ネーミングルール」

等を作ってチーム内で統一を図ろうとします。複数人で1つのものを開発する時は、このルールが無いととんでもなくカオスな状況に陥りかねません。そうですね…イメージするなら

日本全国47都道府県から方言のクセが強い人を1名ずつ選りすぐって47名のチームを作った状態でコミュニケーションを取るための橋渡しをしなさい

と言われているようなものだと考えてみてください。眩暈がしそうでしょ?

ルールが定義されている場合は、必ずルールに従うようにしてください。一般に、ルールすら設けない集団や地域を『無法集団』『無法地帯』と呼び、ルールがあるにもかかわらず遵守しない集団を『違反者』と呼びます。

コンプライアンスは「法令順守」と訳しますが、

 狭義では「法令(法律や条令)」
 広義では「ルール(決め事、約束事)」

のことを指します。すなわち定められたルールがあり、ルールを守ることを求められているにも拘らず、そのルールに従わないことも、

 コンプライアンス違反

と呼ぶことになると言う点を肝に銘じておきましょう。

いただいたサポートは、全額本noteへの執筆…記載活動、およびそのための情報収集活動に使わせていただきます。