2017-06-04 19 views
-2

C++の関数プロトタイプ宣言の変数は、グローバルスコープと見なされますか?関数プロトタイプ変数スコープC++

など。以下のスクリプトでは、配列integerArrayと整数maxNumElementsを入力とし、ユーザーが提供した要素の数を返す関数プロトタイプreadArrayを宣言します。もちろん、readArray関数はmainから呼び出されます。私の質問はdisplayArrayreadArrayで編集された配列をユーザーが挿入した要素の最大数を指定して印刷できるかどうかです。つまり、integerArraynumElementsはグローバルですか?

/* prototype declaration*/ 
int readArray (int integerArray [], int maxNumElements); 
void displayArray(int integerArray[], int numElements); 

int main() 
{ 
    int inputValues[128]; /*the array to be read*/ 
    int numberOfValues = readArray(inputValues, 128); 
    displayArray(inputValues, numberOfValues); 
    return 0; 
} 

int readArray(int integerArray[], int maxNumElements) 
{ 
    int numberOfValues; 
    for (numberOfValues = 0; numberOfValues < maxNumElements; numberOfValues++) 
    { /*take integers as input from user and insert into array */ 
     /*return the number of elements the user as provided*/ 
    } 
    return numberOfValues; 
} 

void displayArray(int integerArray[], int numElements) 
{ /*print the array*/ 
    for (int = 0; i < numElements; i++) 
    { 
     cout << i << ":" << integerArray[i] << endl; 
    } 
    cout << endl; 
} 
+2

各関数は、変数の独自の*ローカル*コピー*を持ちます。 –

+1

生の配列を混乱させないでください。私たちはすでに 'sdt :: array'と' std :: vector'の実装をC++スタンダードに持っています。 –

+0

おそらく本当の質問ではありません。あなたはそれを行い、何が起こるか見ることができます。これは、簡単にテストできるようにするために行うべきことです。 –

答えて

-1

私は変数として関数のパラメータを話すことは理にかなっていないと思います。基本的には、関数を呼び出すときに関数に渡すデータのプレースホルダとして機能します。

したがって、integerArrayでは操作していません。​​が指すデータで操作しています。main()で宣言しています。 integerArrayではなく、inputValueが変数です。

あなたのケースでは、コール・バイ・リファレンスと呼ばれることが起こっています。私。関数プロトタイプは整数へのポインタを受け取ります。あなたはreadArrayへのポインタinputValues渡す場合:

int numberOfValues = readArray(inputValues, 128); 

を、あなたはそれをアドレスinputValuesを与えています。 readValuesは、inputValuesが指し示すメモリ領域上で動作します。

したがって、displayArrayは、readArrayによって編集されたデータを表示します。

これは参照による呼び出しの結果であり、関数のパラメータはある意味ではグローバルスコープではないことに注意してください。

あなたはプロトタイプを機能している場合、このようなものを見ていた:

int readArray (vector<int> integerArray); 
void displayArray(vector<int> integerArray); 

はその後displayArrayは、いかなる意味においてintegerArrayのコンテンツを印刷することはないだろうが。 readArrayを呼び出すと、inputValuesのコピーが得られます(この場合はvector<int> inputValuesと宣言されます)。関数呼び出しが返ってくると元の値はinputValuesになります。この特定の場合、displayArrayは空のベクトルを出力します。

+1

関数のパラメータは実際には特別な種類のローカル変数であり、関数が呼び出されると初期化されます。他のローカル変数と同様に、レジスタや実際のメモリに格納することができます。また、それについて考えるなら、_all_変数は単にデータのプレースホルダです。それらは実際には私たちが使用する名前なので、レジスタとメモリアドレス自体で直接作業する必要はありません。 –

+0

あなたは正しいと思います。私は、OPに遭遇しようとしていただけで、関数宣言を見ているときではなく、通常の変数と同じ方法で関数のパラメータを考えることは、常に有用な概念ではないということです。特に、彼の例では、関数のパラメータが何らかの形でグローバルスコープを持っているという印象を受けるかもしれませんが、実際にはcall-by-referenceのために特定の例で見えるかもしれません。私はこれが彼を混乱させていると思います。私はその混乱に加えていないことを願っています、その意図は反対です。 – ThorOdinsson

+1

ああ、大丈夫です。潜在的な誤解を解消するために、まだ変数であることを明確にしたかっただけです。 –

-2

いいえ、グローバルではありません。関数は、パラメータを受け取っている間にローカルコピーを作成します。これをC++で検証するには、コピーコンストラクタ内にcoutを持つ独自のクラスを作成します。そのクラスのオブジェクトを(値で)関数に渡すと、呼び出されるコピーコンストラクタが表示されます。 C++では、もっと良い方法はstd :: arrayとstd :: vectorを使うことです。また、値渡しは、非プリミティブ型や膨大なデータチャンクのための賢明な考えではありません。パラメータは常に "アドレス"(ポインタ)または "参照"で渡します(std :: refについて読むことができます)

+1

* "アドレス"または "参照"で常にパラメータを渡す* 'const int&param'は' int param'よりどのように優れていますか? – HolyBlackCat

+1

単純な型(組み込み型、単純なコンストラクタを持つ型、単一レジスタ内に収まる型など)では、原文を明示的に変更する必要がある場合を除いて、値渡しが効率的であることがあります。また、セマンティクス(ローカルコピーを移動することができます)のために、コピーを作成しようとすると値渡しが効率的になることに注意してください。 –

+0

@HolyBlackCat "const int&param" - >これには2つのものがあります。第1に、constでパラメータを受け取ることは、関数内のparamの値を変更せず、偶然に値を変更したくない場合には、非常に良い方法です。次に、 "&param"。値ではなく参照としてパラメータを受け取ることも非常に良い習慣ですが、パラメータがクラス/構造体オブジェクトなどの「大きな」型の場合には意味があります。これは、巨大なチャンクのローカルコピーを回避します。 intのようなプリミティブ型の場合、これは大きな違いはありません。しかし、まだ "const int&param"は何の害も生じません。 –

0

名前はどこに表示されますか。たとえば、グローバルスコープ内の名前は、宣言されたポイントから宣言されている翻訳単位の終わりまで表示されます。ローカルスコープ内の名前は、宣言されたポイントから宣言されたブロックの終わり(すなわち、閉鎖}まで)に見える。プロトタイプの引数の名前はプロトタイプでのみ表示されます。関数に渡される引数の名前は、その関数を通して表示されます。

だから、あなたのコードから:

int readArray(int integerArray[], int maxNumElements); 

integerArraymaxNumElementsは、このプロトタイプの外には見えません。

int readArray(int integerArray[], int maxNumElements) { 
    // ... 
} 

integerArraymaxNumElementsは、関数定義thoughoutではなく、それの外に表示されます。

int displayArray(int intgerArray[], int numElements) { 
    // ... 
} 

integerArraynumElementsは、関数定義thoughoutではなく、それの外に表示されます。

integerArrayの3つの使用法は、互いに接続していません。あたかもそれぞれがまったく別の名前であるかのようです。