Postfixausdrücke

Postfixausdrücke bestehen aus primären Ausdrücken bzw. Ausdrücken, in denen Postfixoperatoren einem primären Ausdruck folgen. Die Postfix-Operatoren sind in der folgenden Tabelle aufgeführt.

Postfix-Operatoren

Name des Operators Operator-Notation
Tiefgestellter Operator [ ]
Funktionsaufrufoperator ( )
Expliziter Typkonvertierungsoperator type-name( )
Mitgliedszugriffsoperator . oder ->
Postfix-Inkrementoperator ++
Postfix-Dekrementoperator --

Die folgende Syntax beschreibt mögliche Postfixausdrücke:

primary-expression
postfix-expression[expression]postfix-expression(expression-list)simple-type-name(expression-list)postfix-expression.namepostfix-expression->namepostfix-expression++postfix-expression--cast-keyword < typename > (expression )typeid ( typename )

Der obige Postfixausdruck kann ein primärer Ausdruck oder ein anderer Postfix-Ausdruck sein. Postfixausdrücke gruppieren sich von links nach rechts und ermöglichen so das Verketten der Ausdrücke wie folgt:

func(1)->GetValue()++

Im obigen Ausdruck func handelt es sich um einen primären Ausdruck, func(1) ist ein Postfixausdruck, ein Postfix-Ausdruck, func(1)->GetValue der ein Element der Klasse angibt, func(1)->GetValue() ein weiterer Postfix-Ausdruck ist und der gesamte Ausdruck ein Postfixausdruck ist, der den Rückgabewert von GetValue erhöht. Die Bedeutung des Ausdrucks als Ganzes ist „Funktion aufrufen, dabei 1 als Argument übergeben und einen Zeiger für eine Klasse als Rückgabewert erhalten. Rufen Sie GetValue() dann diese Klasse auf, und erhöhen Sie dann den zurückgegebenen Wert.

Die oben aufgeführten Ausdrücke sind Zuweisungsausdrücke, was bedeutet, dass das Ergebnis dieser Ausdrücke ein "r-value" sein muss.

Die Form des Postfixausdrucks

simple-type-name ( expression-list )

gibt den Aufruf des Konstruktors an. Wenn "simple-type-name" ein grundlegender Typ ist, muss die Ausdrucksliste ein einzelner Ausdruck sein, und dieser Ausdruck gibt eine Umwandlung des Werts des Ausdrucks in den einfachen Typ an. Dieser Typ von Umwandlungsausdruck imitiert einen Konstruktor. Da diese Form die Konstruktion grundlegender Klassen und Typen mit derselben Syntax ermöglicht, ist sie bei der Definition von Vorlagenklassen besonders nützlich.

Die Umwandlungs-Schlüsselwort (keyword) ist eine von dynamic_cast, static_cast oder reinterpret_cast. Weitere Informationen finden Sie in dynamic_cast, static_cast und reinterpet_cast.

Der typeid Operator wird als Postfixausdruck betrachtet. Siehe typeid-Operator.

Formale und tatsächliche Argumente

Durch aufrufende Programme werden Informationen an aufgerufene Funktionen in "tatsächlichen Argumenten" übergeben. Die aufgerufenen Funktionen greifen mithilfe entsprechender "formaler Argumente" auf die Informationen zu.

Wenn eine Funktion aufgerufen wird, werden die folgenden Aufgaben ausgeführt:

  • Alle tatsächlichen Argumente (die vom Aufrufer angegebenen) werden ausgewertet. Es gibt keine implizite Reihenfolge, in der diese Argumente ausgewertet werden. Alle Argumente werden jedoch ausgewertet, und alle Nebeneffekte werden vor dem Eintritt in die Funktion abgeschlossen.

  • Jedes formale Argument wird mit dem entsprechenden tatsächlichen Argument in der Ausdrucksliste initialisiert. (Ein formales Argument ist ein Argument, das im Funktionskopf deklariert und im Textkörper einer Funktion verwendet wird.) Konvertierungen erfolgen wie durch Initialisierung – sowohl Standard- als auch benutzerdefinierte Konvertierungen werden beim Konvertieren eines tatsächlichen Arguments in den richtigen Typ ausgeführt. Die ausgeführte Initialisierung wird durch den folgenden Code konzeptionell veranschaulicht:

    void Func( int i ); // Function prototype
    ...
    Func( 7 );          // Execute function call
    

    Die konzeptionellen Initialisierungen vor dem Aufruf sind:

    int Temp_i = 7;
    Func( Temp_i );
    

    Beachten Sie, dass die Initialisierung ausgeführt wird, als würde die Gleichheitszeichensyntax anstelle der Klammersyntax verwendet werden. Eine Kopie von i wird vor dem Übergeben des Werts an die Funktion erstellt. (Weitere Informationen finden Sie unter Initialisierer und Konvertierungen).

    Wenn der Funktionsprototyp (Deklaration) ein Argument vom Typ longaufruft und das aufrufende Programm ein tatsächliches Argument vom Typ intbereitstellt, wird das tatsächliche Argument mit einer Standardtypkonvertierung in Typ long höher gestuft (siehe Standardkonvertierungen).

    Es ist ein Fehler, ein tatsächliches Argument anzugeben, für das es keine Standard- oder benutzerdefinierte Konvertierung in den Typ des formalen Arguments gibt.

    Für die tatsächlichen Argumente des Klassentyps wird das formale Argument initialisiert, indem der Konstruktor der Klasse aufgerufen wird. (Siehe Konstruktoren für weitere Informationen zu diesen speziellen Klassenmemmfunktionen.)

  • Der Funktionsaufruf wird ausgeführt.

Das folgende Programmfragment zeigt einen Funktionsaufruf:

// expre_Formal_and_Actual_Arguments.cpp
void func( long param1, double param2 );

int main()
{
    long i = 1;
    double j = 2;

    // Call func with actual arguments i and j.
    func( i, j );
}

// Define func with formal parameters param1 and param2.
void func( long param1, double param2 )
{
}

Wenn func von Standard aufgerufen wird, wird der formale Parameter param1 mit dem Wert von i (i wird in Typ long konvertiert, um dem richtigen Typ mit einer Standardkonvertierung zu entsprechen), und der formale Parameter param2 wird mit dem Wert von j (j wird mit einer Standardkonvertierung in Typ double konvertiert).

Behandlung von Argumenttypen

Formale Argumente, die als const Typen deklariert wurden, können nicht innerhalb des Textkörpers einer Funktion geändert werden. Funktionen können jedes Argument ändern, das nicht vom Typ constist. Die Änderung ist jedoch lokal für die Funktion und wirkt sich nicht auf den Wert des tatsächlichen Arguments aus, es sei denn, das tatsächliche Argument war ein Verweis auf ein Objekt, das nicht vom Typ ist const.

Die folgenden Funktionen veranschaulichen einige dieser Konzepte:

// expre_Treatment_of_Argument_Types.cpp
int func1( const int i, int j, char *c ) {
   i = 7;   // C3892 i is const.
   j = i;   // value of j is lost at return
   *c = 'a' + j;   // changes value of c in calling function
   return i;
}

double& func2( double& d, const char *c ) {
   d = 14.387;   // changes value of d in calling function.
   *c = 'a';   // C3892 c is a pointer to a const object.
    return d;
}

Auslassungspunkte und Standardargumente

Funktionen können deklariert werden, um weniger Argumente als in der Funktionsdefinition angegeben mit einer der folgenden beiden Methoden zu akzeptieren: Auslassungspunkte (...) oder Standardargumente.

Ellipsis gibt an, dass Argumente erforderlich sein können, aber die Anzahl und die Typen werden in der Deklaration nicht angegeben. Dies ist normalerweise ein schlechtes Beispiel für C++-Programmierung, da es einen der Vorteile von C++ unterlaufen kann: Typsicherheit. Unterschiedliche Konvertierungen werden auf Funktionen angewendet, die mit auslassungspunkten deklariert werden, als auf die Funktionen, für die die formalen und tatsächlichen Argumenttypen bekannt sind:

  • Wenn das tatsächliche Argument vom Typ floatist, wird es vor dem Funktionsaufruf zum Typ double heraufgestuft.

  • Ein beliebiger signed char oder unsigned shortunsigned charsigned short , aufgezählter Typ oder Bitfeld wird entweder in eine signed int oder eine unsigned int verwendungsintegrierte Heraufsufung konvertiert.

  • Jedes Argument des Klassentyps wird durch einen Wert als Datenstruktur übergeben; die Kopie wird durch Kopieren der Binärdatei statt durch Aufrufen des Kopierkonstruktors der Klasse erstellt (falls vorhanden).

Ellipse, falls verwendet, müssen in der Argumentliste zuletzt deklariert werden. Weitere Informationen zum Übergeben einer variablen Anzahl von Argumenten finden Sie in der Erläuterung von va_arg, va_start und va_list in der Laufzeitbibliotheksreferenz.

Informationen zu Den Standardargumenten in der CLR-Programmierung finden Sie unter Variable Argument Lists (...) (C++/CLI).For information on default arguments in CLR programming, see Variable Argument Lists (...) (C++/CLI).For information on default arguments in CLR programming, see Variable Argument Lists (...) (C++/CLI).

Mit Standardargumenten können Sie den Wert festlegen, den ein Argument annehmen soll, wenn keiner im Funktionsaufruf angegeben wird. Das folgende Codefragment zeigt, wie Standardargumente funktionieren. Weitere Informationen zu Einschränkungen beim Angeben von Standardargumenten finden Sie unter "Standardargumente".

// expre_Ellipsis_and_Default_Arguments.cpp
// compile with: /EHsc
#include <iostream>

// Declare the function print that prints a string,
// then a terminator.
void print( const char *string,
            const char *terminator = "\n" );

int main()
{
    print( "hello," );
    print( "world!" );

    print( "good morning", ", " );
    print( "sunshine." );
}

using namespace std;
// Define print.
void print( const char *string, const char *terminator )
{
    if( string != NULL )
        cout << string;

    if( terminator != NULL )
        cout << terminator;
}

Das vorangehende Programm deklariert eine Funktion, print, die zwei Argumente akzeptiert. Das zweite Argument, Terminator, weist jedoch einen Standardwert auf. "\n" In main, die ersten beiden Aufrufe, damit print das zweite Standardargument eine neue Zeile zum Beenden der gedruckten Zeichenfolge angeben kann. Der dritte Aufruf gibt einen expliziten Wert für das zweite Argument zurück. Die Ausgabe des Programms lautet

hello,
world!
good morning, sunshine.

Siehe auch

Ausdruckstypen