初心者でも理解できる!C言語のunsigned修飾子を使いこなす7つのステップ

初心者でも理解できる!C言語のunsigned修飾子を使いこなす7つのステップのイメージC言語
この記事は約7分で読めます。

※本記事のコンテンツは、利用目的を問わずご活用いただけます。実務経験10000時間以上のエンジニアが監修しており、常に解説内容のわかりやすさや記事の品質に注力しておりますので、不具合・分かりにくい説明や不適切な表現、動かないコードなど気になることがございましたら、記事の品質向上の為にお問い合わせフォームにてご共有いただけますと幸いです。(理解できない部分などの個別相談も無償で承っております)
(送信された情報は、プライバシーポリシーのもと、厳正に取扱い、処分させていただきます。)

はじめに

C言語の世界では、多くの修飾子が存在し、それぞれが独自の役割と機能を持っています。

今回はその中でも、特に初心者にとって理解が難しいとされる「unsigned修飾子」に焦点を当てて詳しく解説していきます。

●unsigned修飾子の基本的な概念

○unsigned修飾子の働き

unsigned修飾子は、変数がとることのできる値の範囲を指定します。

具体的には、その変数が負の数を含まないこと、つまり”符号なし”であることを表します。

その結果、unsigned修飾子を使用すると、その変数はより大きな正の数を表現できるようになります。

○unsignedとsignedの違い

基本的な整数型には「signed」修飾子が暗黙的に適用されています。

この修飾子は変数が負の数を含むことを許可します。

しかし、「unsigned」修飾子があると、その整数は負の値を取ることができず、全てのビットが数値の表現に使われます。

そのため、unsigned修飾子がついた変数は、同じビット数のsigned修飾子がついた変数よりも広範囲の値を表現できます。

●unsigned修飾子の使い方

○サンプルコード1:基本的なunsigned整数の使い方

下記のコードは、unsigned修飾子を使った基本的な整数の宣言と表示の方法を説明しています。

この例ではunsigned修飾子を使って整数を宣言し、その数値を表示しています。

#include <stdio.h>

int main() {
    unsigned int num = 12345;
    printf("%u\n", num);
    return 0;
}

このコードでは、まずunsigned int num = 12345;でunsigned型の整数numを宣言し、12345で初期化しています。

次にprintf("%u\n", num);でその数値を表示しています。

実行すると、コンソールに12345と表示されます。

○サンプルコード2:範囲を超えたときのunsigned整数の振る舞い

次に、unsigned修飾子がついた変数がその範囲を超えたときの振る舞いを確認するコードを紹介します。

この例ではunsigned修飾子がついた変数に対してオーバーフローを引き起こす操作を行い、その結果を確認しています。

#include <stdio.h>

int main() {
    unsigned int num = 4294967295;
    printf("%u\n", num);
    num = num + 1;
    printf("%u\n", num);
    return 0;
}

このコードでは、まず最大値4294967295でunsigned型の整数numを初期化しています。

その後、numに1を足してオーバーフローを引き起こし、その結果を表示しています。

実行すると、初めに4294967295が表示され、次に0が表示されます。

これは、オーバーフローにより値が0に戻ったことを示しています。

●unsigned修飾子の応用例

○サンプルコード3:unsignedを使ったビット操作

unsigned型の変数は全てのビットが数値表現に使われるため、ビット操作に適しています。

次のコードは、unsignedを使ったビットシフトの例を表しています。

この例ではunsigned整数のビットを左にシフトし、その結果を表示しています。

#include <stdio.h>

int main() {
    unsigned int num = 15;
    printf("%u\n", num);
    num = num << 1;
    printf("%u\n", num);
    return 0;
}

このコードでは、まず15でunsigned型の整数numを初期化しています。

その後、numのビットを左に1つシフトして、その結果を表示しています。

実行すると、初めに15が表示され、次に30が表示されます。

これは、15を2倍した結果が30であることを示しています。

左ビットシフトは数値を2倍する操作と等価であることがわかります。

○サンプルコード4:unsignedを使ったハッシュ関数

また、unsigned型の変数はハッシュ関数の作成にも使えます。

次のコードは、簡単なハッシュ関数の例を表しています。

この例では文字列を受け取り、それをunsigned整数に変換しています。

#include <stdio.h>

unsigned int hash(char *str) {
    unsigned int h = 0;
    for (; *str; str++)
        h = h * 31 + *str;
    return h;
}

int main() {
    char str[] = "Hello, World!";
    printf("%u\n", hash(str));
    return 0;
}

このコードでは、まずハッシュ関数を定義しています。

この関数は文字列を受け取り、各文字のASCII値を用いてハッシュ値を計算します。

具体的には、ハッシュ値は初期値0から始まり、文字列の各文字についてハッシュ値に31をかけた後にASCII値を足して更新します。

これにより、異なる文字列が異なるハッシュ値を生成するようになります。

main関数では、このハッシュ関数を用いて文字列”Hello, World!”のハッシュ値を計算し、表示しています。

実行結果は毎回同じになり、同じ文字列が必ず同じハッシュ値を生成することがわかります。

●unsigned修飾子の注意点と対策

○符号なし整数と符号付き整数の混在

unsigned修飾子を使用する際の一つの注意点は、符号なし整数と符号付き整数を混在させないことです。

C言語では、これらの混在が許されていますが、予期しない結果を生む可能性があります

特に、符号付き整数がnegativeであるとき、unsigned修飾子が付いた変数との演算は非常に危険です。

○オーバーフローとアンダーフロー

また、unsigned修飾子を使用する際は、オーバーフローとアンダーフローに注意しなければなりません。

これらは数値がその型の範囲を超えると発生します。

オーバーフローは最大値を超えると発生し、アンダーフローは最小値を下回ると発生します。

C言語では、これらの状況は明確に定義されておらず、その結果は予測不可能です。

そのため、これらの状況を防ぐためには、値の範囲を常に意識してプログラミングする必要があります。

●unsigned修飾子のカスタマイズ方法

○サンプルコード5:独自のunsigned型を作る

最後に、unsigned修飾子を使って独自の型を作る方法を紹介します。

次のコードは、unsigned修飾子を使って新しい型を定義し、その型の変数を操作する例を表しています。

#include <stdio.h>

typedef unsigned int uint32_t;

int main() {
    uint32_t num = 12345;
    printf("%u\n", num);
    return 0;
}

このコードでは、まずtypedef unsigned int uint32_t;でunsigned型の整数を表す新しい型uint32_tを定義しています。

その後、この新しい型を使って変数numを宣言し、数値を表示しています。実行すると、コンソールに12345と表示されます。

これにより、プログラムの他の部分で整数のビット数を明示的に制御することができます。

まとめ

以上、C言語のunsigned修飾子の基本的な概念から使い方、応用例、注意点、カスタマイズ方法までを順を追って詳しく説明しました。

unsigned修飾子は、プログラミング初心者にとっては少々扱いが難しいかもしれませんが、理解と習熟を深めることで多くの利点を享受することができます。

この記事が、あなたのC言語の学習に役立つことを願っています。