0

ポインターについての質問を考えただけです。ポインター p は main 関数の最初のイニシャルであり、
オブジェクト "a" をポイントしてから関数 f を呼び出し、オブジェクト "b" をポイントするように変更します。
しかし、「b」の範囲は機能のみです。関数 f を呼び出した後、ポインター p がまだ "a" へのポインターである理由。p は NULL か何かではないでしょうか?

 void f(int*p){
    int b = 10;
    p = &b;
}
int main(){

    int*p1 = NULL;
    int a=6;
    p1 = &a;
    f(p1);
    cout<<*p1<<endl;//output 6
    cout<<a<<endl;//output 6
    return 0;
}
4

4 に答える 4

2

C++ 関数には値セマンティクスがあり、関数はfポインタをコピーしp1、オリジナルp1は変更されません。

f関数で、ローカル変数へのポインタを指定しようとしましたが、これは危険です。

ポインターpポイントを変更する場合は、ポインターのアドレスを渡す必要があります

void f(int*& p) // pass in reference to pointer
{
    static int b = 10;  // make it static, 
                        // so p won't become dangling pointer when f returns
    p = &b;
}
于 2013-11-05T10:34:49.230 に答える
1

何が起こるのですか:

でポインターを渡すため、関数でローカル コピーが作成されますf。次に、そのコピーに別の値 (b へのポインター) を割り当てて、関数を終了します。元のポインターは変更されません。

ここで、関数を次のように変更するとします。

void f(int * & p){
    int b = 10;
    p = &b;
}

家でやらないで!

これで、実際のポインターが関数に渡され、コピーは作成されません。次に、bへのポインターがそれに割り当てられ、関数が戻ります。p1次に、存在しないために無効になった値 - が指す値にアクセスしようとしますb。ここで未定義の動作が発生します。最良のシナリオは、すべてが実際に予想どおりに機能することです。最悪のシナリオは、アクセス違反が発生するか、さらに悪化することです-プログラムの一部のデータが破損する可能性があります(すべてプラットフォームとコンパイラ)。

C++ コンパイラがそれについて通知しないのはなぜですか? 一般に、C++ は自分の足を撃たないように注意する必要がないためです (実際、C++ を使用して自分の足を撃つ方法はたくさんあります。これらを含む本を積み重ねると、月に到達します)。C++ は、指定されたとおりに実行するだけです。へのポインタを取得したいbですか?わかりました、問題ありません。関数からポインタを返したいですか?これは単に 32 ビットの整数値です。

要点は、C++ で作成する場合、そのようなコードを作成しないように十分に注意する必要があるということです。


編集:コメントに応じて

データが建物であり、ポインタがその建物の住所が記載された一枚の紙であると想像してください。ポインターを値で渡す場合:

void f(int * p)

別の紙を取り、住所をコピーしたようなものです。消去して別の住所に変更しても、元の紙の元の住所は変更されません。

今、次のようなことをすると:

void f(int * p)
{
    *p = 4;
}

紙に書かれた住所に実際に行って、建物の中で何かを変えたようなものです。その後、元の紙に記載されている住所に行くと、建物が変更されます。

最後に、次のようなことをすると:

void f(int * & p)
{
}

元の紙を関数に渡したようなものなので、アドレスを変更すると関数の外でも変更されます。

これがポインタの仕組みを理解するのに役立つことを願っています.

于 2013-11-05T10:45:18.013 に答える
0

ここで、ポインタは値で渡されます。つまり、関数 f はそのコピーを作成してから使用し、コピーが完了すると破棄します。初期ポインタ p1 は変更されません。

于 2013-11-05T10:47:34.753 に答える