Prof. Brauliro Gonçalves Leal
2021
Introdução à Programação
CCMP0041
Estude
Estude
Aula
Conteúdo
Aula
Aula
Conteúdo
5.Operadores
Operadores Aritméticos
Os operadores da Linguagem C é o conjunto de símbolos que representa as operações básicas da matemática:
Operador Ação Exemplo
– menos unário a = –b
+ mais unário a = +b
++ incremento ++a, a++
–– decremento ––a, a––
* multiplicação a = b * c
/ divisão inteira a = b / c
/ divisão real a = b / c
% resto da divisão inteira a = b % c
+ soma a = b + c
Operadores Aritméticos
Erros a Evitar ao usar o Operador /
O operador / é usando para duas operações de divisão.
A divisão inteira, envolvendo variáveis do tipo int, resulta em um valor do tipo int e, portanto, não possui parte fracionária.
A divisão real, envolvendo variáveis do tipo float ou double, resulta em um valor do tipo float ou double e, portanto, possui parte fracionária.
Como são resultados de tipos diferentes, requerem formatos de impressão diferentes.
É preciso saber cada resultado das operações, por exemplo:
int a = 5 , b = 2 ; float x = 3.0, y = 6.0;
x = a/b; // x tem parte fracionária igual a zero porque a e b são int a = x/y; // a não tem parte fracionária porque a é int
Operadores Lógicos
Os operadores da Linguagem C é o conjunto de símbolos que representa as operações básicas da lógica:
Operador Ação Exemplo
> maior que a > b >= maior ou igual a a >= b < menor que a < b <= menor ou igual a a <= b == igual a a == b != diferente de a != b
Operador Ação Exemplo
! negação lógica !a
&& and a && b
|| or a || b
Operador de Atribuição
Erros a Evitar ao usar Operador = e ==
Os operadores = e == podem ser trocados em expressões lógicas.
É comum usar = em lugar de ==.
O compilador não identifica este erro.
Operador Ação Exemplo
= atribuição a = b
Outros Operadores
O ponto e vírgula (;) não é operador, ele é o delimitador de comando. Ele não faz parte de expressões e, sim, indica seu fim.
Há outros operadores na Linguagem C, que serão vistos a seu tempo.
Operador Ação Exemplo
( ) parêntesis a = b*(c+d)
sizeof função a = sizeof(int)
Precedência e Associatividade de Operadores
A precedência dos operadores estabelece regras para avaliação de expressões quando nelas há mais de um operador. A a seguir lista os operadores em ordem decrescente de precedência.
Alguns operadores possuem mesma precedência, como é o caso de {+ –}, sendo necessário estabelecer a associatividade entre eles, que é dada pela direção de ocorrência na expressão.
A a seguir indica esta direção como "da esquerda para a direita" (e–d) e "da direita para a esquerda" (d–e).
No caso de uma expressão com {+ –}, que tem direção é e–d, a subtração é efetuada antes da adição.
Precedência e Associatividade de Operadores
e–d: da esquerda para a direita; d–e: "da direita para a esquerda"
Precedência (Maior) Associação ( ) ! ++ –– – * sizeof d–e * / % e–d + – e–d < <= > >= e–d == != e–d && || = += –= *= /= d–e , Menor
Expressões Lógicas
As expressões lógicas dão resultado verdadeiro ou falso.
São compostas por operadores relacionais (> >= < <=), operadores lógicos (&& || == !=). Podem ainda conter expressões aritméticas.
A linguagem C expressa suas condições lógicas em falso (0) e verdadeiro (diferente de 0, representado por 1).
A tabela abaixo mostra exemplos de expressões lógicas em matemática, em C e seus correspondes valores e condições lógicas.
Expressão Lógica Expressão Lógica em C Valores de x, y, z Valor Lógico
em C Valor Numérico em C x ≥ 10 x >= 10 x = 9 false 0 x > 10 e y < 20 (x > 10) && (y < 20) x = 11, y = 15 true 1 x + y = 5 ( x + y ) == 5 x = 1, y = 5 false 0 x + y ≠ 5 ( x + y ) != 5 x = 1, y = 5 true 1 x > 10 ou y < 20 (x > 10) || (y < 20) x = 11, y = 15 true 1
Expressões Lógicas
A tabela verdade é usado em lógica para determinar o valor lógico de uma expressão, apresenta os resultados das tabelas verdade &&, || e suas negações.
A B A && B A || B !(A && B) !(A || B) !A !B
V V V V F F F F
V F F V V F F V
F V F V V F V F
Expressões Lógicas
Qual expressão lógica para verificar:
a) uma pessoa é de maior: idade >= 18 :: no Brasil
b) uma pessoa é obrigada a votar: (idade >= 18) && (idade <= 70) :: no Brasil c) condição de existência de raiz quadrada real: x >= 0, x é float
d) condição de existência de logaritmo: x > 0, x é float e) x é um número par: (x % 2) == 0, x é int
f) x é um número ímpar: (x % 2) != 0, x é int
Expressões Lógicas
Qual expressão lógica para x nos intervalos:
a) [a,b] – a ≤ x ≤ b – fechado tanto à esquerda quanto à direita: (a <= x) && (x <= b) b) (a,b] – a < x ≤ b – aberto à esquerda e fechado à direita: (a < x) && (x <= b)
b) [a,b) – a ≤ x < b – fechado à esquerda e aberto à direita: (a <= x) && (x < b) c) (a,b) – a < x < b – aberto tanto à esquerda quanto à direita: (a < x) && (x < b)
Qual o significado da expressão lógica:
a) (x <= a) || (x >= b) – o valor lógico de x ∊ (a,b) é FALSO b) (x < a ) || (x >= b) – o valor lógico de x ∊ [a,b) é FALSO
Expressões Aritméticas
As expressões aritméticas envolvem operadores de adição (+), subtração (–), multiplicação (*), divisão (/) e módulo (%). Estes símbolos (+ – * / %) são denominados operadores aritméticos.
Operador de Atribuição
A expressão abaixo, em linguagem C, significa de que lado direito do igual é valiado e atribuído ao lado esquerdo, ou seja, a variável x é somada com a variável y e o resultado é atribuído à variável z.
O operador de atribuição (=) define dois lados, o lado à sua direita e o lado à sua esquerda. O seu significado não é o de igualdade matemática entre os dois lados.
A atribuição significa que o lado direito é avaliado e seu resultado é escrito no lado esquerdo. O valor que o lado esquerdo possuía, antes da atribuição, é perdido, dando lugar ao valor do lado direito.
float x = 10.0, y = 20.0, z; z = x + y;
Operador de Atribuição
No caso do comando z = x + y temos a variável z, x e y são regiões na memória da máquina do tamanho do tipo float.
Na região correspondente a x foi escrito o valor 10.0. Na região correspondente a y foi escrito o valor 20.0. A região correspondente a z permanece sem valor inicial.
Para avaliar a expressão x + y, a CPU busca os valores destas variáveis na memória principal, faz a soma das duas e obtém o valor 30.0. O lado direito tem valor igual a 30.0 e está guardado na CPU.
Em seguida a CPU escreve o valor 30.0 na região de memória de nome z, ou seja, a CPU atribui o valor 30.0 ao nome z.
atribuir – a operação de escrever na memória da máquina.
float x = 10.0, y = 20.0, z;
rvalue x lvalue
A variável pode ser char, int, float ou outro tipo válido. A expressão pode ser lógica ou aritmética ou mista.
O operador de atribuição divide uma expressão em dois lados, o lado esquerdo e o lado direito. O lado esquerdo do operador de atribuição (=) é chamado de lvalue, e o lado direito é denominado rvalue.
O lvalue não podem ser constante porque a atribuição modifica o seu valor, ocorre escrita na memória RAM.
O lvalue é uma variável para que possa ter seu valor modificado, pois o operador de atribuição requer escrita na memória RAM.
O rvalue podem ser ou conter constantes e/ou variáveis porque seus valores não são alterados, são apenas usados, ocorre apenas leitura da memória RAM.
Os rvalues devem possuir valores válidos para que os lvalues correspondentes sejam válidos. Na programação tem uma regra: entra lixo, sai lixo.
Como bons profissionais, essa regra tem que mudar para: entra lixo, sai um aviso que entrou lixo. Acostumem–se a verificar se os valores iniciais dos rvalues foram atribuídos ou lidos.
Transbordamento de Dados
Ocorre o transbordamento de dados (buffer overflow e buffer underflow) ocorre quando se faz acesso indevido ou sobrescreve a memória e corrompe endereços adjacente a ela. Este problema é comum em C porque ela permite acesso de baixo nível, não checa limites superiores ou inferiores de dados e não proveem proteção contra acesso indevido ou sobrescrita da memória.
Um exemplo são as strings e o outro são os vetores e matrizes (arrays), ambos são indexados. Se os valores dos índices vão além do permitido pode ocasionar acesso indevido à memória. Cabe ao programador evitar tais erros.
Promoção de Tipo de Dado em Expressões
Expressões que possuem operandos de vários tipos tem seus valores promovidos para um só tipo. O compilador faz esta promoção automaticamente conforme ilustrado pela figura abaixo.
promoção de tipo – operando de menor tamanho ou precisão é
promovido automaticamente para o de maior tamanho ou precisão (implicitamente)
Algoritmo de Promoção de Tipo
se um dos operandos é long doubleentão o outro é promovido a long double senão se um dos operandos é double
então o outro é promovido a double senão se um dos operandos é float
então o outro é promovido a float
senão se um dos operandos é unsigned long
então o outro é promovido a unsigned long senão se um dos operandos é long
então o outro é promovido a long
senão se um dos operandos é unsigned int
então o outro é promovido a unsigned int
Caso especial adicional: Se um operando é long e o outro é unsigned int, e se o valor da unsigned int não pode ser representado por um long ambos os operandos são promovidos para unsigned long.
Promoção de Tipo
De modo geral, a ordem da promoção dos tipos de dados em expressões, exceto os tipos com modificador unsigned:
Cast - Promoção de Tipo Explícita
O valor de c é igual a 1.000000 porque não há promoção de tipo, a e b são int.
Ao dividir inteiros, ou expressões matemáticas que resultem em inteiros, programas em C truncam os resultados, abandonam a parte fracionária, ficando apenas com a parte inteira.
Para obter os resultados corretos é necessário converter o numerador ou o denominador, neste caso em float, manualmente (explicitamente), um deles é suficiente.
cast de tipo – operador que altera o tipo de um operando manualmente
(explicitamente) pelo programador int a = 9, b = 5;
float c;
Cast - Promoção de Tipo Explícita
O valor de c é igual a 1.800000.
Observe que: c = (float)(a/b) resulta em c = 1.000000 int a = 9, b = 5;
float c;
c = (float)a/b; // cast do numerador, um só cast
ou
c = a/(float)b; // cast do denominador, um só cast
ou
Cast
#include <stdio.h> int main(void){ int a = 9, b = 5; float c; c = (float)a/b; printf( "\n 1. (float)a/b = %f ", c ); c = a/(float)b; printf( "\n 2. a/(float)b = %f ", c ); c = (float)a/(float)b; printf( "\n 3. (float)a/(float)b = %f ", c ); c = (float)(a/b); printf( "\n 4. (float)(a/b) = %f ", c ); printf( "\n\n\n" ); return 0; }Cast - Promoção de Tipo Explícita
Converter o valor de um tipo de dados para outro é denominado cast.
Ao executar um cast de tipos, o valor do operando é forçado a ser de um tipo particular, não importando a regra de conversão de tipos. Sua sintaxe depende do operando, dada por:
(tipo de dado) constante (tipo de dado) variável (tipo de dado) (constante) (tipo de dado) (variável) (tipo de dado) (expressão) (tipo de dado) (função)
Cast
Convertendo valores int para float. #include <stdio.h>
#include <stdio.h> int main ( void ){ int n;
printf( "Digite o valor int: " ); scanf ( "%d", &n );
printf( "float(n) = %f", (float)(n) );
printf( "\n\n\n" ); return 0;
}
Observe que o formato no printf é para variável de tipo float pois o valor da variável n foi alterado o seu correspondente valor float apenas na função printf.
A variável n continua sendo do tipo int, apenas o seu valor impresso foi alterado para float.
Cast
Exemplo Convertendo valores float para int e char. #include <stdio.h>
int main ( void ){ float x;
printf( "Digite o valor float: " ); scanf ( "%f", &x );
printf( "\n int (x) = %d", (int ) x ); printf( "\n char(x) = %c", (char) x ); printf( "\n\n\n" );
return 0; }
A variável x continua sendo do tipo float, apenas o seu valor foi alterado para int e char, conforme o caso.
Funções Matemáticas
Função Significado
sin, cos, tan Funções trigonométricas
asin, acos, atan Funções trigonométricas inversas sinh, cosh, tanh Funções hiperbólicas
sqrt Raiz quadrada
exp Função exponencial
log Logaritmo natural
log10 Logaritmo na base 10
abs Valor absoluto, parâmetro int
fabs Valor absoluto, parâmetro double
A Biblioteca Padrão possui muitas funções matemáticas para tratamento numérico. Na tabela abaixo estão listadas as funções comumente usadas.
O tipo de dados default das funções matemáticas é o double.
Protótipos das Funções Matemáticas
int abs (int i ); double fabs (double d );
double sin (double arco); // arco em radianos double cos (double arco);
double tan (double arco); double asin (double arco); double acos (double arco); double atan (double arco);
double ceil (double num ); // arredonda para cima double floor(double num ); // arredonda para baixo double log (double num );
double log10(double num );
double pow (double base, double exp); double sqrt (double num );
Funções Matemáticas
#include <stdio.h> #include <math.h> int main( void ){
double x = 2.0, y = 2.5;
printf( "\n Funções Matemáticas " ); printf( "\n ---" ); printf( "\n sqrt(x) = %lf", sqrt (x) ); printf( "\n exp (x) = %lf", exp (x) ); printf( "\n ln (x) = %lf", log (x) ); printf( "\n log (x) = %lf", log10(x) ); printf( "\n pow (x,y) = %lf", pow (x,y)); printf( "\n sin(x) = %lf", sin (x) ); printf( "\n cos(x) = %lf", cos (x) ); printf( "\n ---" ); return 0;
Gerando Dados de Entrada
A Biblioteca Padrão possui a função int rand( void ) que gera um número inteiro aleatório entre 0 e a constante RAND_MAX, requer < stdlib.h>.
Pode-se usar o operador módulo para limitar o valor a uma faixa menor.
Esta função é muito útil para gerar dados de entrada, evitando digitações enfadonhas.
Exemplo O programa gera dados de entrada. #include <stdio.h>
#define MAX 10
int main ( void ){
int x = rand() % MAX; // reduz a faixa para 0 a MAX-1. printf(" x = %d", x );
return 0; }
Estrutura e Estilo
A Linguagem C permite a inclusão de espaços, tabulações e quebras de linha extras mas eles são ignorados pelo compilador, exceto em strings).
Recomenda-se um comando por linha para melhor legibilidade do programa fonte. Quando for necessário, divida a instrução em mais de uma linha.
Recomenda-se a endentação, que consiste deslocar para direita os comandos de um bloco. Desta forma, melhora a visualização do programa-fonte e a posição relativa dos blocos e seus comandos.
Questões
1. Explique o resultado do programa abaixo.
2. Explique o resultado do programa abaixo.
Corvo
O Corvo é uma ave de médio a grande porte, vivem em bandos com estrutura hierárquica bem definida. O corvo simboliza a astúcia, a criatividade, a sabedoria, a fertilidade, a esperança. São conhecidos pela sua capacidade de fabricar e utilizar pequenos instrumentos; em testes específicos de inteligência animal, costumam atingir altas pontuações.