C言語/unsigned
概要
[編集]unsigned は C 言語において整数型の符号を明示的に指定する修飾子であり、符号なし整数 を表します。unsigned は unsigned int の省略形として機能し、明示的に符号なしであることを示します。
C 言語の整数型は 符号付き (signed) と 符号なし (unsigned) の両方が存在します。デフォルトでは int は符号付き (signed int) ですが、unsigned を付けることで符号なし整数として扱うことができます。
unsigned 型の仕様とデフォルトの動作
[編集]| 型の宣言 | 意味 |
|---|---|
unsigned
|
unsigned int と同義 (符号なし整数)
|
unsigned int
|
明示的に符号なし整数を指定 |
int
|
signed int と同義 (符号付き整数)
|
例えば、以下の 3 つの宣言はすべて同じ意味を持ちます。
unsigned int a = 100; unsigned b = 100; // unsigned int と同義
unsigned は int のみならず、他の整数型 (char, short, long, long long) にも適用可能です。
| 型 | 説明 |
|---|---|
unsigned char
|
符号なし 8 ビット整数 |
unsigned short
|
符号なし 16 ビット整数 (多くの環境で) |
unsigned int
|
符号なし 32 ビット整数 (多くの環境で) |
unsigned long
|
符号なし 32 ビットまたは 64 ビット整数 |
unsigned long long
|
符号なし 64 ビット整数 |
符号なし整数の範囲
[編集]unsigned 型の範囲は、環境やコンパイラに依存しますが、一般的な 32 ビットおよび 64 ビット環境では以下のようになります。
| 型 | 典型的な範囲 (32 ビット環境) |
|---|---|
unsigned char
|
0 ~ 255 |
unsigned short
|
0 ~ 65,535 |
unsigned int
|
0 ~ 4,294,967,295 |
unsigned long
|
0 ~ 4,294,967,295 (32 ビット環境) |
unsigned long long
|
0 ~ 18,446,744,073,709,551,615 |
64 ビット環境では unsigned long の範囲が unsigned long long と同じ 64 ビットになることが一般的です。
unsigned の適用と注意点
[編集]unsigned を使う利点
[編集]- 負の値を扱わないデータに適用
unsignedは 負の値を使用しない整数値 に適しています。- 例: 配列のインデックス、サイズ、カウンタ変数 (
size_tなど)。
- 符号ビットを有効活用
- ビット演算に適している
unsigned型は ビット単位の演算 (ビットシフトやマスク処理) で意図した動作をしやすい。
unsigned の注意点
[編集]- 符号付き整数との混在に注意
- 負の値を扱えない
unsigned型は負の値を表現できず、0 より小さい値を代入すると オーバーフローが発生 します。
unsigned を使った具体的な例
[編集]1. unsigned を使用した整数型の宣言
[編集]#include <stdio.h> int main() { unsigned int a = 3000000000; // 4,294,967,295 まで OK (32 ビット) printf("unsigned int: %u\n", a); return 0; }
出力:
unsigned int: 3000000000
2. signed と unsigned の混在によるバグ
[編集]#include <stdio.h> int main() { int a = -1; unsigned int b = 1; if (a < b) { printf("a は b より小さい\n"); } else { printf("a は b 以上\n"); } return 0; }
一見すると a = -1 なので a < b ( -1 < 1 ) になると思われますが、実際には a が unsigned int に型変換され、オーバーフローして 非常に大きな値 になります。そのため、実際の出力は:
a は b 以上
となり、意図しない動作になります。signed と unsigned を混ぜる際は型変換に注意が必要です。
3. unsigned のオーバーフロー
[編集]#include <stdio.h> int main() { unsigned int a = 0; a--; printf("unsigned int a: %u\n", a); return 0; }
このコードの出力は:
unsigned int a: 4294967295
signed int の場合は -1 になりますが、unsigned int は負の値を持たないため、最大値 (2^32 - 1 = 4,294,967,295) にラップアラウンドされます。
4. unsigned のビット演算
[編集]#include <stdio.h> int main() { unsigned int a = 5; // 0000 0101 unsigned int b = 3; // 0000 0011 printf("a & b: %u\n", a & b); // 0000 0001 -> 1 printf("a | b: %u\n", a | b); // 0000 0111 -> 7 printf("a ^ b: %u\n", a ^ b); // 0000 0110 -> 6 printf("~a: %u\n", ~a); // 1111 1010 -> 4294967290 (32 ビットの場合) return 0; }
unsigned は負の値を持たないため、ビット演算の結果が直感的になります。
まとめ
[編集]unsignedはunsigned intの別名 であり、符号なし整数 を意味する。- 負の値を使用しない場合に有用 (例: サイズ、カウンタ、ビット演算)。
- 符号付き (
signed) 型との混在に注意。意図しない型変換が発生する可能性がある。 - オーバーフロー時の動作が異なる (
signedの場合は未定義、unsignedは 0 にループ)。 - ビット演算に適している。
unsigned を適切に活用することで、安全で効率的なプログラムを書くことができます。しかし、符号付き型 (signed) との混在やオーバーフローに注意が必要です。