voidポインタとは?C言語のvoid*の意味と使い方をわかりやすく解説

目次

C言語文法解説シリーズ

本記事は「C言語文法解説シリーズ」の1つです。
C言語の文法を、組み込み開発の視点も交えて解説します。

👉 C言語文法解説シリーズ一覧はこちら

初心者さん

voidポインタって何ですか?

エンジニアくん

型が決まっていないポインタだよ

初心者さん

型がないポインタなんてあるんですか?

エンジニアくん

どんな型のアドレスでも入れられる特別なポインタなんだ

voidポインタとは

型を持たないポインタ のことです。

C
void *p;

通常のポインタは型があります。

C
int *p;
char *p;
double *p;

しかし voidポインタは型がありません。
これが最大の特徴です。

基本的なポインタの使い方についてはこちらの記事で解説しています。


voidポインタはどんな型でも代入できる

C
int a = 10;
double b = 3.14;
char c = 'A';

void *p;
p = &a;
p = &b;
p = &c;

すべてOKです。

つまり

voidポインタ = 何でも入るポインタ

になります。


でもそのままでは使えない

初心者さん

じゃあ普通のポインタと同じように使えます?

エンジニアくん

それができないんだ

C
void *p;
int a = 10;

p = &a;
printf("%d", *p);   // エラー

これはエラーになります。

なぜなら

voidポインタは型を持たないため
*p の型が分からないからです。


キャストして型を戻す

voidポインタは型を戻して使います。

C
void *p;
int a = 10;

p = &a;
printf("%d", *(int*)p);

流れ

void* → int* に変換 → 参照

これでアクセスできます。


mallocでよく使われる

voidポインタの一番有名な例が malloc です。

C
void *malloc(size_t size);

malloc は void* を返します。

C
int *p = malloc(sizeof(int));

実際はこういう意味です

C
int *p = (int*)malloc(sizeof(int));

つまり

どの型にも使えるように
voidポインタになっています。

一方で組み込みではmallocは避けられることが多いです。その理由とは?


なぜvoidポインタが必要?

もし void* がなかったら

C
int* malloc_int()
double* malloc_double()
char* malloc_char()

全部用意しないといけません。

voidポインタなら

1つの関数で全部対応できます。


voidポインタはポインタ演算できない

C
void *p;

p++;   // エラー

なぜなら

型のサイズが分からないからです。

例えば

int → 4byte
char → 1byte

void → 不明

どれだけ進めばいいか分からないため
ポインタ演算はできません。


キャストすればポインタ演算できる

C
void *p;

((int*)p)++;

または

C
int *ip = p;
ip++;

こうすればOKです。


汎用関数でよく使う

voidポインタはどんな型でも受け取れるため
汎用関数で使われます。

C
void print(void *data) {
  printf("%d", *(int*)data);
}

呼び出し

C
int a = 10;
print(&a);

このように使えます。

関数ポインタについてはこちらの記事で解説しています。


voidポインタとcharポインタの違い

charポインタはサイズが決まっています。

C
char *p;
p++;

これはOKです。

voidポインタはサイズ不明です。

C
void *p;
p++;   // NG

ここが違いです。


まとめ

voidポインタ

C
void *p;

特徴

・型を持たない
・どんな型でも代入できる
・使用時はキャストが必要
・ポインタ演算できない

主な用途

・malloc
・汎用関数
・コールバック関数
・データ受け渡し

この記事が参考になった方へ

C言語の基本文法を一覧で整理しています。

👉 C言語文法解説シリーズ一覧はこちら

技術に関するご相談・開発・自動化ツール作成・記事執筆などのご依頼も承っています。

小さなご相談からでもお気軽にご連絡ください。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

コメント

コメントする


目次