7

逆参照について話すとき、その*中で を使用する必要がありますか? 他の方法でポインターの指示対象にアクセスする場合、次のように、ポインターを逆参照していると見なすことができますか。

char *ptr = "abc" ;
printf( "%c" , *ptr ); // Here pointer is dereferenced.
printf( "%s" , ptr );  // What about this one?

それが私の質問の最初の部分です。

逆参照の例である場合printf( "%s" , ptr )は、私の質問の次の部分にも親切に答えてください。

K&R 言う

「void へのポインター」は、任意の型のポインターを保持するために使用されますが、それ自体を逆参照することはできません

したがって、

char a = 'c' ;
char *p = &a ;
void *k = &a;
printf( "\n%c\n" , *p );
printf( "\n%c\n" , *k );

コンパイルしない、コンパイラがエラーを出す

関数 'main' 内: 警告: 'void *' ポインターの逆参照エラー: 無効な void 式の使用

しかし、私たちが使用する場合

char *a = "c" ;
char *p = a ;
void *k = a;
printf( "\n%c\n" , *p );
printf( "\n%s\n" , k );

コンパイルして動作します。これは、void ポインターを逆参照できることを意味します。参照しているオブジェクト ポインターを取得しました。
その場合、上記の K&R の引用はこの文脈で何を意味するのでしょうか?

御時間ありがとうございます。

4

2 に答える 2

9

いいえ、あなたが持っているのは「未定義の動作」です-C言語標準は何が起こるべきかを述べていません。あなたの場合、それは「機能します」が、別のユーザー/コンパイラ/プラットフォームでは機能しない場合があります。あなたの声明:

printf( "\n%s\n" , k );

次と同等です。

int k = 42;
printf( "\n%s\n" , k );

であり、同様に未定義です。

于 2010-07-28T10:52:54.367 に答える
0

与えられた例では:

char *a = "c";
char *p = a;
void *k = a;
printf( "\n%c\n" , *p );
printf( "\n%s\n" , k );

何が起こっているのか、最初の printf では、charポインターの逆参照から値 'c' が渡されますが、フォーマットタグのためにprintfa を指定したことしかわかりません。char%c

現在、 avoid*は不明な型を持つ単なる生のポインターです。別のものにキャストしない限り、コンパイラーはどの型を読み取るかがわからないため、逆参照できません。

2 番目の printf では、void*ポインターが渡されます。printf単純な数値と見なされ、指定された書式タグを読み取るまで、それが何であるかはわかりません。を使用%sすることで、実際に を渡したということを printf 関数に伝えているchar*ため、それに応じてキャストし、文字列として適切に読み取ります。つまり、ポインターでchar*はなくポインターを逆参照しvoid*ます。

ポインターがヌル終了配列void*を指している限り、これは有効なコードです。ポインターが別のものを指しているchar場合でも、関数は喜んでそれをポインターとして読み取ろうとし( を指定した場合)、未定義の動作を引き起こします。void*printfchar*%s

別の悪い例:

char *a = "ce";
int b = (int)a;
printf( "\n%s\n" , b );

整数を逆参照することもできませんが、それは であると言っprintfchar*ので、機能します。

于 2014-12-03T04:21:21.117 に答える