• ベストアンサー

void型ポインタ

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

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

  • ベストアンサー
  • kenji_aki
  • ベストアンサー率50% (29/58)
回答No.4

void v; は、「何もない」vという変数を宣言しています。 このvはメモリには当然存在しませんし、「何も無い」のだから何かを入れることも、何かを取り出すこともできません。 だから、存在しません。 void *p; は型のないポインタ変数を宣言します。 ポインタ変数は存在します。このvoidは型が無いことを示しています。 ポインタ変数は変数のアドレスを格納するための変数です。 つまり、 int *pi;//int型変数のアドレスを格納する変数 char *pc;//char型変数のアドレスを格納する変数 short *ps;//short型変数のアドレスを格納する変数 となるわけです。 上記のそれぞれの変数のサイズは4byteです。 アドレスは常に4byteの領域を必要とするわけです。 その他にも、関数ポインタや構造体ポインタなどありますが 全てアドレスなので4byteです。 そう、ポインタ変数は型が何であれ格納されているのは、4byteのアドレスなのです。 そのアドレスがどのような変数を指し示しているのかを知るために型を持っています。 型の無いポインタ変数は、どんな型のアドレスでも、結局4byteのアドレスなのだから型に拠らないアドレスとして扱うためにあります。 だから、int型の変数のアドレスでもchar型の変数のアドレスでも何でも入れる事ができます。 とても懐が広いですね。 私もこんな懐の広い人と付き合いたいものですよ。 結局はアドレスを入れる箱だと云う理解でいいと思います。 使い方としては色々用途がありますが、 さまざまな型に対応したい。とか メモリのアドレス情報のみが欲しい。とか 例えば、 #include <stdio.h> int main(void) { void *v[10]; int i = 1234567890; v[0] = printf; v[1] = "test"; v[2] = &i; (*(int(*)(const char*, ...))v[0])("%s %d\n", (char *)v[1], *(int *)v[2]); return 0; } こんな使い方。 まぁ、これは冗談ですが、理解が進むうちに必要性に気づけるはずです。

szatmari
質問者

お礼

回答ありがとうございます。

その他の回答 (3)

  • tatsu99
  • ベストアンサー率52% (391/751)
回答No.3

voidとは本来「何もない」ことを示す言葉ですが、 void型ポインタは以下のように、 void *ptr1;と定義します。 通常、ポインターは必ず型を持ちます。 char *ptr2; int *ptr3; のようになります。 これは、ポインターが示すところのデータがchar型、int型であることを意味します。 しかしがら、ポインターの示す先が、char型かint型かはどうでもよくて、そのアドレスだけを問題にする場合があります。 そのような場合に、void型のポインターを使用します。 このポインターの示す先に、char型のデータがある場合は、 ptr2 = (char*)ptr1;とします。 そうすると*ptr2とすることにより、そのポインターが示すchar型のデータを操作可能になります。 同様にして、 ptr3 = (int*)ptr1;とすると、int型のデータを操作可能にすることができます。 従って、void型のポインターは、void型自体で使用するのでなく、他の型に変換してから使うことを前提としています。しかし、いまの時点では、どの型にするか決まっていない状態なので、単純にアドレスのみを示す情報を保持していることを示すvoid*という形で定義します。

szatmari
質問者

お礼

回答ありがとうございます。単体ではアドレスを指し示すんですね。

  • eroermine
  • ベストアンサー率18% (83/444)
回答No.2

void func()と void *ptr の void はなんの関係もありません。 予約語を増やしたくないので void を使いまわしました。 * も 掛け算とポインタの指す場所の内容との二つの意味があるが関係は無い。

回答No.1

void* a; printf("%d", sizeof(a)); では?

szatmari
質問者

お礼

回答ありがとうございます。たしかにそうでした。

関連するQ&A

  • 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」などの表記を分解して教えていただけると嬉しいです。

  • ポインタについてです。

    #include <stdio.h> int main (void){ char (*a)[3]; printf("a: %d\n", sizeof(a)); printf("a[0]: %d\n", sizeof(a[0])); printf("a[0][0]: %d\n", sizeof(a[0][0])); return 0; } このようなプログラムがあったとして a: 4 a[0]: 3 a[0][0]: 1 のような結果が得られました。a[]が3であるのは理解できたんですが、その他の結果があんまり理解できません・・・・ 解説をお願いします。

  • ポインタのサイズ

    ポインタのサイズがintと同じになるのは知っているのですが、 以下のコードの場合、 typedef struct hoge{ char buf1[8]; char buf2[16]; }HOGE; void test_func(HOGE *pHoge) { printf("型[%d],実際[%d]\r\n", sizeof(HOGE), sizeof(*pHoge)); memset(pHoge, 0x00, sizeof(*pHoge)); } 正しくサイズが取得できるのですが、 この使い方はC99の仕様的には正しいのでしょうか? よろしくお願いします。

  • 構造体へのポインタについて

    初心者です。 C入門書の著者のサポートページには正誤表とダウンロードしかないためこちらで質問させていただきます。 下記のコードの下から二行目の構造体へのポインタ (Car *) について、中学生に説明するように基本的な考え方、目的、書式、参考URLなどを教えて下さい。 ポインタについては、該当の章を読み直し基本事項については理解しておりますが、突然あるページから(Void *)や(Char *)など括弧で閉じるものが説明なしに出てきてちょっと混乱してます。(汗 どうぞ宜しくお願い致します。 #include<stdio.h> /* 構造体型struct Carの宣言 */ typedef struct Car{ int num; double gas; }Car; int main(void) { printf("int型のサイズは%dバイトです。¥n", sizeof(int)); printf("double型サイズは%dバイトです。¥n", sizeof(double)); printf("構造体structCar型のサイズは%dバイトです。¥n", sizeof(Car)); printf("構造体struct Car型へのポインタのサイズは%dバイトです。¥n", sizeof(Car *)); return 0; }

  • ポインタ変数のサイズ

     いろいろC言語のことを知りたくて、次のソースを作って動かしてみました。 ★ソース(□はタブ) ◆◆◆◆◆ #include <stdio.h> #include <stdlib.h> int main(void) { □char *s1; □int *s2; □ □s1 = (char *)malloc(1000); □s2 = (int *)malloc(1000); □ □printf("sizeof s1 = %d\n", sizeof s1); □printf("sizeof s2 = %d\n", sizeof s2); □ □printf("sizeof *s1 = %d\n", sizeof *s1); □printf("sizeof *s2 = %d\n", sizeof *s2); □ □printf("s1 = %d\n", s1); □printf("s2 = %d\n", s2); □ □printf("*s1 = %d\n", *s1); □printf("*s2 = %d\n", *s2); □ □return EXIT_SUCCESS; } ◆◆◆◆◆ ★実行結果1 ◆◆◆◆◆ sizeof s1 = 4 sizeof s2 = 4 sizeof *s1 = 1 sizeof *s2 = 4 s1 = 1323000 s2 = 1324008 *s1 = -60 *s2 = 1310916 ◆◆◆◆◆ ★実行結果2 ◆◆◆◆◆ sizeof s1 = 4 sizeof s2 = 4 sizeof *s1 = 1 sizeof *s2 = 4 s1 = 11087864 s2 = 11088872 *s1 = -60 *s2 = 11075780 ◆◆◆◆◆ ★実行結果3 ◆◆◆◆◆ sizeof s1 = 4 sizeof s2 = 4 sizeof *s1 = 1 sizeof *s2 = 4 s1 = 1519608 s2 = 1520616 *s1 = -60 *s2 = 1507524 ◆◆◆◆◆  OSはWindows Vista、コンパイラはMS Visual Studio 2010 コマンドプロンプトです。次の疑問についてご教授頂きたく、お願い致します。 (1)“sizeof s1”、“sizeof s2”の値が共に4となるのはなぜか。  char型へのポインタ、int型へのポインタとして宣言したs1、s2のサイズが同じ4になる理由が、どうしても分かりません。 (動かす前の予想は、でたらめな値になるかと思っていましたが) (2)“s1”、“s2”、“*s2”の値が毎回でたらめな値になったのに対して、“*s1”の値が毎回“-60”になったのはなぜか。  ポインタでつまずいており、いろいろ実験して体で理解したいと思っています。どうぞよしくお願い致します。

  • voidポインタ

    教えて頂けますか? 環境は mac osx です。 とあるページのサンプルコード #include <stdio.h> void outString(void *); int main() { int i = 65 ; double d = 10.101; outString(&i); outString(&d); outString("Kitty on your lap"); return 0; } void outString(void *text) { char *str = (char *)text; printf("%s\n" , str); } を実行した次のように表示されました A \301ʡE\2663$@\234\367\377\277A Kitty on your lap 二行目はどういう事になっているのでしょう? ちなみに d = 65.0; で実行しましたが A とは表示されませんでした。 自分の環境のせいでしょうか? よろしくお願いします

  • ポインタに ~0を入れること

    見かけたCのプログラムで、 ポインタに~0を代入するものを見ました。 そのプログラムをそのまま載せるのはわかりにくいので、 代わりに以下のプログラムを作って実行しました。 #include <stdio.h> int main(void) { char *pa[3]; int i; pa[0]=0; pa[1]=~0; pa[2]="Hello"; printf("sizeof(char*)=%d\n", sizeof(char*)); for(i=0; i<=2; i++) { if(pa[i]==NULL) printf("pa[%d] はNULLです。\n", i); if(pa[i]==(char*)0xFFFFFFFF) printf("pa[%d]は全ビット1です。\n", i); if(pa[i]==~0) printf("pa[%d]は~0です。\n", i); } return 0; } 結果 sizeof(char*)=4 pa[0] はNULLです。 pa[1]は全ビット1です。 pa[1]は~0です。 このプログラムはコンパイル時にエラーも警告も出ず、 動作も意図したとおりです。 pa[1]に入っている ~0 は、int型の定数なのでしょうか。 それならば、 pa[1]=~0; という代入や if(pa[i]==~0) という比較は 左辺はchar*型で右辺はconst int型であって型が異なりますが、 問題ないのでしょうか。 ~0は0の否定なので、全ビットは1なのでしょうけど、 int型(の定数)だと思います。 ~0というのは何か特別な値なのでしょうか。 ポインタに~0を入れるというのは、意味があるのでしょうか。 (例えば、「ポインタに0を入れるということは、ヌルポインタであって、ポインタとして無効なんですよ」のようなこと。)

  • C言語のポインタ

    あまり意識せずにポインタを使っているせいか,次のプログラムではまってしまいました. #include<stdio.h> #include<stdlib.h> int main(void) {  int *p, q;  p = (int *)malloc(sizeof(int));  q = (int *)malloc(sizeof(int));  *p = 2;  printf("%d\n", *p);  return 0; } コンパイルエラーで実行ファイルが出力されません. このプログラムで変数qはなぜポインタじゃないのでしょうか? 次にtypedefでptr_intという型を定義したプログラムは, 上のようなエラーが出力されず,期待とおりの結果になりました. #include<stdio.h> #include<stdlib.h> typedef int* ptr_int; int main(void) {  ptr_int p, q;  p = (int *)malloc(sizeof(int));  q = (int *)malloc(sizeof(int));  *p = 2;  *q = 3;  printf("%d\n", *p);  printf("%d\n", *q); return 0; } typedefすることでなぜエラーを回避することができるのでしょうか? よろしくおねがいします.

  • ポインタ

    C言語のポインタの勉強をしています。//エラー と書いている行でエラーがでます。*(a++),*(b++),*(c++)をそれぞれ*(a+i),*(b+i),*(c+i)とすればエラーがなくなるのですが、違いがわかりません。 先頭アドレスをセットしてないからエラーが出たのかと思いましたが、それが原因なら*(a+i),*(b+i),*(c+i)でエラーがなくなるのはどうしてでしょうか? 違いを教えて下さい。よろしくお願いします。 #include<stdio.h> int main(void) { void p_add(int *a, int *b, int *n); int i; int a[10] = {3,7,1,2,8,9,0,4,6,5}; int b[10] = {7,3,9,8,2,1,10,6,4,5}; int c[10]; memset(c,0x00,sizeof(c)); p_add(a, b, c); for(i = 0; i < 10; i++){ printf("a[%d]=%d b[%d]=%d c[%d]=%d\n", i, *(a++), i, *(b++), i, *(c+ +));                                               // エラー } return 0; } void p_add(int *a, int *b, int *n){ int i; for(i = 0; i < 10; i++){ *(n++) = *(a++) + *(b++); } }

  • ポインタのsizeofについて

    C初心者です。 ポインタ宣言させた変数をsizeof()で値を取得させて 表示させてみました。 char *cp; short int *sp; int *ip; i = sizeof(cp); printf("%d\n",i); i = sizeof(sp); printf("%d\n",i); i = sizeof(ip); printf("%d\n",i); 結果は全て4となりました。 これはなぜですか? (ただの変数として宣言すれば1、2、4となります。この理由も理解できています。)

専門家に質問してみよう