2010-12-29 13 views
1

こんにちは、次のコードは移植可能ですか?Cで値渡し

私はちょうど値によってポインタを渡すことができます変更それは呼び出し元で!

void foo(void *p) 
{ 
void **pp = (void**)p; 
*pp = "hahaha"; 
} 

int main(int argc,char **argv) 
{ 
void *p = NULL; 
p = &p; 
printf("%p\n",p); 
foo(p); 
printf("%s\n",(char *)p);  // hahaha 
printf("%p\n",p); 


return 0; 
} 
+0

ここには非常に人気があるコメントがあります。あなたがそれを行うことができるからといって、必ずしもあなたがすべきことではありません! – Nim

+0

あなたは正しい - それは*まだ*(いつものように)pass/call-by-valueだ。答えを参照してください。 –

答えて

3

ポインタにポインタを渡すのは、それを自分自身に割り当てるときと関数に渡すときに1つのポインタに見えるようにすることです。そのポインタが自分自身を指すようにしたためにのみ機能します。何をやっている

は基本的にはこれです:追加いくつかのキャストやトリックと

void foo(void **p) 
{ 
    *p = "hahaha"; 
} 

int main(int argc,char **argv) 
{ 
    void *p = NULL; 
    printf("%p\n", &p); 
    foo(&p); 
    printf("%s\n",(char *)p);  // hahaha 
    printf("%p\n", p); 
    return 0; 
} 

。 「暗闇の中でのカード・トリック」と言えば、実際のプログラムに入れるのは間違いない。

標準では、すべてのデータポインタをvoid *にキャストすることができます(これはコード内で常に実行していることを保証しています)。

voidへのポインタは、任意の不完全またはオブジェクト 型へのポインタまたはから変換することができます。任意の不完全またはオブジェクト型へのポインタは、void へのポインタに変換して戻すことができます。結果は元のポインタと等しいとみなされます。

(C99、§6.3.2.3.1)

4

はい、あなたがどのようなポインタのポイントを変更することができますが、あなただけが自体へのポインタのポイントを作ったので、それを行うことができます:はい、

p = &p; 

あなたの質問に答えるためにこれは移植可能です。それは一般的には良い考えではありません。

2

あなたが実際にポインタへのポインタでプレーしています。あなたはまだ値でポインタを渡しているので、呼び出し元の値を変更するためにコンパイラをだますことはありません。あなたが変えようとしているのは、ポインタへのポインタが指す値だけです。

あなた自身や他のプログラマを混乱させることなく、実生活で使うのはあまり良い考えではありません。

関連する問題