Nodachisoft Nodachi Sword Icon
  
@あまじ✎ 2018年7月13日に更新

第2章16 型の長さ、情報量とビットを知る

イチからゲーム作りで覚えるC言語
第2章15 switch文 条件で実行する処理を分ける : PREV
NEXT : 第2章17 暗黙の型変換ルールを知る :

この記事でやること

前回は switch 文のキホンの書き方をお話ししました。

今回は、C言語で数値を扱うときの仕組みとビットについてお話します。C言語に限らずプログラミング全般的に通じるようなお話もあるので、ある程度仕組みを知っていることで、プログラムでのより正確な計算ができるようになると思います。今回はゲーム要素はなく、基礎知識的な部分ですので、わからなくなったら後から見返すようなつもりみてもらえればと思います。

変数の型が使うサイズと、持てる数値の幅

前のお話のとき、いくつか代表的な変数についてお話しました。

整数を扱う変数の型によって、メモリ上で使用する量が異なり、メモリ上で使用する量が多いほど、変数が持てる数値の幅(種類)は大きくなることになります。

具体的に、どのように違うのかは、環境によって変わってきますので、実際にプログラムを動かして確認してみましょう。

 
SuutiNaibu.c
#include <stdio.h>
#include <limits.h>
int main() {
 printf("1バイトは %d ビット\n", CHAR_BIT);
 printf("char  型は %d バイトで %d ~ %d の数をもてる\n", sizeof(char)  , CHAR_MIN, CHAR_MAX );
 printf("short 型は %d バイトで %d ~ %d の数をもてる\n", sizeof(short) , SHRT_MIN, SHRT_MAX );
 printf("int   型は %d バイトで %d ~ %d の数をもてる\n", sizeof(int)   , INT_MIN , INT_MAX);
 printf("long  型は %d バイトで %d ~ %d の数をもてる\n", sizeof(long)  , INT_MIN , INT_MAX);
 printf("unsigned char 型は %d バイトで %d ~ %d の数をもてる\n", sizeof(unsigned char), 0, UCHAR_MAX);
}

動かしてみると、筆者の環境では下のような結果になりました。

WindowsOS 上の VisualStudio Community 2017 で実行している人は同じ結果になると思います。

SuutiNaibu.cの実行結果
1バイトは 8 ビット
char 型は  1 バイトで -128127 の数をもてる
short 型は 2 バイトで -3276832767 の数をもてる
int 型は   4 バイトで -21474836482147483647 の数をもてる
long 型は  4 バイトで -21474836482147483647 の数をもてる
unsigned char 型は 1 バイトで 0255 の数をもてる

ではでは、中身を見ていきましょう。

サンプルコードの中身

実際にソースコードを見てみましょう。

さっそくですが2行目に新しく「#include <limits.h>」という行があります。

#include <ほにゃららぁ>」は、あらかじめ役に立つ便利な関数を、今回のソースコードの中で使えるようにする文です。

詳細は別のページでお話しますが、#include <limits.h> と記載があり、ある型(intとかcharとか)の最小の値、最大の値などの定義を確認することができるようになります。

 
SuutiNaibu.c
#include <limits.h>

続いて5行目です。

 
SuutiNaibu.c
 printf("1バイトは %d ビット\n", CHAR_BIT);

ここで、CHAR_BIT はビルドされるときには整数に置き換えられます。Visual Studio Community 2017で標準的な環境であれば、整数の 8 に置き換えられます。 つまり単純に「1バイトは 8 ビット」を文字として表示していることになります。

通常のコンピュータでは、ビットは 0 か 1 かの 2 通りを表す最小の単位となります。

1バイトは8ビットとはどういう意味?

パソコン内の適当なファイルを右クリックしてプロパティを確認すると、下のようが画面が出るかと思います。

ファイルのサイズ確認 ファイルのサイズ確認

この例だと 13,824 バイトと表示されているかと思います。これはこのファイルの情報量を表しています。

メモリやUSB、ハードディスク上には実際には 0 と 1 の羅列で保存されています。この 0 か 1 を持つことができるサイズが 1 ビット(bit)です。

1ビットは磁石でいえば S極とN極、電気信号でいえば電圧が加わっている、加わっていないなどの状態と置き換えることで、保存することができます。

最近の標準的に利用されるプログラムの実行環境では1 バイト を 8 ビットとして処理しています。 今後、このC言語のお話も 1 バイトは 8ビットとして記載していきます。

例にあげた「ぷらんくの簡単ごはんレシピ.docx」ファイルは 13,824 × 8 ビットで作られており、 つまりそれだけ 0 と 1 の組み合わせを使用しているサイズということになります。

ワンポイント

C11規格でも1バイトは「8ビット以上」と定義 していつつも、C言語のコンパイラを作っている実際のソフト、 Visual Studio Community 2017 や GCC では、 limits.h という定義ファイル内にて、CHAR_BIT(1バイト)を 8 と定義しています。 昔は 1 バイトが 何ビットかの定義は処理系によって必要に応じてそれぞれ定義されていた(もしくは可変の概念として扱っていた)ようですが、 最近のコンピュータでは 1 バイトは 8 ビットと事実上、決まっているようです。

ワンポイント

元々 1 バイトを 7 ビットとして扱っていたりするのは、一文字(英数字、特殊制御文字)を表現できるビット数を 一つのカタマリとして考えていたためのようです。以前の記事 に記載しているASCIIコード表だけであれば 7 ビットで表現することができますね。 現在のコンピュータでは通常 1 バイトは 8 ビットの扱いです。

ビットの組み合わせで数値を表現

1ビットが持てる数の組み合わせは 2 種類のみ(0 か 1、ON か OFF)とお話しました。 このビットで数値を表すにはどのようにすればよいでしょうか。 たとえば2ビットで数値をどれくらい表現できるかを例に考えてみましょう。2ビットを使っての 0 と 1 の組み合わせはこんな数があります。

組合せ 1ビット目 2ビット目
1つめ 0 0
2つめ 0 1
3つめ 1 0
4つめ 1 1

パターンは 4 つありました。 つまり、2ビットでは 4 種類の数を表現できることになります。

一般化して考えると、各ビットが 2 パターンあるので、 2 の 2 乗 = 4 パターンぶんの組み合わせ(数の種類)を表現できることになります。

  • 3 ビットなら 2 の 3 乗ぶんで 8 パターン
  • 4 ビットなら 2 の 4 乗ぶんで 16 パターン
  • 8 ビットなら 2 の 8 乗ぶんで 256 パターンを持つことができる、ということになります。

sizeof演算子とchar型が持てる数の範囲

ソースコードの6行目で、sizeof というキーワードが出てきました。

これは sizeof 演算子と呼ばれる、変わった演算子です。

使う時は sizeof ( 型 ) という書き方をします。「型」は「int」だったり「char」だったりします。

sizeof 演算子は、指定した型がどのくらいのサイズをメモリ上で使うのか、バイト数で結果を返してくれます

また CHARMINCHARMAX は 「#include 」を2行目に書いたことで使えるようになるキーワードであり、 ビルドする時の処理(プリコンパイラ処理。詳細は後のページでお話します)でパソコンの環境に合わせて適切な整数に置き換わります。

具体的に、CHARMIN は char型の変数が持てる整数の最小、CHARMAX は char 型が持てる整数の最大に置き換わります。

 
SuutiNaibu.c
 printf("char 型は %d バイトで %d ~ %d の数をもてる\n", sizeof(char) , CHAR_MIN, CHAR_MAX );

この行にあたる結果は下の通りでした。

SuutiNaibu.cの実行結果
char 型は  1 バイトで -128127 の数をもてる

sizeof演算子でchar型を調べた結果を表示してみたところ、char 型は 1 バイトとなっていることがわかりました。 1バイトは英数字などを1文字表示するためのサイズだったという事情もあり、char型が 1 バイトであることはC言語の 仕様(C11 – 3.6) で決まっています。

また、1バイトは 8ビット計算であるとき、2の8乗(個)ぶんのビットの組み合わせがあり、256通りの数値を表現することができます。

これは、char型が -128 ~ 127 の幅の整数を持つことと一致します。(256通りの数値)

short 型、int型、long型の持てる数値の幅

ソースコードの7行目以降はこんな結果になっていました。

SuutiNaibu.cの実行結果
 short 型は 2 バイトで -3276832767 の数をもてる
 int 型は 4 バイトで -21474836482147483647 の数をもてる
 long 型は 4 バイトで -21474836482147483647 の数をもてる

short 型は 2 バイトですので、メモリで16ビットを使用しています。

char 型は 1 バイトで固定ですが、short 型や int 型がいくつのバイト数を使うかは環境によって変わってきます。ルールとしては、ここに挙がっている型のサイズの順番として char < short ≦ int ≦ long であり、short は 2 バイト以上、intは 2 バイト以上、long は 4 バイト以上と記載があります。

(参考:C11 – N1570 – 5.2.4.2.1 Sizes of integer types)

unsigned の指定

ソースコードの8行目を見てみましょう。

char 型の前に「unsigned」というキーワードが入っていますね。このキーワードを付けることで、 マイナスの値を扱わず、その分の数字の範囲をプラスの数字の範囲に割り当てる、 という意味となります。

 
SuutiNaibu.c
 printf("unsigned char 型は %d バイトで %d ~ %d の数をもてる\n", sizeof(unsigned char), 0, UCHAR_MAX);

普通の char 型でしたら、1 バイトで -128 ~ 127 の間の 256通りの数字をもつことができました。

unsigned char 型であれば、 1 バイトで 0 ~ 255 の間の 256通りの数字をもつことができるようになります。

unsinged はプラスマイナスなどの「

符号なしの

」という意味となります

結果はこんな感じになっていると思います。

SuutiNaibu.cの実行結果
 unsigned char 型は 1 バイトで 0255 の数をもてる

unsigned は char 型だけでなく、他の型(int型やfloat型)にも指定することができます。

メモリが限られた環境で、大量の 0 ~ 200 の数字を扱うときなど、short 型で1つの変数あたり 2 バイトを使うよりも、unsigned char 型を使うことで 1 バイトだけで 0 ~ 200 の数字を表現することができるなど、場合によって利点があります。

あとがき

今回はここまで。お疲れさまでした。

非常に参考になったサイトさまや、参考文献など

ページの更新履歴

更新日 更新内容
更新なし
イチからゲーム作りで覚えるC言語
第2章15 switch文 条件で実行する処理を分ける : PREV
NEXT : 第2章17 暗黙の型変換ルールを知る :
 
 
送信しました!

コメント、ありがとうございます。

なんかエラーでした

ごめんなさい。エラーでうまく送信できませんでした。ご迷惑をおかけします。しばらくおいてから再度送信を試していただくか、以下から DM などでご連絡頂ければと思います。

Twitter:@NodachiSoft_jp
お名前:
 
連絡先:
 
メッセージ:
 
戻る
内容の確認!

以下の内容でコメントを送信します。よろしければ、「送信」を押してください。修正する場合は「戻る」を押してください

お名前:
 
連絡先:
 
メッセージ:
 
Roboto からの操作ではないという確認のため確認キーを入れてください。
確認キー=95
戻る
 / 
送信確認へ
コメント欄
コメント送信確認へ

関連ありそうな記事(5件)です!

ゲーム等で使えるつなぎ目のないループするテクスチャ画像の作り方

#ツール#ゲームプログラミング✎ 2021-01-24
ゲームなどで使えるループ画像、パターンテクスチャのツール、手動での作り方をまとめ
広告領域
追従 広告領域
目次
第2章16 型の長さ、情報量とビットを知る
第2章16 型の長さ、情報量とビットを知る
この記事でやること
この記事でやること
変数の型が使うサイズと、持てる数値の幅
変数の型が使うサイズと、持てる数値の幅
サンプルコードの中身
サンプルコードの中身
1バイトは8ビットとはどういう意味?
1バイトは8ビットとはどういう意味?
ビットの組み合わせで数値を表現
ビットの組み合わせで数値を表現
sizeof演算子とchar型が持てる数の範囲
sizeof演算子とchar型が持てる数の範囲
short 型、int型、long型の持てる数値の幅
short 型、int型、long型の持てる数値の幅
unsigned の指定
unsigned の指定
あとがき
あとがき
非常に参考になったサイトさまや、参考文献など
非常に参考になったサイトさまや、参考文献など
ページの更新履歴
ページの更新履歴
Nodachisoft © 2020