【C言語】NULLポインタとvoidポインタの違いをわかりやすく解説
C言語でプログラミングを行う際、「NULLポインタ」と「voidポインタ」はしばしば混同されがちですが、実はまったく異なる概念です。最大の違いは、NULLポインタが「値」であるのに対し、voidポインタは「型」であるという点にあります。本記事では、それぞれの特徴と使い方をサンプルコード付きで詳しく解説します。
NULLポインタとは何か
NULLポインタとは、「何も指し示していない状態」を表す特別な値を持つポインタのことです。ポインタ変数に割り当てるべきアドレスが存在しない場合や、まだ有効なアドレスを代入していない段階では、NULLを設定しておくことが推奨されます。これにより、未初期化ポインタによる予期せぬバグやメモリの不正アクセスを防ぐことができます。
なお、各ポインタ型(int * や char * など)には、それぞれ対応するNULLポインタ値が定義されています。
NULLポインタの宣言構文
<データ型> *<変数名> = NULL;
記述例
int *p = NULL; char *p = '\0';
NULLポインタのサンプルプログラム
以下は、NULLポインタの動作を確認するためのC言語プログラムです。
#include<stdio.h>
int main(){
printf("チュートリアルポイント C言語入門");
int *p = NULL; // pはNULLポインタ
printf("\n ポインタの値は: %x ", p);
return 0;
}
実行結果
上記のプログラムを実行すると、次のような出力が得られます。
チュートリアルポイント C言語入門 ポインタの値は: 0
voidポインタとは何か
voidポインタは、特定のデータ型と結び付いていない汎用的なポインタで、「汎用ポインタ(general purpose pointer)」とも呼ばれます。その最大の特徴は、あらゆるデータ型のアドレスを格納できる点にあります。
ただし、voidポインタが指し示す先の値を実際に利用する際には、適切な型へキャストしてから間接参照する必要がある点に注意しましょう。
voidポインタの宣言構文
void *<変数名>;
記述例
void *p; int a; char c; p = &a; // int型のアドレスを代入すると、int型ポインタとして扱える p = &c; // char型のアドレスを代入すると、char型ポインタとして扱える
このように、同じvoidポインタ変数 p でも、代入されるアドレスの型によって柔軟に扱いを変えられるのが魅力です。
voidポインタのサンプルプログラム
以下は、voidポインタを使ってint型変数の値を表示するC言語プログラムです。
#include<stdio.h>
int main(){
int a = 10;
void *ptr = &a;
printf("%d", *(int *)ptr);
return 0;
}
ここでは *(int *)ptr のように、voidポインタを一度 int型ポインタへキャストしてから間接参照しています。
実行結果
上記のプログラムを実行すると、次のように出力されます。
10
まとめ:NULLポインタとvoidポインタの違い
- NULLポインタ: 「どのオブジェクトも指していないこと」を示す特別な値
- voidポインタ: あらゆる型のアドレスを格納できる汎用的な型
両者は役割も用途も異なるため、混同せずに正しく使い分けることが、安全で可読性の高いC言語プログラムを書くための第一歩となります。特にNULLポインタはエラー処理や初期化チェックに欠かせず、voidポインタは汎用関数やライブラリ設計で活躍します。
-
C言語におけるユニオンとポインタの使い方を徹底解説
ユニオン(共用体)とは、異なるデータ型を持つ複数の変数が、同一のメモリ領域を共有するための仕組みです。構造体が各メンバーごとに独立したメモリを割り当てるのに対し、ユニオンではすべてのメンバーが同じアドレスを参照するという点が大きな特徴です。 ユニオンの構文 ユニオンを定義するときの基本的な書式は次の通りです。 union タグ名{ データ型 メンバー1; データ型 メンバー2; ---- ---- データ型 メンバーn; }; 実際の記述例を見てみましょう。 union sample{ int a; float b; char
-
C言語のポインタ入門!宣言・初期化から配列アクセスの実例まで徹底解説
ポインタ(pointer)とは、他の変数のメモリアドレスを格納するための変数です。C言語においてポインタは、メモリを直接操作したり、関数間でデータを効率的にやり取りしたりするために欠かせない重要な概念です。 ポインタの宣言・初期化とアクセス まず、次のような通常の整数変数の宣言を見てみましょう。 int qty = 179; 変数qtyには値「179」が格納されると同時に、メモリ上のどこかにその格納場所(アドレス)が割り当てられます。 ポインタの宣言 int *p; 「p」はポインタ変数であり、別の整数型(int)変数のアドレスを保持します。変数名の前にアスタリスク(*)を付けることで、「こ