Detailed C++ programming main expression and suffix expression writing basis

  • 2020-05-07 20:10:27
  • OfStack

main expression
The
main expression is the building block of a more complex expression. They are the names of the qualified text, name, and scope resolution operators (::). The main expression can have any of the following forms:


    literal
this
:: name
name 
( expression )

literal is a constant main expression. Its type depends on the form of its specification.
The this keyword is a pointer to a class object. It is available in non-static member functions and points to an instance of the class for which the function is called. The this keyword can only be used outside of the body of a class member function.
The type of this pointer is type *const in a function that does not specifically modify the this pointer (where type is the class name). The following example demonstrates the member function declaration and the type of this:


// expre_Primary_Expressions.cpp
// compile with: /LD
class Example
{
public:
  void Func();     // * const this
  void Func() const;  // const * const this
  void Func() volatile; // volatile * const this
};

The range resolution operator (::), followed by the name, constitutes the main expression. The name of this class must be globally scoped, not a member name. The type of this expression is determined by the declaration of the name. If the name of the declaration is left, the type is left (that is, it can appear on the left side of an assignment operator expression). The scope resolution operator allows a reference to a global name, even if the name is hidden in the current scope.
A bracketed expression is a main expression with the same type and value as an unbracketed expression. If the expression without parentheses is lvalued, the expression enclosed in parentheses is also lvalued.
In the context of the main expression syntax given above, name is represented as anything in the syntax described by name, but when the scope resolution operator is used before the name, it is not allowed to use a type of name that appears only in the class. This includes the names of user-defined transformation functions and destructors.
Examples of main expressions include:


100 // literal
'c' // literal
this // in a member function, a pointer to the class instance
::func // a global function
::operator + // a global operator function
::A::B // a global qualified name
( i + 1 ) // a parenthesized expression

The following examples are all the name and various forms of the main expression considered:


MyClass // a identifier
MyClass::f // a qualified name
operator = // an operator function name
operator char* // a conversion operator function name
~MyClass // a destructor name
A::B  // a qualified name
A<int> // a template id

suffix the expression

A postfix expression contains the main expression or the expression in which the suffix operator follows the main expression. The following table lists the suffix operators.
Postfix operator
Operator name
Operator notation
Subscript operator
[ ]
Function call operator
( )
Explicit type conversion operator
type-name ( )
Member access operator
Or �. >
Postfix increment operator
++
Postfix decrement operator
� �
The following syntax describes the possible postfix expressions:


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

The above postfix-expression may be the main expression or another postfix expression. See the main expression. Postfix expressions are grouped from left to right, which allows the expressions to be linked as follows:
func(1)- > GetValue()++
In the above expression, func is the main expression, func(1) is the function suffix expression, func(1)- > GetData is the postfix expression for the specified class member, func(1)- > GetData() is another function postfix expression, and the entire expression is a postfix expression that increments the return value of GetData. The overall meaning of this expression is to pass "call func of 1 as a parameter and to get a pointer to the class as a return value. Then call GetValue() on this class, and increment the returned value.
The expressions listed above are assignment expressions, which means that the results of these expressions must be right valued.
Postfix form
simple-type-name ( expression-list )
Indicates the call to the constructor. If simple-type-name is the base type, the list of expressions must be a single expression, and that expression indicates that the value of the expression will be converted to the base type. This cast expression mimics a constructor. This form is especially useful when defining template classes because it allows the same syntax to be used to construct basic types and classes.
cast-keyword is one of dynamic_cast, static_cast, or reinterpret_cast. More information can be found in dynamic_cast, static_cast, and reinterpet_cast.
The typeid operator is treated as a postfix expression. See the typeid operator.
Form parameter and argument
The caller passes the information to the called function in the argument. The called function USES the corresponding parameter to access the information.
When the function is called, the following tasks are performed:
Evaluates all arguments (arguments supplied by the caller). There is no implicit order for these parameters to be computed, but all parameters are computed, and all side effects are done before entering the function.
Initialize each parameter with its corresponding argument in the list of expressions. A parameter is an argument declared in the header and used in the body of a function. Conversions are like 1 through initialization - standard and user-defined conversions are performed when the arguments are converted to the correct type. The following code conceptually demonstrates the initialization performed:


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

The pre-invocation conceptual initialization is:


int Temp_i = 7;
Func( Temp_i );

Note that initialization is performed as if using the equals syntax instead of the parenthesis syntax 1. A copy of i is made before the value is passed to the function.
Therefore, if the function prototype (declaration) makes a call to an argument of type long, and the caller provides an argument of type int, the standard type conversion of type long is used to promote the argument.
If one argument is provided, but it does not have a standard or user-defined conversion to the parameter's type, it is one error.
For arguments of a class type, the parameters are initialized by calling the constructor of the class.
Perform the function call.
The following program snippet illustrates the function call:


// 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 )
{
}

When func is called from main, the parameter is initialized with the value param1 (i will be converted to type ilong to correspond to the correct type using the standard transform) and with the value param2 (j will be converted to type jdouble using the standard transform).
Processing of parameter types
You cannot change a parameter declared as type const within a function topic. The function can change any parameter whose type is not const. However, the change is local to the function and does not affect the value of the argument, unless the argument is a reference to an object of type other than const.
The following functions illustrate some of these concepts:


// 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;
}

Ellipsis and default parameters
You can declare a function to accept fewer arguments than are specified in the function definition by using either of the following two methods: ellipsis (...) Or default parameters.
The ellipsis indicates that parameters may be required, but the number and type are not specified in the declaration. This is generally a poor C++ programming practice because it prevents you from getting the one advantage of C++, which is type safety. Different conversions will apply to functions declared with ellipses, rather than to functions whose parameter and argument types are known:
If the argument is of type floating point, it is raised to double before the function is called.
Convert all signed or unsigned char, short, enumerated types, or bit fields to signed or unsigned int using an integer lift.
All parameters of the class type are passed as data structures through values; The replica is created by a binary copy, not by calling the copy constructor of the class (if one exists).
If an ellipsis is used, it must be declared last in the parameter list.  

If no value is provided in the function call, the default parameter can be used to specify the value that the parameter should take. The following code snippet shows how the default parameters work.


// expre_Ellipses_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;
}

The above program declares a function print that takes two arguments. The second parameter, terminator, has a default value of "\n". In main, the first two calls to print allow the default second argument to provide a new line to terminate the printed string. The third call specifies an explicit value for the second argument. The output of this program is


// expre_Primary_Expressions.cpp
// compile with: /LD
class Example
{
public:
  void Func();     // * const this
  void Func() const;  // const * const this
  void Func() volatile; // volatile * const this
};
0


Related articles: