Baixe o app para aproveitar ainda mais
Prévia do material em texto
APOSTILA: LINGUAGENS DE PROGRAMAÇÃO C E C++ Angelo Passaro Página III.1 Segunda revisão / 2002 IIIIII.. OOPPEERRAADDOORREESS EE EEXXPPRREESSSSÕÕEESS Operadores são símbolos que definem como manipular valores. São representados por um caracter ou uma combinação de caracteres. Cada símbolo corresponde a uma unidade de significado (“token”), ou seja cada símbolo tem um significado bem determinado. É possível classificar os operadores em 3 classes: • operadores unários : operam sobre um único operando; • operadores binários : operam sobre dois operandos; • operador ternário : As linguagens C e C++ definem um único operador ternário, o qual opera sobre 3 operandos. Os operadores também podem ser classificados em dois grupos : • operadores ativos : modificam o operando sobre os quais são aplicados (exemplo operador ++); • operadores passivos : produzem um resultado intermediário sem, no entanto, alterar o valor do operando (exemplo : operador +); A classificação dos operadores como passivos e ativos é apresentada na seção III.E. Os operadores operam sobre operandos, formando expressões. Contudo, expressões podem não apresentar nenhum operador, como, por exemplo, uma expressão constante (0x0AA), ou uma declaração de variável. III.A. Operadores unários O conjunto dos operadores unários e seu significado é apresentado na tabela III.1. Os operadores são discutidos mais detalhadamente nas próximas subseções. Tabela III.1 : O conjunto de operadores unários e seu significado. operador significado ! operador de negação lógica ( ! ) ~ operador de complemento binário ( ~ ) + soma unária ( + ) - negação aritmética ( - ) * operador de indireção (aplicado a ponteiros) ( * ) & operador de endereço ( & ) ++ incremento unário -- decremento unário sizeof operador de tamanho de variável ou tipo new operador de alocação dinâmica de memória (SOMENTE C++) delete operador de liberação de memória alocada com new (SOMENTE C++) :: operador de resolução de escopo (SOMENTE C++) APOSTILA: LINGUAGENS DE PROGRAMAÇÃO C E C++ Angelo Passaro Página III.2 Segunda revisão / 2002 III.A.1. Operador de negação lógica ( ! ) O operando deve ser de um tipo aritmético ou um ponteiro. A aplicação do operador de negação lógica a um operando diferente de zero resulta o valor zero e, aplicado a um operando cujo valor é zero resulta o valor 1. O valor resultante é sempre do tipo inteiro. Exemplos: long int a = 0; // objeto do tipo long int, com identificador a, declarado e definido short int b = -100; // objeto do tipo long int, com identificador a, declarado e definido int resultado; resultado = !a; // neste caso resultado é igual a 1, já que a foi definido igual a zero resultado = !b; // aqui, a variável resultado assume o valor 0, já que b foi definido // com um valor diferente de zero if (! (a < b) ) // se a é menor que b, (a < b) resulta VERDADEIRO, ou seja 1, // caso contrário, (a < b) resulta FALSO, ou seja 0;. // Esse resultado é o operando do operador de negação. // No caso deste exemplo, a é maior que b e a expressão (a < b) resulta FALSO (0). // Com a aplicação do operador de negação lógica o argumento do comando if passa a ser // VERDADEIRO, ou seja 1. III.A.2. Operador de complemento binário ( ~ ) O operando deve ser um inteiro. Este operador atua bit a bit (por isso o nome complemento binário). Com a aplicação deste operador a um operando inteiro, todos os bits cujo valor é zero resultam valores 1 e todos os bits cujo valor é 1 resultam zero. Exemplo: unsigned short int a = 1; // em termos binários, um short int é um inteiro de dois bytes e, // neste caso, temos a = 0000 0000 0000 0001 a = ~a; // a variável a passa a assumir o valor 65534 que, em termos binários, // pode ser representado como a = 1111 1111 1111 1110 Outro exemplo: unsigned short y = 0xAAAA; // aqui y = 1010 1010 1010 1010 y = ~y; // agora y = 0101 0101 0101 0101, ou seja y = 0x5555 III.A.3. Soma unária ( + ) O operando deve ser um tipo aritmético. A aplicação deste operador resulta o próprio valor do operando. Observação APOSTILA: LINGUAGENS DE PROGRAMAÇÃO C E C++ Angelo Passaro Página III.3 Segunda revisão / 2002 O símbolo + também pode ser utilizado como o operador de soma binário. O compilador identifica o tipo do operador pelo contexto da expressão. III.A.4. Negação aritmética ( - ) O operando deve ser um tipo aritmético. A aplicação deste operador resulta o valor negativo do operando. Exemplo: long int a = 1301, b; b = -a; // o valor de b é igual a –1301 Observação O símbolo - também pode ser utilizado como o operador de subtração binário. O compilador identifica o tipo do operador pelo contexto da expressão. III.A.5. Operador de indireção ( * ) O operando de operador de indireção deve ser um ponteiro (qualquer). Quando aplicado a uma variável do tipo ponteiro (tipo derivado) resulta um valor do tipo declarado para o ponteiro. Esse valor é o conteúdo da memória apontada pelo ponteiro. Ponteiros serão abordados oportunamente (capítulo VI). Observação O símbolo * também pode ser utilizado como o operador binário de multiplicação. O compilador identifica o tipo do operador pelo contexto da expressão. III.A.6. Operador de endereço ( & ) Este operador fornece o endereço de memória (ponteiro) do operando, ou seja a posição de memória ocupada pelo valor cujo identificador é o operando. De forma simplificada, pode-se dizer que fornece o ponteiro para o valor associado à variável b. Maiores informações sobre o uso deste operador e de ponteiros serão apresentadas oportunamente (capítulo VI). Observação O símbolo & também é utilizado como o operador binário bitwise AND. O compilador identifica o tipo do operador pelo contexto da expressão. APOSTILA: LINGUAGENS DE PROGRAMAÇÃO C E C++ Angelo Passaro Página III.4 Segunda revisão / 2002 III.A.7. Operadores de incremento e decremento unário ( ++, -- ) III.A.7 Estes operadores podem ser utilizados como um prefixo ou um sufixo, com significados diferentes. III.A.7.a. OPERADOR USADO COMO PREFIXO Com a aplicação do operador ++ (--) antes do operando, este é incrementado (decrementado) de uma unidade antes de ser utilizado. Exemplo: long int var, i = 1, j = 11; var = ++i; // operador de incremento como prefixo // Neste caso, i é incrementado (assume o valor 2) e então esse // valor é atribuído a var. Portanto, var = 2 e i = 2. var = --j; // operador de decremento como prefixo // Neste caso, j é decrementado (assume o valor 10) e então esse // valor é atribuído a var. Portanto, var = 10 e i = 10. III.A.7.b. OPERADOR USADO COMO SUFIXO Com a aplicação do operador ++ (--) após o operando, este é incrementado (decrementado) de uma unidadeapós ser utilizado. Exemplo: long int var, i = 1, j = 11; var = i++; // Neste caso, o valor atual de i é atribuído a var (ou seja, var = 1) e somente // então i é incrementado (assume o valor 2). Portanto, var = 1 e i = 2. var = j--; // Resultado : var = 11 e j = 10 III.A.8. Operador sizeof Este operador fornece o tamanho (em bytes) de seu operando, em tempo de execução. O operador sizeof fornece um valor do tipo size_t (definido em STDDEF.H). O operando de sizeof pode ser: • o nome de um tipo (intrínseco ou derivado). O operando deve ser delimitado por parênteses; • um objeto de tipo intrínseco ou derivado. Neste caso, o operando pode ou não ser delimitado por parênteses. APOSTILA: LINGUAGENS DE PROGRAMAÇÃO C E C++ Angelo Passaro Página III.5 Segunda revisão / 2002 Exemplo: #include <iostream.h> // aqui encontra-se a definição de cout e do operador << void main(void) { char st_Hello[ ] = “Alo, Mundo”; // declara e define um vetor de caracteres, com // identificador st_Hello, inicializado com uma // constante “string literal” cout << “\n O tamanho do tipo de “<< st_Hello << “ e : “ << sizeof (char) << “bytes” ; cout << “\n\n O comprimento do vetor : “<< st_Hello << “ e : “ << sizeof st_Hello << “bytes\n” ; } // fim da definição da função main Os resultados da execução de tal programa são : O tamanho do tipo de Alo, Mundo e 1 bytes O comprimento do vetor Alo, Mundo e 11 bytes. III.A.9. Operadores new e delete O operador new tenta alocar, dinamicamente (ou seja em tempo de execução), um ou mais objetos do tipo (intrínseco ou derivado) especificado. O operador delete é utilizado para liberar a memória alocada por meio do operador new. Uma discussão mais detalhada destes operadores será apresentada mais adiante, nos tópicos sobre alocação dinâmica de memória e sobre a programação orientada a objetos. Observação: Estes operadores são definidos somente para o C++. III.A.10. Operador de resolução de escopo ( :: ) O operador unário de escopo é utilizado para acessar objetos ou funções com escopo global. Sua sintaxe básica é : ::identificador Para exemplificar o funcionamento deste operador vamos retornar ao exemplo apresentado na seção II.F.2 e reproduzido com pequena alteração a seguir: Exemplo: #include <iostream.h> // cabeçalho com definição de cout e operador << int i = 1; // identificador definido em nível externo (visibilidade global) int main (void) // função main com nível de visibilidade externa (global) APOSTILA: LINGUAGENS DE PROGRAMAÇÃO C E C++ Angelo Passaro Página III.6 Segunda revisão / 2002 { cout << “\nvariavel i de visibilidade global : ” << i; { // inicio de primeiro bloco aninhado int i = 2; j = 3; // i e j definidos no nivel interno cout << “\nvariavel i de visibilidade interna : “<< i; cout << “\nvariavel j de visibilidade interna : “<< j; cout << “\n\n Que visibilidade de i estamos considerando aqui? “<< ::i; { // inicio do segundo bloco aninhado int i = 0; // identificador i redefinido cou t << “\nvariavel i com visibilidade do segundo bloco aninhado : “ << i; cout << “\n variavel j visivel no segundo bloco aninhado : “<< j; cout << “\n\n Que visibilidade de i estamos considerando neste caso? “<< ::i; } // fim do segundo bloco aninhado cout << “\nvariavel i de visibilidade interna restaurada : “<< i; } /// fim do primeiro bloco aninhado cout << “\nvariavel i de visibilidade global restaurada: ” << i; } // fim da definição de main Observação: Este operador é definido somente para o C++. APOSTILA: LINGUAGENS DE PROGRAMAÇÃO C E C++ Angelo Passaro Página III.7 Segunda revisão / 2002 III.B. Operadores binários O conjunto dos operadores binários e seu significado é apresentado na tabela III.2. Estes operadores são discutidos mais detalhadamente nas próximas subseções. Tabela III.2 : O conjunto de operadores binários e seu significado. operador significado = Operador de atribuição +, -, *, /, % Operadores aritméticos operadores aditivos (soma e subtração) operadores multiplicativos (produto, divisão, resto) == != > >= < <= Operadores relacionais igual a não igual a maior do que maior ou igual que menor que menor ou igual a && || Operadores lógicos AND (e) lógico OR (ou) lógico >> << & | ^ Operadores de atuação bit a bit (bitwise) operador de deslocamento binário à direita operador de deslocamento binário à esquerda AND (e) binário: OR (ou) binário XOR (ou exclusivo) binário @= Operadores de atribuição compostos forma geral dos operadores de atribuição compostos. O símbolo @ representa uma família de operadores binários (aritméticos e bitwise) : +=, *=, >>=, etc Observação: Observem com atenção a diferença de uso entre os operadores lógicos (&& e ||) e os operadores bitwise ( & e | ). A confusão no uso desses operadores costuma ser fonte de dor de cabeça para programadores. Notem, também, que existe uma grande diferença entre o operador binário bitwise AND e o operador unário de endereço (ambos representados pelo símbolo &). APOSTILA: LINGUAGENS DE PROGRAMAÇÃO C E C++ Angelo Passaro Página III.8 Segunda revisão / 2002 III.B.1. Operador de Atribuição ( = ) As linguagens C e C++ implementam apenas um operador de atribuição, cujo símbolo é o sinal matemático de igualdade (=). Contudo, este pode ser utilizado para gerar outros operadores, denominados operadores de atribuição compostos, os quais serão vistos na seção III.B.6. Exemplos : const double PI = 3.14159265; // note-se o uso do qualificador const. Seu uso implica que a // variável cujo identificador é PI deve ser definida na // declaração e esse valor não mais é modificado. Este tipo de // expressão é denominada expressão constante. long int var1, var2 = 20; var1 = var2; double double_var1, double_var2 = PI; double_var1 = double_var2; Observação: Em C, todos os identificadores utilizados em uma função devem ser declarados no início do bloco de definição da função. Em C++ essa restrição não existe. Uma declaração de variável (declaração de identificador) pode ser feita em qualquer ponto do bloco de definição de função. A única restrição é que qualquer identificador deve ser declarado antes de seu primeiro uso, como ocorre no exemplo acima). III.B.2. Operadores aritméticos ( +, -, *, /, % ) Os operadores aritméticos podem ser subdivididos em operadores aditivos ( + e - ) ou multiplicativos (*, /, %). Mesmo usuários em seu primeiro contato com uma linguagem de programação reconhecem, de imediato, quase todos estes operadores e seu uso, uma vez que aparecem costumeiramente em expressões aritméticas. A exceção fica para o operador de “resto” (%), o qual se aplica a operandos da família do tipo inteiro. A aplicação do operador deresto resulta 0 (zero) se a divisão entre os dois operandos resulta exata ou diferente de zero , em caso contrário. O valor de retorno no caso da divisão não exata depende de implementação. Exemplos: long int prim, seg, terc, result; prim = 15; seg = 2; terc = 3; result = prim + seg; // result = 17 result = prim – terc; // result = 12 result = prim * seg; // result = 30 result = prim / seg; // result = 7 result = prim / terc; // result = 5 result = prim % seg; // result = 1 ou seja, existe um resto da divisão result = prim % terc; // result = 0 ou seja, não existe resto da divisão APOSTILA: LINGUAGENS DE PROGRAMAÇÃO C E C++ Angelo Passaro Página III.9 Segunda revisão / 2002 III.B.3. Operadores relacionais (==, !=, >, >=, <, <=) Uma expressão relacional com um operador de comparação resulta o valor false (falso) ou true (verdadeiro) = !false (le-se NOT false). De fato, qualquer expressão escalar pode ser utilizada no lugar de uma expressão de comparação. Quando o valor da expressão escalar é zero significa false, enquanto que um valor diferente de zero (qualquer valor diferente de zero) resulta true. Exemplos: double a = 27, b = 32; a expressão relacional (a < b ) resulta true, a expressão relacional (a >= b) resulta false a expressão relacional ( a == b) resulta false a expressão relacional ( a <= b) resulta true unsigned char char1, char2 ; char1 = ‘a’; // inicializa (define) a variável char1 com a // constante caracter ‘a’ (código ASCII = 97) char2 = ‘A’; // inicializa a variável char2 com a // constante caracter ‘A’ (código ASCII = 65) a expressão relacional (char1 < char2) resulta false, a expressão relacional (char1 > char2) resulta true a expressão relacional (char1 == char2) resulta false, a expressão relacional (toupper(char1) == char2) resulta true, (ver observação a seguir) Observação: toupper() é uma função (ou macro) que transforma uma constante caracter minúscula em maiúscula, se for possível. Consulte a documentação, ou help, do compilador para mais informações. III.B.4. Operadores lógicos ( &&, || ) Os operandos em uma expressão lógica são tratados como true (não zero) ou false (zero). Uma expressão lógica fornece resultados que podem ser zero (false) ou não zero (true). As linguagens C e C++ têm dois operadores lógicos: && (AND) e || (OR). Exemplos do resultado de operações AND e OR lógicos são apresentados nas tabelas III.3 e III.4. Tabela III.3 : Processamento do operador AND lógico false false true true operandos false true false true operador (&&) ------------------ ------------------ ------------------ ------------------ resultado false false false true APOSTILA: LINGUAGENS DE PROGRAMAÇÃO C E C++ Angelo Passaro Página III.10 Segunda revisão / 2002 Tabela III.4 : Processamento do operador OR lógico false false true true operandos false true false true operador ( || ) ------------------ ------------------ ------------------ ------------------ resultado false true true true Exemplos: if (2 || 0) // operação lógica || (OR) entre um valor diferente de zero (2 – true) e // um valor 0 (false). O resultado da expressão lógica é (true) ver tabela III.4. if (2 && 0) // operação lógica && (AND) entre um valor diferente de zero (2 – true) e // um valor 0 (false). O resultado da expressão lógica é (false) ver tabela III.3 III.B.5. Operadores de atuação bit a bit (bitwise : >>, <<, &, |, ^) III.B.5.a. OPERADOR DE DESLOCAMENTO BINÁRIO À DIREITA >> Desloca o conteúdo da variável o número de bits especificado para a direita, preenchendo os bits da esquerda com zeros. Sintaxe : identificador >> n onde identificador é o identificador de um tipo inteiro e n é o número de bits que devem ser deslocados para a direita: Exemplos: unsigned short int algo = 0x09 >>2; // resulta algo = 2 // 0000 0000 0000 1001 >> 2 => 0000 0000 0000 0010 III.B.5.b. OPERADOR DE DESLOCAMENTO BINÁRIO À ESQUERDA << III.B.5.b Desloca o conteúdo da variável o número de bits especificado para a esquerda, preenchendo os bits da direita com zeros. Sintaxe : identificador << n onde identificador é o identificador de um tipo inteiro e n é o número de bits que devem ser deslocados para a esquerda: Exemplo: unsigned short int outro_algo; outro_algo = 0x09 <<2 ; // resulta outro_algo = 36 (em notação decimal) Estes dois zeros são incluídos na operação bits perdidos na operação APOSTILA: LINGUAGENS DE PROGRAMAÇÃO C E C++ Angelo Passaro Página III.11 Segunda revisão / 2002 // 0000 0000 0000 1001 << 2 => 0000 0000 0010 0100 III.B.5.c. OPERADORES BINÁRIOS AND, OR E EXCLUSIVE OR (&, |, ^) III.B.5.C Estes operadores realizam as operações AND (e), OR (ou) ou XOR (ou exclusivo) bit a bit para números inteiros. Exemplos: AND (e) binário (&): unsigned char a = 3, b = 5, c; c = a & b; // resulta c = 1 // operandos: // a = 3 (representação binária 0 0 0 0 0 0 1 1) // b = 5 (representação binária 0 0 0 0 0 1 0 1) // operador & ______________________________________ // resultado c =1 (representação binária 0 0 0 0 0 0 0 1) OR (ou) binário ( | ) unsigned char x = 3, y = 5, z; z = x | y; // resulta z = 7 // operandos: // x = 3 (representação binária 0 0 0 0 0 0 1 1) // y = 5 (representação binária 0 0 0 0 0 1 0 1) // operador | ______________________________________ // resultado z = 7 (representação binária 0 0 0 0 0 1 1 1) XOR (ou exclusivo) binário ( ^ ) unsigned char x = 3, y = 5, z; z = x ^ y; // resulta z = 6 // operandos: // x = 3 (representação binária 0 0 0 0 0 0 1 1) // y = 5 (representação binária 0 0 0 0 0 1 0 1) // operador ^ ______________________________________ // resultado z = 6 (representação binária 0 0 0 0 0 1 1 0) III.B.6. Operadores de atribuição compostos (@=) III.B.6 Os operadores de atribuição compostos formam uma família de operadores nos quais o operador de atribuição (=) é associado a outros operadores binários (aritméticos e bitwise). O símbolo @ representa esses operadores (+, -, *, /, %, >>, <<, &, |, ^). Esses operadores podem ser utilizados em qualquer tipo intrínseco (com exceção do operador de resto, que atua somente sobre inteiros), ponteiros (os quais serão apresentados na seção VI) ou tipos derivados (classes) para os quais foi definida a sobrecarga apropriada do operador (sobrecarga de funções será discutida oportunamente). A aplicação de um destes operadores, como segue: Estes dois zeros são incluidos na operação bits perdidos na operação APOSTILA: LINGUAGENS DE PROGRAMAÇÃO C E C++ Angelo Passaro Página III.12 Segunda revisão / 2002 a @= b; é equivalente, em termos de resultado da operação, à seguinte expressão: a = a @ b; ou seja, a primeira parte do operador composto, representada por @, opera sobre os dois operandos e o resultadoé atribuído ao primeiro operando. Exemplos: c += b; // corresponde a: c = c + b; y −= z; // corresponde a: y = y – z; xx <<= 3; // corresponde a xx = xx << 3 (ver seção III.B.5.b) var1 |= var2; // corresponde a var1 = var1 | var2; (ver seção III.B.5.c) dvar1 ∗= 13.5; // corresponde a dvar1 = dvar1 * 13.5 III.C. Operador Ternário III.C Tabela III.5 : O operador ternário e seu significado. OPERADOR SIGNIFICADO COMENTÁRIOS ?: operador condicional ternário Seja o exemplo: double a = 10.1, b = 100.1, maior; (a > b)? maior = a : maior = b; que deve ser interpretado como segue: ( a > b) : condição Se a condição for VERDADEIRA (true, ou seja, diferente de zero) então a instrução entre o símbolo ? e o símbolo : é executada, ou seja, a variável maior assume o valor a. Se a condição for FALSA (false, ou seja, igual a zero), então a instrução entre o símbolo : e o delimitador ; é executada, ou seja a variável maior assume o valor b. III.D. Outros operadores III.D.1. Pontuadores Os pontuadores apresentados na seção I.H têm significado sintático e semântico para o compilador, no entanto, não causam nenhuma ação (ou seja, não são operadores). Contudo, dependendo de sua localização, muitos pontuadores em C++ podem ser utilizados também como operadores. Veja alguns exemplos na tabela a seguir: operador significado APOSTILA: LINGUAGENS DE PROGRAMAÇÃO C E C++ Angelo Passaro Página III.13 Segunda revisão / 2002 ( ) operador de acionamento (chamada) de uma função. Note-se que aqui o operador envolve o par ( ). [ ] operador de índice de vetores (acesso a componentes de vetores). Note-se que aqui o operador envolve o par [ ]. , o operador vírgula separa uma expressão em subexpressões, como no exemplo: var = (i = 1, j = 2, i+j); que é executado na seguinte ordem: o valor 1 é atribuido à variável i o valor 2 é atribuido à variável j o valor 3 é atribuido à variável var O uso e definição de operadores em C++ será abordado oportunamente. Observação: As vírgulas utilizadas na lista de argumentos de uma função não são operadores. III.D.2. Operadores de seleção de membros As linguagens C e C++ têm dois operadores de seleção de membros, a saber: operador significado . Membro de uma classe (structure) ou union −> Ponteiro para um membro de uma classe (structure) ou union Mais detalhes sobre o uso destes operadores serão apresentados quando da utilização de ponteiros e de tipos de dados derivados. III.D.3. Operador “cast” (conversão explícita de tipo) III.D.3 Apesar dos compiladores das linguagens C e C++ realizarem automaticamente a conversão entre tipos de dados compatíveis, existem situações nas quais uma conversão de tipo explícita é necessária. Nestes casos é utilizado o operador de conversão explícita ou “cast”. O operador “cast” corresponde ao tipo de dado da conversão exigida e pode ser escrito de duas maneiras diferentes: • o tipo é delimitado por parênteses e este conjunto colocado antes da expressão cujo tipo deve ser convertido (por exemplo: (double) alpha); • o tipo é especificado à frente da expressão a ser convertida e a expressão é delimitada por parênteses (exemplo: double (alpha)); APOSTILA: LINGUAGENS DE PROGRAMAÇÃO C E C++ Angelo Passaro Página III.14 Segunda revisão / 2002 O objeto sobre o qual o “cast” é aplicado não sofre, contudo, modificação. Exemplo: int aa = 9, bb = 3, cc = 2; cout << "\n 9/3 = "<< (aa/bb); // o tipo de ambos aa e bb é int e a operação é uma // divisão de inteiros. A divisão é exata. O resultado é 3 cout << "\n 9/2 (sem cast) = "<< (aa/cc); // novamente aa e bb são inteiros e a operação // é uma divisão de inteiros. O resultado é 4 cout << "\n 9/2(com cast 1) = "<< ((double)aa/cc); // neste caso o tipo da expressão aa é // explicitamente modificado para double, utilizando a primeira // forma de exprimir o operador “cast”, antes de ocorrer a // divisão. Agora a operação de divisão ocorre entre um número // double e outro int. O compilador automaticamente faz uma // conversão (implícita) de bb para o tipo de maior precisão (no // caso, double) e a divisão, de fato, é efetuada entre dois // números do tipo double. O resultado é 4.5 cout << "\n 9/2(com cast 2) = "<< (double(aa)/cc); // mesma explicação da instrução anterior. // Aqui é utilizada a segunda forma de exprimir o operador // “cast”. O resultado é 4.5 Observação: As aplicações típicas do operador “cast” são: • forçar uma expressão a apresentar um tipo específico; • forçar que uma expressão aritmética seja realizada com a precisão especificada (caso do exemplo acima); • evitar avisos do compilador quando da execução de conversões implícitas. III.E. Precedência de Operadores III.E A tabela III.6 apresenta a ordem com que os operadores são avaliados numa expressão. Note-se que alguns operadores apresentam a mesma precedência (não são separados por linhas na tabela). Em caso de dúvida, utilizem parênteses para forçar a precedência de uma operação com relação a outra. Tabela III.6 : Ordem de precedência de processamento de operadores Operador Tipo Comportamento :: resolução de escopo passivo APOSTILA: LINGUAGENS DE PROGRAMAÇÃO C E C++ Angelo Passaro Página III.15 Segunda revisão / 2002 ( ) [ ] −> . acionamento de função índice de vetor seleção de membro passivo passivo passivo ++ −− ∼ ! + − ∗ & (cast) sizeof new delete incremento e decremento complemento binário negação lógica sinal unário ponteiro alocação dinâmica ativo passivo passivo passivo passivo passivo passivo passivo −>∗ .∗ ponteiro membro passivo ∗ / % aritmético (multiplicativos) passivo + − aritmético (aditivos) passivo << >> deslocamento de bits passivo < <= > >= relacionais (comparação) passivo == != igualdade e não igualdade passivo & AND bitwise passivo ^ XOR bitwise passivo | OR bitwise passivo && lógico passivo || lógico passivo ?: condicional (ternário) passivo = += −= ∗= /= %= >>= <<= &= ^= |= atribuição e atribuição composta ativos , vírgula passivo APOSTILA: LINGUAGENS DE PROGRAMAÇÃO C E C++ Angelo Passaro Página III.16 Segunda revisão / 2002 EXERCÍCIOS 1. Dadas as seguintes variáveis : int a = 1, b = 2, c = 3, d = 4, e, f = 0; Verifique o resultado das expressões a seguir e o valor final das variáveis a, b, c, d, e, e f.a. e = a && b || d && f (1) b. e = a && (b || d) && f (0) c. e = a <= b || c < d (1) d. e = a++ * --b (e = 1, a = 2, b = 1) e. e = a++ * b-- (e = 2, a = 2, b = 1) f. e = ++a * b-- (e = 4, a = 2, b = 1) g. e = --a * b++ (e = 0, a = 0, b = 3) h. e = a += b * d (e = 9, a = 9) i. e = a -= c * f (e = 1, a = 1) j. e = --a && b || d && f (e = 0, a = 0) 2. Qual o resultado das operações de deslocamento binário apresentadas abaixo (mostre a representação binária)? (Realize a operação manualmente!!!!) unsigned short int a = 0x07 >> 3, b = 0x07 << 3 , c = 13 <<2, d = 0x0D >> 1, e = 4 << 2. 3. Seja o seguinte trecho de código em C. Avalie as expressões e obtenha o valor final de cada uma das variáveis. int a = 1, b = 2, c = 3, d = 4, e, f = 0; e = ++ a * b + c-- * d; f -= e * b + a * c; c = e && f; (a=2, b=2, c=1, d=4, e=16, f=-36) 4. Considere as seguintes definições: APOSTILA: LINGUAGENS DE PROGRAMAÇÃO C E C++ Angelo Passaro Página III.17 Segunda revisão / 2002 unsigned char char1 = 30, char2 = 13; Mostre o resultado das operações apresentadas a seguir: char1 & char2 char1 | char2 char1 ^ char2 char1 >> 2 | char2 <<1 (char1 & char2) | char2 (char1 & char2) | char1 5. Interprete a seqüência de expressões do bloco abaixo, explicando o resultado final para as variáveis envolvidas (considere os operadores aplicados e as regras de precedência). { int a = 1, b, c, d, e, f, g, h ; int m = 3, n, o, p , q, r, s; c = (a && 1); g = (a && 5); e = (a || 5); f = (a || 4); d = (a && 2) || (b = 6); n = (a & 1); o = (a & 5); p = (a | 5); q = (a | 4); r = (a && 1) | (b = 6); h = (a || 8) * (m && (a | 4)); s = (4 << 2) / (32 >> 4); double d_a = 1, d_b = 2.14, d_c, d_d, d_e, d_f; d_b++; d_c = (++d_b > --d_a) ; d_d = (++d_b > d_a--) ; d_e = (d_b < ++d_a) * (d_a * (++d_b)++); d_f = d_b * --d_a + s; }
Compartilhar