• ベストアンサー

voidポインタ

曖昧な質問になってしまいますが、voidポインタを使うことによって どのような利点があるのかが解りません、あらゆるポインタ型から キャスト可能だということは解るのですが、具体的な使用方法がわかりません よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
noname#25358
noname#25358
回答No.1

 利点は、おっしゃっていることそのまんまです。  たとえば、「どんな型の変数を代入する必要があるか全く分からない」という状況があったとします。  もしかしたら struct tm* かもしれないし、もしかしたら int* かもしれない。あるいは char* かもしれない。  これらのどれもが代入する必要がある可能性がある場合、先を見越して型を決めておくことができません(union で対処できる場合はいいですが)。  そこで、void* 型を「何でもいいよ」という意味で宣言しておくんです。  memcpy 関数の第1引数は void* で宣言されていますが、これは、どんなメモリーをどんな形でコピーする必要があるか、まったく分からないからです。

MrSIMPSOM
質問者

お礼

回答ありがとう御座いました。 そうですね、memcpyなどは普段何も考えずに使って いたので気付きませんでした。 初心者なのでまた質問するかもしれませんが その時はまたお願いします。

その他の回答 (2)

  • HogePiyo
  • ベストアンサー率57% (24/42)
回答No.3

> int *buf; > > buf = ( int * )malloc( sizeof( char ) * 10 ); 訂正。 int *buf; buf = ( int * )malloc( sizeof( int ) * 10 ); でした。すいません。

MrSIMPSOM
質問者

お礼

いいえ、とんでもないです、回答ありがとう御座いました。 私自身、Cを始めたばっかりなのでmallocに キャスト演算子を付けてすらいませんでした ので勉強にもなりました。

  • HogePiyo
  • ベストアンサー率57% (24/42)
回答No.2

具体例をあげれば動的にメモリ確保する malloc や realloc など、型の違うポインタを返す関数の戻り値や、型の違うポインタを引数に取る関数など。また、関数へのポインタなど。 どんな型がそこに来るのかわからないという場合いくらでも利点はあります。 ちなみに malloc なら、戻り値が void* で、 char *buf; buf = ( char * )malloc( sizeof( char ) * 10 ); で char 型のサイズが10個ある配列の先頭要素へのポインタが取得できます。つまり char 配列を確保しています。 ここで、 int *buf; buf = ( int * )malloc( sizeof( char ) * 10 ); とすると今度は int 型の配列が確保できたりします。

関連するQ&A

  • C言語のvoid型ポインタを使いたいのですが…

    C言語のvoid型ポインタを使いたいのですが… 関数の引数として、void型ポインタを使おうと思ったのですが、内部でどのように処理すればいいのかわかりません キャストすれば問題なく使えるとのことですが、どの型でキャストするのかをどのように判断するのかがわかりません 具体的には、画像処理で画像の構造体をいくつか作ったのですが、それぞれの構造体ごとに関数を書くと関数が多くなるので、void型ポインタでまとめてつくろうとしています どのように型の判断を行えばいいのかを教えてください

  • void型へのポインタ

    というのがC言語にありますよね? このvoid型へのポインタというのは、 どのようにイメージすればいいのでしょうか? 例えばchar型へのポインタなら、 指している領域は 1バイトの領域ですよね? ではvoid型は? また malloc関数を 使って char *p; p=(char *)malloc(1000); とするとでchar型にキャストしているから、 1個1バイト分の領域が1000個用意して、 先頭アドレスをpに格納するのですよね? では、 int *q; q=(int *)malloc(1000); としたら、用意されるのは、int型にキャストしているから 1個2バイト分の領域が500個用意されるのでしょうか? お願いします。

  • Voidポインタで受け取った変数の型を調べる方法

    あるライブラリの関数を利用しようとしたのですが、その関数の引数にVoidポインタがあり、どういう型のデータを格納したのかわかりません。このポインタのアドレスに格納されたデータの型を調べる関数なり方法なりというのはあるのでしょうか。 Voidポインタというのは型を問わずに受け取れるというのは利点ですが、受け取ったものがあらかじめなんだかわからない場合はどうするのでしょうか。よろしくお願いします。

  • void型ポインタ

    void型ポインタがわかりません。ためしに void a; printf("%d",sizeof(a)); でも当然エラーになりました。どうしてvoid型はないのにvoid型ポインタは存在するのでしょうか?サイズはどうなているのですか?また何に使うのでしょうか?

  • ポインタと()について

    ((void*)0)がNULLらしいのですが、(void*)0とキャストするだけではダメなのでしょうか?ポインタや配列関係?で()を厳重に多くしている場合をよく見ますが、何か理由があるのでしょうか。

  • void型ポインタについて

    -------------------------------- #include<stdio.h> void uni_disp(void *p,int typ); int main() { int idt=123456; double ddt=56.789; char ss[]="abcdef"; uni_disp(&idt,'I'); uni_disp(&ddt,'D'); uni_disp(ss,'S'); uni_disp("STRING",'S'); return 0; } void uni_disp(void *p,int typ) { if(typ=='I'){ printf("%d\n",*(int *)p); } else if(typ=='D'){ printf("%f\n",*(double *)p); } else if(typ=='S'){ printf("%s\n",(char *)p); } } ----------------------------------- 以上のプログラム等で、void型ポインタをint型ポインタ、double型ポインタとみなす場合の、「*(int *)p」や「*(double *)p」の表記がどういう仕組みになっているか分かりません。 「*(int)p」などはエラーが出るのですが、やはり表記の意味を理解していないため何故か分かりません。 「*(int *)p」などの表記を分解して教えていただけると嬉しいです。

  • void型のポインタで構造体の参照

    void型のポインタで構造体や共用体を参照することはできますか? void *p=&kou; struct KOU kou; (struct KOU*)kou.name="名前"; のようにして構造体を参照しようとしたのですが、「左側が構造体又は共用体ではありません。」と出ます。型キャストはコンパイラに型を知らせるだけのものなのでコンパイラが構造体の型を知ることができない、ということでしょうか?void型のポインタを使って構造体(共用体)を参照することはできますか?回答よろしくお願いします。

  • C言語のvoid型ポインタ変数について。

    C言語のvoid型ポインタ変数について。 C言語のvoid型ポインタ変数について質問があります。 組み込み系の開発を行っているのですが、現在使用しているシステムで、 提供されている "API" を介してアプリケーション部のソフト作成を行っています。 この "API" ですが、引数の多くはvoid型ポインタとなっています。 ある人がこの引数がvoid型となっているのを見て、 『なんでvoid型なんや??、C言語でアセンブラと違うんやから、void型なんかにしない方が良い』 とおっしゃいました。 この意味がよくわからなかったのですが、なぜ void型はよろしくないんでしょうか? -- 僕が思うに、APIなんやから引数を void型ポインタ にすることでどんな型にも対応できる 汎用的であると感じ、逆にこの方が良いのではと感じたのですが。。 -API例---- int _exApiKannsuu( char in_data, void* out_data ) "in_data" をもとに "out_data" を取得する。 どーやらこの "out_data" が void型 であるのががよくないらしい・・

  • voidポインタをハンドルへ

    voidポインタをハンドルへ 今、Form1でlogBoxというTextBoxを作成し、Form1.h以外ののソースからでも、エラーが出た場合そこにLogが吐き出されるようにしようとしています。 //clrres.h void *LOGBOX; void OutText(TextBox^ b,String^ s); extern inline void OUTPUTLOG(String ^s); //clrres.cpp #include "stdafx.h" #include"clrres.h" void OutText(TextBox^ b,String^ s){   b->AppendText(s+L"\r\n");   b->SelectionStart = b->Text->Length;   b->ScrollToCaret(); } inline void OUTPUTLOG(String ^s){   OutText((TextBox^)LOGBOX,s); } //Form1.hのForm1コンストラクタ内 System::IntPtr ptr=logBox->Handle; LOGBOX=ptr.ToPointer(); とすれば、簡単に、Logを書き出せるようになるかと考えたのですが、 error C2440: '型キャスト' : 'void *' から'System::Windows::Forms::TextBox ^' に変換できません。 と出てきます。 どの様にすれば、出来るようになるでしょうか? 宜しくお願いします。

  • #define NULL ((void *)0) の弊害

    よく話題にされるヌルポインタについての疑問です。 定数の0は、それがポインタと解されるべき文脈では ヌルポインタに読み替えられますが、 可変長引数のようにポインタであることがコンパイラには判断できない文脈では、 明示的にキャストしてやらなければなりません。 このとき、#define NULL 0 と定義されている処理系では、 NULLを使っても定数の0を書いたのと全く同じであり、 上のような場合におけるキャストの必要性からは逃れられません。 しかし、たまたま自分の処理系で #define NULL ((void *)0) と定義されていれば、 キャストを行わなくてもNULLを使うことによって正しく動いてしまいます。 ということは、#define NULL ((void *)0) と定義された処理系しか 使ったことの無いプログラマは、 「NULLを使うこと自体が、これはポインタだよという意志表示になる」 と錯覚してしまう危険性をはらんでいることになります。 この人の書いた「NULLを使い、必要なキャストを省略しているソース」を、 #define NULL 0 と定義された処理系でコンパイルすると 正しく動作しない可能性があります。 こういう弊害があるにもかかわらず、 ANSI Cでは #define NULL 0 のほかに #define NULL ((void *)0) も許しているのは、 一体なぜなのでしょうか。 メリットもあるのでしょうか?

専門家に質問してみよう