Aula 6: Atribuição, scanf e cálculos

Traduzido por Ana Paula Costa

Atribuição

Na aula anterior (aula 5) viu-se como se podem definir variáveis. Agora vamos ver como se pode atribuir um valor a uma variável.

Dar um novo valor a uma variável chama-se atribuição. Em C isto é feito com o operador
 
 

Do lado esquerdo do operador coloca-se a variável, e do lado direito coloca-se o novo valor ou expressão que irá produzir o valor do mesmo tipo que a variável. Exemplos:

  a = 3.0;
  b = 3.0*a;
  c = cos(t);

Errado (assumindo a do tipo float):

  1.0 = a;
  a = TRUE;
  a = 1;

Na verdade, em C o último exemplo está correcto. O C sabe o que queremos e dá uma ajuda convertendo o inteiro 1 no real 1.0.  De qualquer forma, é má prática mistura inteiros com reais e será melhor escrever: a = 1.0;


O símbolo = deve ser distinguido do símbolo matemático =. Nesta fase é interessante fazer-se uma comparação entre o símbolo matemático = e o símbolo de atribuição nas linguagens de programação (= em C). Como exemplo consideremos a seguinte equação matemática
  a = a + 1
Isto, como todos sabemos, não contem uma solução para a. (Em comparação, outro exemplo: a = a2 - 2, contem uma solução, nomeadamente a = 2).
Contudo, nas linguagens de programação deve-se ler a equação de forma diferente:
  a = a + 1;
significa
  (o novo valor de a)     (será)    (o antigo valor de a)     (mais 1)
Ou, por outras palavras: primeiro o valor de a é carregado da memória, depois é-lhe adicionado 1, e finalmente o resultado é colocado de novo em memória. Isto é fundamentalmente diferente da equação matemática. Na maioria das linguagens modernas o símbolo = é utilizado, o que é confuso, especialmente para os programadores novatos. Por essa razão os estudantes são aconselhados a pronunciar o símbolo de atribuição como "torna-se" ou "será" em vez de "é" ou "iguala".


O símbolo = também deve ser distinguido do símbolo de comparação =. Por exemplo a=b ? Mais tarde, iremos aprender como fazer comparações (na aula de "if .. then" e "álgebra booleana"), para a qual se utilizará o símbolo ==.
 
 Para sumariar, o símbolo = é 
   NÃO parte de uma comparação ("a é igual a b?") 
   NÃO parte de uma equação ("a2 = 2a -1")
   É uma atribuição ("a transforma-se em b")


Exemplo

O que se segue mostra um exemplo de um programa que utiliza atribuições, variáveis e constantes. O lado direito mostra o valor das variáveis após cada linha
 
valor de a
depois da execução da linha
valor de b
depois da execução da linha
main()
{
  float a;
  float b;
  float c = 4.3;
  a = 1.0;
  b = c;
  a = a + b + c;
}

 
 
 
 

indefinido
1.0
1.0
9.6


 
 
 
 

indefinido
indefinido
4.3
4.3


Input formatado: scanf

Nas aulas anteriores aprendemos como mostrar os resultados dos cálculos do programa no écran. Com printf podemos fazer com que o nosso programa tenha output. Em muitos casos, nós também queremos que o nosso programa tenha input. O utilizador digita o seu nome, ou introduz números que o programa tem que processar. Ou ainda mais simples, queremos que os utilizadores tenham controlo do programa. Por exemplo, queremos que o utilizador possa parar o programa carregando na tecla escape.
C: com scanf podemos obter informação a partir do teclado. Podem-se ler valores e caracteres do teclado e armazená-los directamente em variáveis especificadas. O formato geral da instrução é

scanf("descrição(ões) de formato", &var1, &var2, ...);

De notar o símbolo &. Isto significa "o endereço de ...". É preciso fornecer o endereço da(s) variável(veis) para a função scanf. Como veremos mais tarde, fornecer o endereço de uma variável é igual a "passar por referência" o que permite que a função possa alterar o valor da variável. De momento, é suficiente dizer que temos que fornecer os endereços das variáveis no scanf. Na analogia com as caixas, pode-se ver o fornecer do endereço como dar a caixa à função que depois a preenche com um valor. 

As descrições de formato são as mesmas que as da instrução de output printf. Por exemplo %d para inteiros, etc. De notar que as variáveis a serem lidas não têm que ser do mesmo tipo. 

Como por exemplo

  // lines starting with these // are cooment
  // always when we use input or output
  // we have to include the standard-I/O library:
  #include <stdio.h>

  main()
  {

  // don't forget to declare the variables we will use
    int n1, n2: integer;

    printf("Please enter two numbers separated by a space\n");
    scanf("%d", &n1);
    scanf("%d", &n2);
    printf("n1 = %d  n2 = %d", n1, n2);
  }

Quando correr, o programa mostrará a mensagem 
  Please, enter two numbers separated by a space
O utilizador deve digitar os dois números
  128 31<return>
(Atenção às convenções que são utilizadas no texto: coisas que o utilizador introduza (digite) aparecem em green italics, e <return> significa pressionar a tecla enter).
Depois o programa mostra
  n1 = 128  n2 = 31


Operações, operadores e operandos

Depois de aprender como atribuir valores, podemos agora ver como efectuar cálculos com os nossos programas. As operações mais básicas são a adição, subtracção, multipicação e divisão:
 
 operador 
 operação 
+
adição
-
subtracção
*
 multiplicação 
/
divisão

Estes quatro operadores, quando utilizados em cálculos, necessitam de dois operandos e são chamados operadores binários. Em C, um operando é colocado do lado esquerdo e outro do lado direito do operador. Como exemplos:
 
 correcto
 errado
3 * a
* a
a + b
3 a +

Estas expressões resultarão em valores que podem ser atribuídos a variáveis como vimos anteriormente: Como um exemplo:

c = 3 * a;

De notar novamente, do lado esquerdo do símbolo de atribuição = temos a variável e do lado direito colocamos a nossa expressão que irá resultar num novo valor para a variável.

Em C existem também operadores unitários que necessitam apenas de um operando:
 

 operador   operação 
++
  incremento
--
 decremento 
!
 negação (álgebra booleana) 
~
 inversão de todos os bits deste inteiro
-
 negação do número
&
 endereço de ..

Por exemplo
  i++;
   --k;
Incrementa o valor de i e decrementa o valor de k em 1, respectivamente. O operador pode ser colocado antes ou depois do operador. A diferença está no momento em que a variável muda o seu valor, antes da execução do resto da instrução (++i) ou depois (i++). Por exemplo
 

i = 1;
j = i++;

no final
i é igual a 2
j é igual a 1

i = 1;
j = ++i;

no final
i é igual a 2
j é igual a 2

Os operadores ! e ~ serão estudados depois na aula sobre álgebra linear.
O operador obtem-endereço será discutido na aula sobre ponteiros.
O operador unário - retorna o número negado (floating point ou inteiro).


Combinações de cálculo e atribuição

Em C existe a peculiar e confusa possibilidade de usar cálculo e atribuição ao mesmo tempo. Por exemplo:
   c += a;
que é equivalente a
   c = c + a;
Qualquer operador binário pode ser utilizado desta forma (*=, /=, +=, -=).
Isto pode ser confuso e como tal deve ser evitado. Por outro lado, pode prevenir erros. Por exemplo:
  matrixelements[i+2*k-offset][n+m-f] = matrixelements[i+2*k-offset][n+m+f] + matrixelements[i+2*l+offset][n+m-f]
É fácil de cometer um erro de escrita aqui. Na verdade existe um erro. Localizou-o?
Mais simples e mais legível seria:
  matrixelements[i+2*k-offset][n+m-f] += matrixelements[i+2*l+offset][n+m-f]

Matemática de Inteiros


Os operadores abordados na secção anterior são usados para cálculos reais (floating point calculations). Para cálculos inteiros (usada para tipos como byte. word, integer, longint, etc.), o operador da divisão funciona de forma um pouco diferente. Vamos imaginar o cálculo de, por exemplo, 7/3. Como se aprendeu na escola primária, isto é igual a 2 com resto de 1 a ser dividido por 3:
 
 

7
   
1
------
   = 
2  + 
------
3
   
3

Em C existem dois operadores / e % que reproduzem estes resultados. Exemplo:
 

 expressão 
 resultado 
 7 / 3
2
7 % 3
1

Estes substituem o operador floating-point /. Os outros três operadores (*, +, -) são os mesmos para números inteiros.


Prioridade

No caso de existir mais do que um operador numa expressão, as regras normais da matemática são aplicadas para determinar qual é avaliada primeiro. Os operadores de divisão e multiplicação têm a precedência mais alta. Assim, quando se escreve
   a = 1 + 3 * 2;
O resultado será 7.
Se se pretender alterar a ordem pela qual os operadores são avaliados, colocam-se parentesis ( e ). Assim, por exemplo
  a = (1 + 3) * 2;
irá resultar em 8. Colocar parentesis não custa!
  a = (1 + 3) - (4 + 5);

Exemplos

main()
 /* an example floating point calculation */
{
  double x, y, sum, diff, divis;

  printf("Give the value of the first variable x:\n");
  scanf("%f", &x);
  printf("Give the value of the second variable y:\n");
  scanf("%f", &y);
  sum = x + y;
  printf("The sum of %f and %f is %f\n", x, y, sum);
  diff = x - y;
  printf("The difference between %f and %f is %f\n", x, y, diff);
  divis = x / y;
  printf("%f divided by %f is %f\n", x, y, divis);
}

irá produzir ao correr:

Give the value of the first variable x:
3.4
Give the value of the second variable y:
1.8
The sum of 3.4000 and 1.8000 is 5.2000
The difference between 3.4000 and 1.8000 is 1.6000
3.4000 divided by 1.8000 is 1.8889



main()
 /* an example integer calculation */
 /* note the different format specifiers in printf and scanf */
{
  int x, y, sum, diff, divis, divr;

  printf("Give the value of the first variable x:\n");
  scanf("%d", &x);
  printf("Give the value of the second variable y:\n");
  scanf("%d", &y);
  sum = x + y;
  printf("The sum of %d and %d is %d\n", x, y, sum);
  diff = x - y;
  printf("The difference between %d and %d is %d\n", x, y, diff);
  divis = x / y;
  divr = x % y;
  printf("%f divided by %d is %d plus %f/%d\n", x, y, divis, divr, y);
}

irá produzir ao correr:

Give the value of the first variable x:
13
Give the value of the second variable y:
5
The sum of 13 and 5 is 18
The difference between 13 and 5 is 8
13 divided by 5 is 2 plus 3/5


Teste Rápido:

Para testar os conhecimentos sobre o que aprendeu nesta aula, prima aqui para fazer um teste on-line. De notar que este Não é o formato que será utilizado no teste final!

Peter Stallinga. Universidade do Algarve, 10 October 2002