Menu
Coddy logo textTech

voidポインタの復習

CoddyのCジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 49/61。

void* は C で「何かへのポインターだが、それが何かは伝えない」と表現する方法です。intfloat、構造体など、あらゆる data type のアドレスを保持できます。このため、C で汎用的なコードを書くための基盤となります。

注意点は、void* を直接デリファレンスできないことです。コンパイラーには、何バイトを読み取ればよいのか、またそれらをどのように解釈すればよいのかが分かりません。data を使用するには、正しい type にキャストし直す必要があります。

void print_int(void* data) {
    int* p = (int*)data;
    printf("%d\n", *p);
}

int main() {
    int x = 42;
    print_int(&x);
    return 0;
}

この柔軟性には責任が伴います。間違った type にキャストしても、コンパイラーは止めてくれませんが、プログラムはでたらめな結果を出したり、クラッシュしたりします。そのため、汎用的な function では、void* と type の指示子(enum や flag など)を組み合わせることがよくあります。これにより、function は data を正しく解釈する方法を把握できます。

これからのレッスンでは、void* を使ってあらゆる type の data を格納できるコンテナを構築し、真に再利用可能なデータ構造を実現します。

challenge icon

チャレンジ

簡単

print_valueという名前のfunctionを作成してください。このfunctionは2つのパラメーターを受け取ります。dataへのvoid* pointerと、int type flagです。functionは、type flagに基づいてdataを解釈し、出力する必要があります。

  • type flagが0の場合、pointerをint*にキャストし、整数値を出力する
  • type flagが1の場合、pointerをfloat*にキャストし、小数点以下2桁でfloat値を出力する

プログラムは2つの入力を受け取ります。

  1. type flag(整数の場合は0、floatの場合は1
  2. 数値

type flagに基づいて、値を適切な変数の型で格納し、その変数へのpointerとtype flagを指定してprint_valueを呼び出してください。

入力が042の場合の出力例:

42

入力が13.14の場合の出力例:

3.14

入力が0-17の場合の出力例:

-17

入力が199.5の場合の出力例:

99.50

自分で試してみよう

#include <stdio.h>

// TODO: ここに print_value 関数を書いてください


int main() {
    int type_flag;
    scanf("%d", &type_flag);
    
    if (type_flag == 0) {
        int int_value;
        scanf("%d", &int_value);
        
        // TODO: int_value へのポインタと type flag を使って print_value を呼び出してください
        
    } else if (type_flag == 1) {
        float float_value;
        scanf("%f", &float_value);
        
        // TODO: float_value へのポインタと type flag を使って print_value を呼び出してください
        
    }
    
    return 0;
}
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

オブジェクト指向プログラミングのすべてのレッスン

自分で練習してみよう: Cオンラインコンパイラ