C言語の変数にはsigned(符号あり)とunsigned(符号なし)の2つの種類の変数を作れる型があります。
このsigned(符号あり)とunsigned(符号なし)は非常に重要で間違えた使い方をすると代入した値がオーバーフローしたり、ループで無限ループしたりと思わぬ不具合の原因になったりします。
この記事ではsigned(符号あり)とunsigned(符号なし)の2つの違いを明確にしていきます。
signed(符号あり)とunsigned(符号なし)の「符号」とは
C言語のsigned(符号あり)とunsigned(符号なし)の「符号」とは「その変数がマイナスの値を取り得るかどうか」を区別するためにあります。
文字通り
signed(符号あり)であれば「マイナス~0、そしてプラス」の値を取ることができる変数、unsigned(符号なし)の場合は「0からプラスの値」しかとれない変数
になります。
signed(符号あり)とunsigned(符号なし)
C言語におけるsigned(符号あり)とunsigned(符号なし)は変数を宣言する時に変数の型の前に付けて利用します。
例えばint型であれば以下のように宣言します。
int i ; //signed(符号あり)のint型 unsigned int i ; //unsigned(符号なし)のint型
※signed(符号あり)は通常省略可能で型の前にunsigned(符号なし)が無ければsigned(符号あり)になります。
signed(符号あり)とunsigned(符号なし)の違いは最上位ビットの扱い
実際にsigned(符号あり)とunsigned(符号なし)の違いは最上位ビットの扱いが異なります。
signed(符号あり)は変数の最上位ビットを符号(0がブラス、1がマイナス)を表現し、unsigned(符号なし)は最上位を値の一部として扱います。
以下はchar型(8ビット)の場合で考えたビットイメージです。
これにより、signed(符号あり)とunsigned(符号なし)では同じchar型でも扱える数値の範囲が異なるようになります。
10進数で言うとchar型ではsigned char(符号あり)で-128から127、unsigned char(符号なし)で0~255までの値を扱るようになります。
この法則は他のint型などでも同様で最上位ビットを符号として扱うか値として扱うかで表現できる数値の範囲が変わります。
まとめ
C言語にはsigned(符号あり)とunsigned(符号なし)の変数を作成することができ、signed(符号あり)とunsigned(符号なし)の違いは最上位ビットをどのように扱うかの違いです。
signed(符号あり)は最上位ビットを符号(0がブラス、1がマイナス)として利用し、unsigned(符号なし)では値の一部として使います。
そのためにsigned(符号あり)とunsigned(符号なし)では同じ型でも表現できる数値(値)に違いが出てきます。