2017-06-04 2 views
-2

Werden Variablen in der Funktionsprototypdeklaration in C++ als global betrachtet?Funktionsprototyp Variablenbereich C++

z. Im folgenden Skript deklarieren wir einen Funktionsprototyp von readArray, der ein Array integerArray und eine Ganzzahl maxNumElements als Eingabe akzeptiert und die Anzahl der vom Benutzer bereitgestellten Elemente zurückgibt. Natürlich wird die readArray Funktion von main aufgerufen. Meine Frage ist, ob displayArray das in readArray bearbeitete Array drucken kann, indem die maximale Anzahl von Elementen, die der Benutzer eingefügt hat, bereitgestellt wird. Kurz gesagt, sind integerArray und numElements global?

/* 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

Jede Funktion hat ihre eigene private und lokale * Kopie * der Variablen. –

+1

Machen Sie sich nicht mit rohen Arrays herum. Wir haben bereits 'sdt :: array'und' std :: vector' Implementierungen in den C++ - Standards. –

+0

Möglicherweise keine echte Frage. Sie können es tun und sehen, was passiert. Das sollten wir für jedes einfach zu testende Verhalten tun. –

Antwort

-1

Ich glaube nicht, dass es sinnvoll ist, von Funktionsparametern als Variablen zu sprechen. Sie dienen grundsätzlich als Platzhalter für Daten, die Sie der Funktion beim Aufruf bereitstellen.

In Ihrem Beispiel arbeiten Sie also nicht auf integerArray, sondern Sie arbeiten mit den Daten, auf die int inputValues[128] zeigt, die Sie in main() deklarieren. inputValue ist die Variable, nicht integerArray.

In Ihrem Fall tun Sie zufällig, was Call-by-Referenz genannt wird. I.e. Ihre Funktionsprototypen erhalten einen Zeiger auf eine Ganzzahl. Wenn Sie den Zeiger inputValues zu readarray passieren:

int numberOfValues = readArray(inputValues, 128); 

dann geben Sie ihm die Adresse inputValues. readValues arbeitet dann auf dem Speicherbereich, auf den inputValues zeigt.

So zeigt displayArray in Ihrem Beispiel die von readArray editierten Daten an.

Bitte beachten Sie, dass dies ein Ergebnis des Aufrufs durch Verweis ist, nicht, dass die Funktionsparameter in einem gewissen Sinne global sind. so etwas wie dieses sah

Wenn Sie Prototypen funktionieren hatte:

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

Dann würde displayArray nicht sein Druck den Inhalt integerArray in jedem Sinn. Wenn Sie readArray aufrufen, würden Sie einen Abruf-Wert eingeben: Es würde eine Kopie von inputValues (in diesem Fall würde es als vector<int> inputValues deklariert werden) und wenn der Funktionsaufruf zurückgibt, bleiben Sie mit dem ursprünglichen Wert von inputValues und In diesem speziellen Fall würde displayArray einen leeren Vektor drucken.

+1

Funktionsparameter sind eigentlich nur eine spezielle Art von lokalen Variablen und werden beim Aufruf der Funktion initialisiert. Sie können sich wie andere lokale Variablen in einem Register oder im aktuellen Speicher befinden. Auch, wenn Sie darüber nachdenken, _all_ Variablen sind nur Platzhalter für Daten; Sie sind wirklich nur Namen, die wir verwenden, so dass wir nicht direkt mit den Registern und Speicheradressen selbst arbeiten müssen. –

+0

Ich denke du hast Recht. Ich versuchte nur, zum OP zu kommen, dass es nicht immer ein nützliches Konzept ist, über Funktionsparameter auf die gleiche Weise wie "normale" Variablen nachzudenken, besonders nicht, wenn man sich die Funktionsdeklaration ansieht. Insbesondere kann er in seinem Beispiel den Eindruck gewinnen, dass der Funktionsparameter irgendwie einen globalen Gültigkeitsbereich hat, aber tatsächlich könnte er in seinem bestimmten Beispiel aufgrund des Call-by-Reference nur so aussehen. Ich denke, das verwirrt ihn. Ich hoffe, ich habe diese Verwirrung nicht verstärkt, die Absicht war das Gegenteil. – ThorOdinsson

+1

Ah, okay. Ich wollte nur klarstellen, dass sie immer noch Variablen sind, um mögliche Missverständnisse auszuräumen. –

-2

Nein, sie sind nicht global. Funktionen erstellen beim Empfang eines Parameters eine lokale Kopie. Sie können dies in C++ überprüfen, indem Sie im Kopierkonstruktor eine eigene Klasse mit einem Cout erstellen. Übergeben Sie das Objekt dieser Klasse an eine Funktion (nach Wert) und Sie sehen, dass der Kopierkonstruktor aufgerufen wird. In C++ ist es besser, std :: array und std :: vector zu verwenden. Auch die Weitergabe nach Werten ist keine kluge Idee für nicht-primitive Typen und riesige Datenblöcke. Übergeben Sie Parameter immer durch "Adresse" (Zeiger) oder durch "Verweis" (Sie möchten vielleicht über std :: ref lesen)

+1

* "Parameter immer mit" Adresse "oder mit" Referenz "übergeben" * Wie ist 'const int & param' besser als' int param'? – HolyBlackCat

+1

Beachten Sie, dass es für einfache Typen (wie die integrierten Typen, Typen mit trivialen Konstruktoren oder Typen, die in ein einzelnes Register passen können) oft effizienter ist, Werte zu übergeben, wenn Sie das Original nicht explizit ändern müssen . Beachten Sie auch, dass die Übergabe nach Wert effizienter sein kann, wenn Sie eine Kopie erstellen, da die Semantik verschoben wird (Sie können die lokale Kopie verschieben). –

+0

@HolyBlackCat "const int & param" -> Dies hat zwei Dinge. Zunächst ist es sehr empfehlenswert, einen Parameter als const zu erhalten, wenn Sie den Wert von param in Ihrer Funktion nicht ändern und den Wert nicht versehentlich ändern möchten. Zweitens, das "& param". Das Empfangen eines Parameters als Referenz und nicht als Wert ist ebenfalls eine sehr gute Übung, ist jedoch sinnvoller, wenn der Parameter vom "großen" Typ ist, wie beispielsweise ein Klassen-/Strukturobjekt. Es vermeidet eine lokale Kopie des riesigen Brocken. Bei primitiven Typen wie int wird das keinen großen Unterschied machen. aber trotzdem "const int & param" wird keinen Schaden anrichten. –

0

Umfang ist etwa wo Namen sichtbar sind. Namen im globalen Gültigkeitsbereich sind beispielsweise von ihrem Deklarationspunkt bis zum Ende der Übersetzungseinheit sichtbar, in der sie deklariert sind; Namen im lokalen Geltungsbereich sind von ihrem Deklarationspunkt bis zum Ende des Blocks sichtbar, in dem sie deklariert sind (d. h. bis zum abschließenden }).Die Namen von Argumenten in einer Funktion Prototyp sind nur in dem Prototyp sichtbar. Die Namen der Argumente, die an eine Funktion übergeben werden, sind in dieser Funktion sichtbar.

Also, aus dem Code:

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

Die Namen integerArray und maxNumElements sind außerhalb dieser Prototyp nicht sichtbar.

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

Die Namen integerArray und maxNumElements sind thoughout der Funktionsdefinition sichtbar, aber nicht außerhalb.

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

Die Namen integerArray und numElements sind thoughout der Funktionsdefinition sichtbar, aber nicht außerhalb.

Die drei Verwendungen des Namens integerArray haben keine Verbindung zueinander; es ist, als ob jeder von ihnen ein ganz anderer Name wäre.

Verwandte Themen