【初心者にやさしい】CS(コンピューターサイエンス)基礎の基礎の学習：データとデータ型

# CS(コンピューターサイエンス)基礎の基礎
現在、CS基礎の基礎を一から学んでいるので、その学習成果のアウトプットに、、、
今回はCSを基礎から学習できるサービス「 __Recursion__」を参考にさせていただきました。興味のある方は以下からどうぞ！
↓↓↓↓↓↓
[Recursion](https://recursionist.io/)

## 今回は「データとデータ型」

### 1.データとは
　データとは、 __コンピューターで処理される特定の順序で示された記号や数字__ のことを指します。
　このデータを人間が理解できる形として示されているものを __情報__ と呼びます。

### 2.データ型とは
　前提として __コンピュータはデータを「0」と「1」の２種類の数字の組み合わせでのみ表現する__ ことができます。
　その時、組み合わせて表現されたものが __どのような種類のデータを示すのか__ を判断できないと意味がないですね。その時に使用されるのが、 __「データ型」__ です。

　例えば、プログラムで __「1」__ と打った時と __「"1"」__ と打った時では、人間は同じ1だと判断しますが、コンピューターは違う種類のデータだと判断します。これは、「1」は __「整数型」__ というデータ型であり、「"1”」は __「文字列型(言語によっては『文字型』)」__ というデータ型のため、違う種類だと判断されるからです。このようにして、「0」と「1」でしか表現できないデータを様々な種類で使用していくことができます。

```ruby
#Rubyの場合
puts 1 #「整数型」の「1」だと認識される
puts "1" #「文字列型」の「1」だと判断される

puts 1 + 1 #結果は「2」
puts "1" + "1" #文字列の連結と判断され、結果は「11」
```

:::note warn
上記はあくまでRubyの場合のデータ型です。言語ごとに用意されているデータ型が異なるので、逐一確認するようにしましょう。
:::

### 3.データ型の種類

#### 3-1. Boolean(ブーリアン)型
　コンピュータは「0」と「1」のみで表現しますが、その基本的な考え方を用いて、2通りのみで表現できるデータとして、 __「真偽値」__ があります。「１」を「True」、「0」を「False」のようにして扱い、その　__「真偽値を出力するため」__ に使用する型が __Boolean型__ です。

　【具体例】
　●アンケート機能の「はい」、「いいえ」
　●チェックボックスにチェックを「入れた」、「入れていない」
　●金融機関の預金口座に「預金した」、「預金していない」

```ruby
#Ruby
puts true   #結果は「true」
puts false  #結果は「false」
```

#### 3-2. Integer(整数)型
　__0と1の組み合わせの方法を増やすことで、日常的に用いるような整数を表現することができるようになります。そのための型__ を __Integer型__ と言います。
　普段私たちは __10進法__ を用いて、「0 1 2 3 4 5 6 7 8 9」の10個の数字の組み合わせで整数を表現していますが、コンピューターは先ほどの「0」と「1」の組み合わせ、つまり __２進数__ で表現しています。この __10進数と2進数を対応させることで整数を表現__ することができるのです。

　　　　　　　　　　　　　　　![2進数と10進数対応表.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2375287/de2c5537-542d-051a-0cad-6d868d383c4d.jpeg)

#### ※「bit」と「byte」
　先ほどコンピューターは「0」と「1」の２種類の組み合わせで表現すると示しましたが、この組み合わせの要素一つ一つのことを __bit__ と呼びます。 __この「bit数が大きくなる = コンピューターで保存できるデータの領域が増える」__ ことにより、表現できる値の種類が増えていきます。
![bitについて.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2375287/39f32533-d140-550f-051b-dc2eca75361c.png)


![bitの増え方図解.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2375287/318f9df3-aa06-fde3-a8b6-ee07a5336d38.png)


　このように、「1」と「0」をそれぞれ「1bit」と基準点とし、そこから __「n bitはn個の数字の組み合わせの要素が2n乗通り」__ のように表現できる数が増えていきます。
　このbitが __8bit__ に達すると、 __1byte__ となります。1byteは8bitなので、2の8乗つまり __256通り__ の整数表現ができるようになります。
　この考えを利用し、整数型では「桁数」という概念で表現できる値の種類を判断するのではなく、「byte数」で判断するようになります。整数型はデフォルトで「4byte」であるため、2の３２乗通りの表現が可能です。 __プログラミング言語によっては、表現できる数の上限が設けられている__ ようです。

#### ※16進数
　　　　　　　　　　　　　　　　![2進数と10進数対応表.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2375287/dbe53ba0-3aaf-ee94-8653-f09a68dbb880.jpeg)

　上のように、10進数は人間が扱いやすく可読性にも優れています。一方 __2進数はコンピューターにとって扱いやすいですが、数字が大きくなれば２進数で表現する時の桁数も増え、人間にとってはかなり可読性という点で劣っています__ 。
　この点を踏まえて使われるのが __16進数__ です。
　 __16進数は「0 1 2 3 4 5 6 7 8 9 A B C D E F」の16個の組み合わせで表現する__ ものです。
　　　　　　　　　　　　　　![2進数と16進数.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2375287/45d614b7-87b0-5e0b-a52a-01840545fa5a.png)

　このように、16進数で表現したものを2進数に変換すると、4bitの数の組み合わせで表現できるようになり、可読性が増すようになります。長ければ長いほど、16進数と2進数の対応表記法は便利になります。
　16進数は __「IPアドレス」__ や __「文字コード」__ などの冗長になりやすい値に広く使われているそうです。

#### 3-3. Char(文字)型
　 __0と1の2進数の組み合わせを文字と対応させて表現する__ のが __Char型__ です。
　そもそもコンピュータは文字というものを識別できません。だからこそ、 __文字とそれに対応するコードを用意しておき、コンピュータがそのコードを読み取ることで文字に変換できるようにする__ という技術を使って文字を出力しています。
　この「__文字とコードの対応__」は誰でも決めることができますが、誰でも決めることができてしまうと、コンピュータによって文字とコードの対応が違ってしまい、使いづらくなってしまいます。
　そこで登場したのが「__文字コード__」と呼ばれるものになります。これは文字とコードの対応を表にして、世界基準で使用していこうという意図で作成されたものです。最も古い文字コードには「__ASCII__」というものがあり、これは英語のみに対応した文字コードでした。
　　　　　![ASCII　文字コード表.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2375287/3b6306e3-dd39-543d-3611-76ef1826d500.png)
　これは、ASCIIの文字コード表ですが、各文字を２進数ではどのように表現するのかが定義されているのが分かります。例えば、「__A__」という文字だと、「__1000001__」の7bitで表現されるという具合です。
　
　しかし、ASCIIでは英語しか対応していないため、他の言語にも対応させたいところですよね。そこで生まれたのが、「__Unicode__」と呼ばれるものになります。これは、世界中の言語に対応しているものになりますが、厳密には「文字コード」ではありません。一つ一つの文字に「__コードポイント__」と呼ばれる数字を割り振っているだけのものになります。つまり、このUnicodeそのものをコンピュータが理解することは出来ません。
![unicode.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2375287/9e4a4a72-ba15-1a4e-81e8-e2ac9f9878f1.jpeg)
　この __unicodeのコードポイントをコンピュータが実際に理解できるコードに変換するための対応表として作られた__ のが、かの有名な「__UTF-8__」です。unicodeからUTF-8へと変換する仕組みは以下の図のとおりです。
![UTF-8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2375287/c507c420-6d8d-5b64-7024-1d1e8c206225.png)
　unicodeのコードポイントに応じた変換ルールが決まっているため、それに応じてUTF-8用の変換をします。上の図では変換後のコードを16進数で表記していますが、実際にはコンピュータは2進数で識別します。
　また、 __UTF-16__ という文字コードもあり、これはUTF-8とはまた違った対応ルールを持っています。
 ![符号化文字集合と文字符号化方式.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2375287/994e4f40-eee6-877c-c69f-b67f5786e3b8.png)
　UnicodeやUTF-8はそれぞれ上の図のように呼ばれています。難しいので理解しなくてもいいと思います。
しかし　「文字コード」は「__文字化け__」などの原因にもなる存在でもあるため、その対応のために知っておくことは必要だと言えます。
　

#### 3-4. String(文字列)型
　上の __「Char型」の文字一つ一つを配列のように順番に並べて文章のように表現する__ のが __String型__ です。

:::note 
　言語によっては、「Char型」と「String型」が両方存在しているものもあれば、「String型」のみに纏められているものもあります。
:::

　　![String型.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2375287/612bdc4a-f219-3471-f879-757d9aa78682.png)

#### 3-5. 浮動小数点型

##### 3-5-1. 固定小数点数について
　まず、コンピュータの世界には「 __固定小数点数__ 」と「 __浮動小数点数__ 」というものがあります。固定小数点数とは、「 __小数点が決まった位置にあるという前提で扱う少数__ 」を指します。コンピュータは、小数点の「.」は理解できません。そのため、整数を覚えさせて、「 __その整数の決まった位置に点を打つ__」というように覚えさせるわけです。こうすることで __決まった位置に小数点の打たれた固定小数点数__ を表現できるのです。　

##### 3-5-2. 浮動小数点数について
　固定小数点数は決まった位置に小数点を置いて扱うやり方です。しかし、この方法では、 __コンピュータのメモリは有限のため、とても大きい値や逆にとても小さい値を扱うことができません__ 。
　そのため、通常コンピュータでは「 __浮動小数点数__ 」として少数を扱います。これは、「3.1×10^8, 0.31×10^9」のように「 __何乗形式__ 」で扱う少数を指します。コンピュータには、「3.1×10^8」の例で言えば、「3.1」と「８」の部分のみを記憶させるようにします。こうすることで、 __少ないメモリでもより小さな値やより大きな値を表現できるようになります__。
　実際に表記するときは、「固定小数点数」と「浮動小数点数」という区別はあるものの、コンピュータで表現するときは、例えばRubyであれば、固定少数点数の表記をした値も、浮動小数点数のE表記をした値も、「データ型」としては浮動小数点型の「 __Float型__ 」が適用されることになります。
```ruby
3.14159285 #Float型
3.1E+8     #Float型
31.4E+7    #Float型
```

まとめると、

固定小数点数は、「 __小数点が決まった位置にあるという前提でコンピュータに記憶させて扱うもの__ 」であり、浮動小数点数は、「 __指数を使った表記をすることで扱える数値の範囲を増やしたもの__　」と言えます。
　浮動小数点数は「 __計算などで誤差が生じる(コンピュータが10進数で入力された少数を２進数に変換するときに生じる)__  」という点もありますが、コンピュータの世界では広く一般的に使われているということですね。


### 4.学び
　プログラミングでデータベース設計で何気なく指定している「カラム型」も、よくよく考えてみると、これだけの基礎知識に基づいたものなのだと改めて実感しました。
　今後「型」を決めるときに、今回学んだ視点も取り入れながら実装してみようと思います。