2012-11-08 27 views
10

私はC++が新しくなりました(すべての初心者XDの通常のイントロです)。まあ、私は予期しない動作が現れたときに、プログラムを開発していました! 私は、この動作を実行するコードのパターンを決定するまで、私のプログラムで変数と配列をトレースしました!!関数内から配列要素の値を変更する

ここで私は物事の仕組みトレースするために使用されているものです:

#include <iostream> 

using namespace std; 

void showArray(int arr[], int n) 
{ 
    for(int i = 0; i < n; i++) cout << arr[i] << " "; 
    cout << endl; 
} 
void someFunction(int x[], int n) // changes the original values 
{ 
    x[0] = 2; 
    x[1] = 1; 
    x[2] = 0; 
} 
void someFunction2(int * x, int n) 
{ 
    x[0] = 2; 
    x[1] = 1; 
    x[2] = 0; 
} // changes the original values 
int someFunction3(int x[], int n) 
{ 
    x[0] = 2; 
    x[1] = 1; 
    x[2] = 0; 
    return 0; 
} // changes the original values 
int someFunction4(int x[], int n) 
{ 
    x = new int[n]; 
    x[0] = 2; 
    x[1] = 1; 
    x[2] = 0; 
    return 0; 
} // does NOT change the original value 

int main(void) 
{ 
    int * y = new int[3]; 
    y[0] = 0; 
    y[1] = 1; 
    y[2] = 2; 
    showArray(y, 3); 
    someFunction4(y, 3); 
    showArray(y, 3); 
    return 0; 
} 

私は問題があるが、ここではより多くの情報のWHEREコメント付きコードは説明すると思う: 4つの機能、すなわち、someFunctionがあります、someFunction2、someFunction3、someFunction4。 0、1、2の値を持つ配列yがあります。 すべての関数が元の配列の値を変更します。つまり、someFunctionX呼び出しの後のメイン関数のy要素は、関数を呼び出す前の要素と変わります。

私の質問は:なぜsomeFunction4は値を変更しない唯一の機能ですか?

ありがとうございます。私の悪い英語には申し訳ありません。

答えて

7

someFunction4には、newの整数の配列を指すようにxを割り当て、割り当てます。関数に渡された変数が指す配列は、古い配列を指しています。 someFunction4の中でxに、別の配列、つまりnewで関数で作成した配列を参照するように設定しているので、古い配列は変更されません。

1)x = new int[n];を取り除く:someFunction4()でオリジナルxを作るために

はあなたが割り当てられた値を保持し、2つのうちの1つを行います。これにより、someFunction4()は前のように動作します。

2)xへのポインタを引数としてsomeFunction4()に渡し、someFunction4()にポインタを渡します。

int someFunction4(int *x[], int n) 
{ 
    *x = new int[n]; 
    (*x)[0] = 2; 
    (*x)[1] = 1; 
    (*x)[2] = 0; 
    return 0; 
} // Makes x point to a new a new array 

そして、あなたのメインで、

someFunction4(&y,3); 
+0

ありがとうございました。あなたの答えは明らかです。だから、古い配列を作る方法は新しい価値がありますか? – joker

+0

割り当てを取り除く 'x = new int [n];' – GraphicsMuncher

+0

関数内から配列サイズを変更したいのですが? – joker

0

を行うあなたはSomeFunctionN呼び出すときの引数が機能

に渡されるかを理解する必要がある(yは、3)その後、SomeFunctionN内部の 'X'変数は、yがmainで指し示すのと同じ配列を指すように初期化されたローカル変数です。

SomeFunc4では、新しい配列を作成し、新しい配列を指すようにローカルポインタ(x)を変更します。あなたが作るすべての変更は、あなたが

2

のみのxを残して他のすべての場合で、私はテストケースを作った新しい配列

を打ちます。

http://ideone.com/fyl6MX

結果

0 1 2 
0x943b008 
0x943b018 
0x943b008 
0 1 2 

2つ目は、アドレスが新しいテーブルのアドレスです。あなたのポインタがローカルに他のアドレスを指しているのを見ることができます。

#include <iostream> 

using namespace std; 

void showArray(int arr[], int n) 
{ 
    for(int i = 0; i < n; i++) cout << arr[i] << " "; 
    cout << endl; 
} 
void someFunction(int x[], int n) // changes the original values 
{ 
    x[0] = 2; 
    x[1] = 1; 
    x[2] = 0; 
} 
void someFunction2(int * x, int n) 
{ 
    x[0] = 2; 
    x[1] = 1; 
    x[2] = 0; 
} // changes the original values 
int someFunction3(int x[], int n) 
{ 
    x[0] = 2; 
    x[1] = 1; 
    x[2] = 0; 
    return 0; 
} // changes the original values 
int someFunction4(int x[], int n) 
{ 
    x = new int[n]; 
    std::cout << x << endl; 
    x[0] = 2; 
    x[1] = 1; 
    x[2] = 0; 
    return 0; 
} // does NOT change the original value 

int main(void) 
{ 
    int * y = new int[3]; 
    y[0] = 0; 
    y[1] = 1; 
    y[2] = 2; 
    showArray(y, 3); 

    std::cout << y << endl; 

    someFunction4(y, 3) ; 
    std::cout << y << endl; 

    showArray(y, 3); 
    return 0; 
} 
+0

どのように関数内から元のポインティング値を変更するには? – joker

5
someFunctionのそれぞれにおいて

someFunction2、およびsomeFunction3、あなたが実際にあなたがmain()であなたの配列に割り当てられたメモリへpointerを渡しています。

x[1] = 1; 

それは実際にyポイントがmain()にバックアップするのと同じメモリに影響を与えます。これは、あなたがデータこのポインタポイントを操作するときことを意味します!

しかし、someFunction4に、あなたは声明で、新しいメモリを指すようにポインタxを再割り当て

x = new int[n]; 

だから、もはやymain()でないのと同じメモリを指し、何らかの変更それ以降は(someFunction4の範囲内でのみ)yには影響しません。

関連する問題