Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
As expressões Postfix consistem em expressões primárias ou expressões nas quais os operadores postfix seguem uma expressão primária. Os operadores de postfix estão listados na tabela a seguir.
Operadores Postfix
| Nome do operador | Notação do operador |
|---|---|
| Operador subscrito | [ ] |
| Operador de chamada de função | ( ) |
| Operador de conversão de tipo explícito | tipo-nome( ) |
| Operador de acesso de membro | . ou -> |
| Operador de incremento Postfix | ++ |
| Operador de decréscimo Postfix | -- |
A sintaxe a seguir descreve possíveis expressões de postfixo:
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 )
A expressão postfix acima pode ser uma expressão primária ou outra expressão postfix. As expressões do Postfix agrupam-se da esquerda para a direita, permitindo assim que as expressões sejam encadeadas da seguinte forma:
func(1)->GetValue()++
Na expressão acima, func é uma expressão primária, func(1) é uma expressão postfix de função, func(1)->GetValue é uma expressão postfix especificando um membro da classe, func(1)->GetValue() é outra expressão de função postfix e toda a expressão é uma expressão postfix incrementando o valor de retorno de GetValue. O significado da expressão como um todo é "chamar func passando 1 como um argumento e obter um ponteiro para uma classe como um valor de retorno. Em seguida, chame GetValue() essa classe e, em seguida, incremente o valor retornado.
As expressões listadas acima são expressões de atribuição, o que significa que o resultado dessas expressões deve ser um valor r.
O formulário de expressão postfix
simple-type-name ( expression-list )
Indica a invocação do construtor. Se o nome de tipo simples for um tipo fundamental, a lista de expressões deve ser uma única expressão, e essa expressão indica uma conversão do valor da expressão para o tipo fundamental. Este tipo de expressão de elenco imita um construtor. Como esse formulário permite que tipos e classes fundamentais sejam construídos usando a mesma sintaxe, esse formulário é especialmente útil ao definir classes de modelo.
A palavra-chave cast é uma de dynamic_cast, static_cast ou reinterpret_cast. Mais informações podem ser encontradas em dynamic_cast, static_cast e reinterpet_cast.
O typeid operador é considerado uma expressão postfix. Consulte operador typeid.
Argumentos formais e reais
Programas de chamada passam informações para funções chamadas em "argumentos reais". As funções chamadas acessam as informações usando "argumentos formais" correspondentes.
Quando uma função é chamada, as seguintes tarefas são executadas:
Todos os argumentos reais (aqueles fornecidos pelo chamador) são avaliados. Não há uma ordem implícita na qual esses argumentos são avaliados, mas todos os argumentos são avaliados e todos os efeitos colaterais são concluídos antes da entrada na função.
Cada argumento formal é inicializado com seu argumento real correspondente na lista de expressões. (Um argumento formal é um argumento declarado no cabeçalho da função e usado no corpo de uma função.) As conversões são feitas como se fossem por inicialização — as conversões padrão e definidas pelo usuário são realizadas na conversão de um argumento real para o tipo correto. A inicialização realizada é ilustrada conceitualmente pelo seguinte código:
void Func( int i ); // Function prototype ... Func( 7 ); // Execute function callAs inicializações conceituais anteriores à chamada são:
int Temp_i = 7; Func( Temp_i );Observe que a inicialização é executada como se estivesse usando a sintaxe de sinal de igual em vez da sintaxe entre parênteses. Uma cópia do é feita antes de
ipassar o valor para a função. (Para obter mais informações, consulte Inicializadores e conversões).Portanto, se o protótipo da função (declaração) chama para um argumento do tipo
long, e se o programa de chamada fornece um argumento real do tipoint, o argumento real é promovido usando uma conversão de tipo padrão para tipolong(consulte Conversões padrão).É um erro fornecer um argumento real para o qual não há uma conversão padrão ou definida pelo usuário para o tipo de argumento formal.
Para argumentos reais do tipo classe, o argumento formal é inicializado chamando o construtor da classe. (Consulte Construtores para obter mais informações sobre essas funções de membro de classe especial.)
A chamada de função é executada.
O fragmento de programa a seguir demonstra uma chamada de função:
// 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 )
{
}
Quando func é chamado de principal, o parâmetro param1 formal é inicializado com o valor de i (i é convertido em tipo long para corresponder ao tipo correto usando uma conversão padrão), e o parâmetro param2 formal é inicializado com o valor de j (j é convertido em tipo double usando uma conversão padrão).
Tratamento dos tipos de argumentos
Os argumentos formais declarados como const tipos não podem ser alterados dentro do corpo de uma função. As funções podem alterar qualquer argumento que não seja do tipo const. No entanto, a alteração é local para a função e não afeta o valor do argumento real, a menos que o argumento real fosse uma referência a um objeto não do tipo const.
As seguintes funções ilustram alguns desses conceitos:
// 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;
}
Reticências e argumentos padrão
As funções podem ser declaradas para aceitar menos argumentos do que os especificados na definição de função, usando um de dois métodos: reticências (...) ou argumentos padrão.
A reticência indica que os argumentos podem ser necessários, mas que o número e os tipos não são especificados na declaração. Esta é normalmente uma prática de programação C++ pobre porque derrota um dos benefícios do C++: segurança de tipo. Conversões diferentes são aplicadas a funções declaradas com reticências do que àquelas funções para as quais os tipos de argumento formal e real são conhecidos:
Se o argumento real for do tipo
float, ele será promovido para digitardoubleantes da chamada de função.Qualquer
signed charouunsigned char,signed shortou , ouunsigned short, tipo enumerado, ou campo de bit é convertido em umsigned intou um usando promoçãounsigned intintegral.Qualquer argumento do tipo de classe é passado por valor como uma estrutura de dados; A cópia é criada por cópia binária em vez de invocar o construtor copy da classe (se existir).
As reticências, se usadas, devem ser declaradas em último lugar na lista de argumentos. Para obter mais informações sobre como passar um número variável de argumentos, consulte a discussão de va_arg, va_start e va_list na Referência da BibliotecaRun-Time.
Para obter informações sobre argumentos padrão na programação CLR, consulte Variable Argument Lists (...) (C++/CLI).
Os argumentos padrão permitem especificar o valor que um argumento deve assumir se nenhum for fornecido na chamada de função. O fragmento de código a seguir mostra como os argumentos padrão funcionam. Para obter mais informações sobre restrições na especificação de argumentos padrão, consulte Argumentos padrão.
// 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;
}
O programa anterior declara uma função, print, que usa dois argumentos. No entanto, o segundo argumento, terminator, tem um valor padrão, "\n". No main, as duas primeiras chamadas para print permitir que o segundo argumento padrão forneça uma nova linha para encerrar a cadeia de caracteres impressa. A terceira chamada especifica um valor explícito para o segundo argumento. A saída do programa é
hello,
world!
good morning, sunshine.