この記事のポイント
この記事ではマイナス値を持たない整数型である、C言語のunsigned型について、基本概念の整理から実際のコードでの活用までを順を追って解説します。
unsigned型による符号なし整数の定義と値の範囲 基本的な宣言方法と初期化の構文 実際のプログラムでの活用例とコードサンプル これらのポイントを理解しておくことで、より効率的かつ安全にプログラミングを行えるようになります。それでは、unsigned型が持つ特徴と利点を、具体的なコード例を交えながら学んでいきましょう。
unsignedとは?
C言語におけるunsignedは、負の値を持たない整数型を表すキーワードです。int型 が正負の値を扱えるのに比べ、unsigned int型は 0 以上の値だけを保持します。
符号を持たないという特徴により、unsigned int型は同じビット幅で通常の int型の約2倍の正の値を表現可能です。具体的には32ビットシステムでは、int型が -2,147,483,648 ~ 2,147,483,647を扱えるのに対し、unsigned int型は 0 ~ 4,294,967,295まで対応します。この性質は、unsigned型は配列インデックスやループ制御、ビット演算といった用途に有効です。
【関連】C言語をもっと詳しく学ぶならpaizaラーニング
基本構文 unsigned型の宣言は、整数型の前にunsignedキーワードを付けるか、unsigned単体で記述する方法があります。最も一般的なのはunsigned intですが、shortやlongと組み合わせることも可能です。初期化方法は通常の整数型と同様ですが、負の値を代入すると警告が表示されたり、予期せぬ動作を招く可能性があります。
#include <stdio.h>
int main() {
unsigned int count = 100;
unsigned short small_num = 50;
unsigned long big_num = 1000000;
printf("count: %u\n", count);
printf("small_num: %hu\n", small_num);
printf("big_num: %lu\n", big_num);
return 0;
}
実行する
出力結果
count: 100
small_num: 50
big_num: 1000000このコード例では、異なるサイズのunsigned型変数を宣言し、それぞれに正の値を代入しています。printf関数 では、各unsigned整数型に対応する書式指定子を使用して、正確に表示しています。
実用例 以下では、C言語のunsigned型を実際のプログラムで使用する具体的な例を紹介します。各サンプルコードでは、unsigned型の特徴を活かした実用的な使用場面を示し、コードの動作原理と期待される結果を詳しく解説しました。これらの例を通じて、unsigned型がいかに効果的にプログラムの品質と効率を向上させるかを理解できます。
配列要素の合計計算 配列内の全要素を合計する処理で、インデックスと合計値にunsigned型を使用します。
#include <stdio.h>
int main() {
unsigned int numbers[] = {10, 20, 30, 40, 50};
unsigned int sum = 0;
unsigned int i;
for (i = 0; i < 5; i++) {
sum += numbers[i];
}
printf("合計: %u\n", sum);
return 0;
}
実行する
出力結果
合計: 150このコードは配列のインデックスと合計値にunsigned型を使用しており、負のインデックスによる意図しないアクセスを防いでいます。ループ変数iも配列の範囲内でのみ動作するため、安全で効率的な処理となっています。
カウンタとしての活用 プログラム実行中のイベント発生回数をカウントする処理です。
#include <stdio.h>
int main() {
unsigned int cat_count = 0;
unsigned int dog_count = 0;
char animals[] = {'c', 'd', 'c', 'd', 'c'};
unsigned int i;
for (i = 0; i < 5; i++) {
if (animals[i] == 'c') cat_count++;
else if (animals[i] == 'd') dog_count++;
}
printf("ネコ: %u匹, イヌ: %u匹", cat_count, dog_count);
return 0;
}
実行する
出力結果
ネコ: 3匹, イヌ: 2匹カウンタ変数にunsigned型を使用することで、負の値になる心配がなく、より大きな数値まで正確にカウントできます。動物の種類を判定してそれぞれのカウンタを増加させる典型的な集計処理です。
ビット演算での活用 unsigned型はビット演算において特に有用で、論理演算の結果を正確に表現できます。
#include <stdio.h>
int main() {
unsigned int flag1 = 5; // 0101 (binary)
unsigned int flag2 = 3; // 0011 (binary)
unsigned int result;
result = flag1 & flag2;
printf("AND演算結果: %u\n", result);
result = flag1 | flag2;
printf("OR演算結果: %u\n", result);
return 0;
}
実行する
出力結果
AND演算結果: 1
OR演算結果: 7このコードではビット単位のAND演算とOR演算を実行しています。unsigned型を使用することで、符号ビットを気にすることなく純粋なビット操作が可能になり、フラグ管理やビットマスク処理で威力を発揮します。
大きな数値の計算 unsigned型の値域の広さを活用して、大きな数値を扱う計算処理です。
#include <stdio.h>
int main() {
unsigned long mouse_population = 1000;
unsigned int months = 6;
unsigned int growth_rate = 2;
unsigned int i;
for (i = 0; i < months; i++) {
mouse_population *= growth_rate;
}
printf("%u ヶ月後のネズミ個体数: %lu\n", months, mouse_population);
return 0;
}
実行する
出力結果
6 ヶ月後のネズミ個体数: 64000この例ではunsigned long型を使用することで、大きな数値でもオーバーフローが起こりにくくなっています。指数的増加を計算する際に、負の値が発生しないunsigned型の特性が活かされています。
文字列長の計算 文字列の長さを計算する処理で、unsigned型をカウンタとして使用します。この例では日本語文字列のバイト数をカウントしています。
#include <stdio.h>
int main() {
char animal_name[] = "ライオン";
unsigned int length = 0;
while (animal_name[length] != '\0') {
length++;
}
printf("動物名の長さ: %u文字\n", length);
return 0;
}
実行する
出力結果
動物名の長さ: 12文字unsigned型を使って文字列長が 0 以上であることを明示することで、意図を明確にし、処理の効率化にもつながります。
メモリサイズの管理 データ構造のサイズ計算にunsigned型を活用する例です。
#include <stdio.h>
int main() {
unsigned int elephant_count = 10;
unsigned int elephant_size = 6000; /* kg */
unsigned int total_weight;
total_weight = elephant_count * elephant_size;
printf("ゾウ%u頭の総重量: %u kg\n", elephant_count, total_weight);
if (total_weight > 50000) {
printf("重量超過です\n");
}
return 0;
}
実行する
出力結果
ゾウ10頭の総重量: 60000 kg
重量超過です重量などの物理量を扱う場合、負の値が意味を持たないため、unsigned 型を用いるのが効果的です。ここでは総重量を求め、その値を制限値と照らし合わせています。
インデックス管理 配列やデータ構造のインデックス管理でunsigned型を使用した例です。
#include <stdio.h>
int main() {
char bird_types[] = {'h', 's', 'e', 'h', 's'}; /* h: hawk, s: sparrow, e: eagle */
unsigned int hawk_positions[5];
unsigned int hawk_count = 0;
unsigned int i;
for (i = 0; i < 5; i++) {
if (bird_types[i] == 'h') {
hawk_positions[hawk_count] = i;
hawk_count++;
}
}
printf("タカの位置: ");
for (i = 0; i < hawk_count; i++) {
printf("%u ", hawk_positions[i]);
}
printf("\n");
return 0;
}
実行する
出力結果
タカの位置: 0 3配列の要素位置(インデックス)は、0以上の整数で表されます。そのため、インデックスを扱う変数には、負の値を取らないunsigned型などを活用しつつ、正しく範囲を管理することが重要です。
まとめ C言語のunsigned型は、符号なし整数を扱うための基本的でありながら非常に有用な機能です。負の値を必要としない場面では、int型よりも広い正の値を表現でき、プログラムの安全性やメモリ効率の向上に役立ちます。
unsignedの活躍する場面
配列インデックスやループカウンタでの境界管理
ビット操作やフラグ管理での論理演算処理
大きな正の整数値を扱う数値計算処理
重要なポイント
値域が0以上に限定されることによる安全性向上
同一メモリサイズでの表現可能数値範囲拡大
負の値代入時の予期しない動作への注意が必要
unsigned型を適切に使用することで、プログラムの品質向上とバグの予防につながります。特に配列操作やカウンタ処理では、その特性を最大限に活用できるでしょう。
レベルを更に上げたい方はpaizaプログラミングスキルチェックへ