void(int a []){a [5] = 3; // これは間違っています?}
渡される配列が変更されるようにこれを行うことはできますか?
削除して申し訳ありませんが、ここで少し新しいです...
私の質問に答える可能性のある別の質問があります:
私が持っている場合
void Test(int a) {
}
void Best(int &a) {
}
これらの2つのステートメントは同等ですか?
Test(a);
Best(&a);
void(int a []){a [5] = 3; // これは間違っています?}
渡される配列が変更されるようにこれを行うことはできますか?
削除して申し訳ありませんが、ここで少し新しいです...
私の質問に答える可能性のある別の質問があります:
私が持っている場合
void Test(int a) {
}
void Best(int &a) {
}
これらの2つのステートメントは同等ですか?
Test(a);
Best(&a);
void Test(int a[])
{
a[5] = 3;
}
次の代替構文のみ:
void Test(int* a)
{
*(a+5) = 3;
}
配列は渡されず、ポインターのみが渡されます。元の配列が変更されます。
2番目のリビジョンについては、次のようになります。
void Test(int a)
{
}
void Best(int &a)
{
}
それから
Test(aa); // Passes aa by value. Changes to a in Test() do not effect aa
Best(aa); // Passes aa by reference; Changes to a DO effect aa
Best(&aa); // Is a syntax error: Passing a pointer instead of an int.
参照やポインタではなく変数を取得する場合、それは関数が本質的に分離されていることを意味し、のアドホックコピーを取得します。(スタックなどをハックしようとせずに)何をしても、呼び出し元のコンテキストでその値にアクセスすることはできません。
呼び出しコンテキストについて何か知っている場合は、スタックの内容をある程度予測して何かを行うことができるかもしれませんが、それは一般的に悪い考えです。
メソッドが本質的にa*であるa[]をとる場合、はい、ポイントするセルの内容を変更できますが、(ポインター)自体を変更して他の何かをポイントすることはできません。
パラメータリストのint[]
との違いについてここに示されている答えを読んでください:との違い。私はその答えに本当にたくさんの愛を注いできました!:)int*
char*
char[]
Test
あなたとBest
機能についてのあなたの質問に関して、ジェームズ・カランは素晴らしい答えを提供しました。
元の関数が機能するはずです。
名前を付ける場合:
#include <iostream>
// Arrays always de-generate to pointers.
void plop(int a[]) // Make sure this function has a name.
{
a[5] = 3;
}
int main()
{
int test[] = { 1,1,1,1,1,1,1,1};
plop(test);
std::cout << test[5] << std::endl;
}
これは、配列が引数として関数に渡されると、常にポインターに逆生成されるためです。したがって、これは常に期待どおりに機能するはずです。配列の終わりを超えてインデックスを作成しないと仮定します。plop の内部では、渡された配列のサイズを決定する方法はありません。
いいえ。
関数の外部から値を変更するためのオプションは、参照 f(int& a) による呼び出し、ポインター f(int* a) による呼び出し、およびグローバル (shudder...) 変数の使用です。
配列を参照渡しする主な理由は、スタック オーバーフローと大きなオブジェクトの不必要なコピーを防ぐことです。たとえば、次のような関数があるとします。
void foo(int x[500000000000]);
すべての配列が値で渡された場合、最初に関数を呼び出したときにスタックがオーバーフローする可能性があります (もちろん、これは明らかに誇張です)。
これは、オブジェクト指向のメソッドを使用する場合に役立ちます。配列の代わりに、これがあったとします:
void foo(SomeClass x);
SomeClass は、500000000000 個のデータ メンバーを持つクラスです。このようなメソッドを呼び出すと、コンパイラは x をビット単位でコピーしますが、これは控えめに言っても非常に長いプロセスになります。配列で使用するのと同じ概念が引き続き適用されますが、これが手動で参照によって使用されることを指定する必要があります。
void foo(SomeClass &x);
(そして、64 ビット マシンと大量の RAM がない限り、最初から 500000000000 要素配列を作成しようとしないでください)