へっぽこびんぼう野郎のnewbie日記

けろけーろ(´・ω・`)! #vZkt8fc6J

『数学が得意だけどプログラミングは初心者』な人に送る、あんまり勉強しなくてもプログラミング(OOP限定)がわかる文法の考え方とかのTips全部入り【前半】

はじめに

高校数学わかる程度の数学知識を前提として書いています。
一部『知らねーよこんなの!』というものがあるかもしれませんが、知ってください。

前から順番に読んでいただくことを想定しているので、
自由奔放な読み方をするとイミフな箇所が発生するかもしれません。
あらかじめご了承ください。

シロートが書いた文章なので、間違っている箇所があるかもしれません!!
これ違うだろバカというものがあったらコメントをいただけると助かります。

コードはあくまで説明用なので、モジュール読み込んでないなどで、そのまま動かないものも多いハズです。スペルミス等に関しては大至急直しますのでもし見つけてくださったら報告していただければ嬉しいです。

この文章の読み方

  • まずザッと流して読みます
  • もう1度、今度はじっくり読みます
  • さらにもう1度じっくり読みます
  • 最後にサラッと見直します

説明するときに使った言語

Python, C#, Java, Perl, VB.net, JavaScript

ビット(bit)

1ビットは、2進数表記の1桁
2ビットは、2進数表記の2桁
8ビットは、2進数表記の8桁。*1

歴史的に8ビットを1バイトと呼びます(2^3だから便利だったんだろう)*2
Nビットのことをbase Nとか呼んだりします。(baseは基数とも言います。log[2](3)の2です。同じ意味ですね)

例えば64ビットはbase64と言ったりして、主にデータを64種類の記号だけ用いて送る際などに用いられます。

OOPオブジェクト指向プログラミング)について

オブジェクト指向プログラミングの説明によくある、『現実のものと対応させる』という考え方を、死ぬほどよく見かけましたが、
最初あれは僕にとっては具体的すぎて意味不明でした。

オブジェクト指向プログラミングというものは、
『色んな種類の値を集めて1つの塊として扱う』と考えた方が良いですし、そちらの方が根幹に近いです。
この1つの塊をオブジェクトと呼んで使います。

オブジェクトは、現実世界では不可能なこともできるので、1対1に対応していません*3

オブジェクトの作り方の例を適当に挙げてみます。

たとえば色を表現したいとき、『赤色の度合・緑色の度合・青色の度合』をそれぞれ決めてあげれば、任意の色を作ることができるので、
Color を Red, Green, Blueの3つの値を使って表すとかいった具合にオブジェクトを作れるよということです。


たとえば、画像を表現したいときには、画像は『x座標・y座標・色』がたくさん集まったもの、と表現することができます(本当はもっと細かいですが……)
具体的な例を挙げるとと、(x, y, c) = (0, 0, Red), (0, 1, Blue), (1, 0, Green), (1, 1, Red)であれば


※原点は左下のとしています。

のように画像を表現できました。
実際の画像はこれがいっぱい集まったものです。
*4


で、まぁ、『こうやってオブジェクトにしていくのって、便利じゃね? だから使おう』というのがOOPの発祥です。オナカピーピーのOPPではありません。

変数 (variable)

【=】は、『x = 2とおく』と宣言するようなノリです。定義です。
【x = x + 2】は『xを、以前のxと2で足したものとおく』というノリです
この宣言をすることで、データを(主に)PC上のメモリに保存し、あとで気軽に読み出せるようにします。

(メモリのことを知らない人は、『メモリはハードディスクの読み込む速度が速い版(ただし電源切るとデータ吹っ飛ぶ)』と認識すれば良さげです。)

「厳密にはイコールじゃないし、けしからん記号の使い方しやがって」という野暮なことは言わないでおくべきです。
アルゴリズム的には『x ← 2』と表すようなので、イコールが気に食わない人はそのように脳内補完するか、自分で言語を作ってください。

その言語にもともと入っている【型 (Type)】

型は、『有理数の空間』だの『実数空間』だの『無理数空間』だの『線形空間』を定義しているようなノリです。
きっと、英語のTypeの方が意味がわかりやすいかもしれません。

線形空間非線形なもの入れたら怒られるので、入れたい場合は変換しよう』*5
有理数空間に無理数入れたら怒られるので、入れたい場合は無理数を途中で切り取って有理数にしてしまおう』という感じです。

『ありとあらゆる全ての空間』が、object型というやつに相当します。これに関しては後述するつもりです。


型の種類について
int -> integer(整数)(32bitであることが多い【※2^32通りの数を表現することができるということです】)
long -> integerのデカい版(64bitであることが多い)

float -> 小数(32bitで(ry
double -> 小数のデカい版(64bitで(ry

char -> character (文字)(32bitで(ry 【詳しくは文字コードについてで後述します】
string -> 文字列。charが1つ以上集まったもの

bool [boolean] -> ブール型(ブール代数のやつ)1か0しか入らない、スイッチのようなもの。TrueとFalseでしか表せない言語もある。*6

その言語にもともと入っていることをbuilt inと言います。
基本的にこれらの型は大体の言語に入っています。

型は、たとえpythonRubyJavaScriptだけしかやらなくても、知らないと『???』となるときが来るので、知るべきです。

型は他にも色々あるし、別に数値以外でも作れる

線形空間』のように、ベクトルしか入らない空間を作ることができます。
たとえば2次元ベクトルは、2つの値で表すことができます。【(x, y)のように】
したがって、

class Vector {
int x;
int y;
}

Java。また、classについては後述します。

とすれば『ベクトル型』というものを作ることができます。


例えば、C#にDate型というのが元々用意されていたりして、その名の通り日付が入る型なので、これを使って日付に関する操作をしたりします。
『画像型』というものを作って、jpgファイルなどをいじることももちろん可能です。
多くの『型』が、様々な人によって作られているので、それを使うと、いちいち自分で作らなくてよくて楽です。

配列(Array)

いわゆる数列です。

項番号が0から始まる言語が多いです。
0から始まる理由はPCが0,1,10,11,...と数え上げていくことに所以があるっぽい感じです(詳しくは知らないのでおざなりに流してください)

0番目と言われるとキモチワルイかもしれませんが、a[0]から始まる数列もありますし、a[0]から始まる数列なんだな程度のノリで理解したほうが良さげです。

この配列の要素数(『数列の項数』に相当します)は、
Pythonではlen(array)
C#ではarray.Length
Javaではarray.length
のように得ることができます。かなり重要です。

式と文 (expression and statement)

式とは、値があります。
文は、何か操作するときに使います。
x = 2は、代入文です。x, 2はそれぞれ式です。
x + 3は、x + 3もxも3も式です。ただし言語によってはx+3を評価して出力することもあるので、この場合は式文と言えるかもしれません。

基本的にプログラミングは、機械に式がどのような値なのか評価させ、それによって操作方法を変化させ続けていくというものだと、僕は勝手に思ってます。

ただ厳密に言うと実際ぼくもよくわかってないです。誰かおしえて。

if文(if statement)

その名の通り『もし〜できるなら…する』という文を書く為のものです。英語より遥かに簡単で、仮定法などはありません。

if x == 2:
print x

Python

のように書きます。printは、出力するという意味です。『どこに出力するんだ!』などについて、詳しくは後述します。

ただし、次のように評価時にイコールが2つ無い言語もあるので、注意が必要です。
このx = 2は代入文ではありません。Console.Write()も出力するという意味です。C#にも同じものがあります。

If x = 2 Then
Console.Write(x)
End if

VB.net

else文

『もし〜できるなら…するけどそうでないなら××する』という文を書く為のものです。

if (x == 2) {
System.out.print(x);
} else {
System.out.print("2じゃない");
}

Java

elif, elsif, else if 文

『もし〜できるなら…するけど、それじゃなくてピヨヨーンなら△△する』という文を書く為のものです。

if x == 2:
print x
elif x > 2:
print "%dより大きい" % x

Python

if ($x == 2) {
print "$x";
} elsif (x > 2) {
print "$xより大きい";
}

Perl

if (x == 2) {
alert(x);
} else if (x > 2) {
alert(x+"より大きい");
}

JavaScript

for文

クソ重要です。

繰り返しの操作をするときに使います。

for文は、ΣやΠなど、総和や直積を求めるときなど、主に数列の特定の範囲を演算するときに使います。
例えば、自然数、1から10までの総和は

sumNumber = Σ[1→10] (k)

と表現できますが、for文はまさにこれです。
最初のsumNumberは、足してるときに足してる途中のデータを保存するところがないと困るので定義(宣言)しているだけで、他に特に意味はありません。

sumNumber = 0;
for (int k = 1; k <= 10; i++) {
sumNumber = sumNumber + k;
}


Java

プログラミング初学者が一番最初につまづく点がここらしく、特に

for (int k = 0; k < 10; k++) {}

の部分が、混乱を招く原因となっています。
ただし植木算や、離散数学をやった人は特に困ることはないでしょう。


たとえば、ひとくちに『3から7まで』と言っても、さまざまな捉え方があり、『7を含めるのか、含めないのか』で随分話が違ってきます。
『3月1日から7月31日までは何ヶ月間あるでしょう』という問題の答えは『5ヶ月間』ですが、これをパシッと答えられる人はセンスがあります。

『引き算』をすると、『引かれたもの(この場合では3月全体)が消え去る』と考えると、納得いきやすいでしょう。
『7月まで - 3月まで』をすると、7月までから1月と2月だけでなく、3月全ても同時に消えます。だから、4,5,6,7月しか残りません。
3月1日からということは、当然3月分も含めるのだから、3月分は消してはいけないのです。

たとえば、『今日は水曜日です。日曜日までは何日でしょう』という問題も、
『水曜を含めるのか、含めないのか』『日曜になった時点でいいのか、日曜終日までなのか』で話が違ってきます。

これによって、

  • 水曜を含まず、日曜も含まない場合)あと3日
  • (水曜を含み、日曜は含まない場合)あと4日
  • 水曜を含まず、日曜を含む場合)あと4日
  • (水曜を含み、日曜も含む場合)あと5日

という非常にアバウトな日数が算出されてしまいました。
深夜26時に『明日の23時に待ち合わせね』と言うと大変やり取りに困るといった経験があれば納得していただけるでしょう。

プログラミングでは、for文の一番左側は、絶対に『含みます』。なぜならここで定義しているからです。
真ん中で、含まれたり(<=など)、含まれなかったり(<など)します。

つまり、『3から7(7も含む)は何個ある?』と聞かれた場合は、いったん引き算して、4を出した後、消えた分の1を足してあげればいいわけです。
そうやって、3から7(7も含む)のときは、5個あることがわかります。

多くの参考書たちは、このへんを『慣れ』とかで終わらせてますが、慣れじゃないです……
こういった、境界値付近の値操作は、非常に非常に間違えやすいので、注意するべきです。

*7

foreach文

foreach文は、主に配列の値を順番に使っていくときに使います。
Pythonでは、xrange(1, 11)が、1から10までの数字が入った配列を作ってくれます。
『11までじゃないの!?』と驚かないでください。右側の11は含まれていないので、10までしか配列ができないのです。
Pythonでは、むしろfor文の代わりにこれを使います。(ふつうのfor文がない)

sumNumber = 0
for k in xrange(1, 11):
sumNumber = sumNumber + k

Python

foreach( int i : array )
{
Console.WriteLine(i);
}

C#

for文応用(おまけなので読み飛ばしていいです)

for文は、繰り返しができるので、別に数値を足し合わせるだけの面白みのないこと以外にも色々できます。
例えば、微小空間をdouble型で小さくとって、足し合わせまくれば、結構精度の良い近似の積分ができ(ry

とか言ったことではなくて、
例えば文字列を結合しまくっていくとか、きみが無くまで殴るのをやめないとか、そういった実装も可能です。

while文

while文は、for文が、『ここからあそこまで』となるのに対して、『こうなるまでずっと続ける』という構文です。
『繰り返ししたいけど、別にここからとかは特にないよ』というときは、whileを使います。

なんで繰り返しが2種類もあるかというと、書くのがだるいからです。
これは永遠に殴り続けるやつです。

while 1:
print "なぐる"

Python

メソッド・関数

厳密には違うみたいですが、ここではメソッドで統一します。
メソッドとは、『毎回同じ処理書くのだるいから、ひとまとめにしようぜ』というやつです。

1からNまで毎回足すって処理を書くのめんどくさくねえ?
だからそういうの書いた
的なノリです。

『数学の関数とは違う』と言っている人がいるみたいですが、だいたい同じです。

違うところは

  • メソッドには返す値がある【※後述】
  • 別に数値計算以外のこともやる(実際パソコンの内部では数値計算をしているわけですが、人間から見た場合的な意味で)

とりあえずメソッドを作ってみます。


def f(x):
return 1

Python

public int f(int x) {
return(1);
}

Java

ここで、これらのメソッドの下の方に

f(x)
Python

f(x);
Java

と書くと、メソッドが実行されます。
これをメソッドが呼ばれるとか、メソッドがコールされるとか言います。
return というのは、戻り値とか、返り値とか言われていて、メソッドf(x)の最終的な値がこれだというわけです。
この場合は単純にreturn(1);としていますから、
どんなxを入れても、返って来るのは1という値……というメソッドです。

f(x)の中で色んなことを処理して、最後に値をもらってくるんだなあという感じです。

本とかでよくある、『2章の図5を参照せよ』がメソッド呼び出しに近いです。

Javaの方ではint型で返ってきてほしいと宣言しているので、絶対にint型を返す文(Return)を書かなければ、コンパイルできません。


後半へつづく

かなり疲れた。結構説明することいっぱいあるんだな……。まだ1/3も説明できてないよ……。
メソッドとか自分でもよくわかってないなーって思う。

*1:桁は英語でdigitと言います。digital(デジタル)のdigitです。

*2:でも7ビットを1バイトと呼ぶ特殊なこともあります

*3:(いわゆる全単射ではないというやつ)

*4:ちなみにこの1個の■を1ピクセルと呼び、1024×768画素というやつは、これが横に1024個、縦に768個並んでる状態なわけです。

*5:(これ大学の範囲だった気がする)

*6:1か0しか入らないということは、宣言したときにメモリを1ビットしか占有しない。

*7: for(;;) や for ( l ;_; l) { HanageYabee(笑) } などと書いて無限ループさせ遊ぶこともできますが、こう書いてあるのが死ぬほど嫌いな人もいるようなので要注意です。