MC102MN

Introdução a Algoritmos e programação de computadores

Aula IV, básico de funções e condicionais

Básico de funções

Já vimos em sala de aula como escrever a função main e como usar funções de math.h. Mesmo isso estando reservado para mais à frente no curso, eu acho legal começarmos a vermos funções agora. Uma função é assim:

<tipo> <nome>(<tipo1> <nome1>, <tipo2> <nome2>, ...) {
  <declarações de variáveis>
  <bloco de código>
  return <valor>;
}

De agora em diante, os exercícios serão passados para vocês escreverem funções que executam o código que eu pedir, podendo, é claro, escrever e usar outras funções para ajudar a vida de vocês. Funções são interessantes porque te dão todo um nível de organização de código diferente, e tornam os programas bem mais fáceis de entender.

Uma função é uma estrutura útil pra usar quando você tem o mesmo pedaço de código repetido em vários lugares do programa e quer usá-lo mais de uma vez. A idéia é que, quando você escrever nome(param1, param2, …), o compilador vai executar o código da função, pegar o resultado retornado (pelo comando return) e usar na expressão. Então, por exemplo se eu tenho uma função

double quadrado(double x) {
  return x*x;
}
e mais na frente no programa eu faço
a = quadrado(2) - quadrado(5*c-4*b)
o compilador vai executar e substituir pelos seus valores corretos (ie, vai aparecer 2*2=4 no lugar de quadrado(2)).

Uma função então torna muito fácil pegar esse mesmo trecho de código e executar várias vezes. Isso permite que seus programas façam mais coisas sendo mais simples de entender. Eu recomendo que vocês usem funções daqui pra frente sempre que quiserem escrever algo localmente contido, que aí se forem precisar do resultado em outro trabalho podem reusar numa boa.

Escopo

Funções são o primeiro construto que utilizaremos em sala de aula que depende do conceito de escopo para se entender. Digamos que você veja o seguinte código:

int f1() {
 int x = 2;
 return x;
}

int f2() {
  int x = 3;
  return x;
}

int main(int argc, char *argv[]) { 
  int x = 4;
  f1();
  f2();
  printf("%d", x);
  return 0;
}

Qual o valor de x usado em main?

A resposta para isso é que uma variável, para ser usada em um bloco de código (incluindo uma função), tem que ter sido declarada ou nele ou em um bloco que o contém. É como se funções (e qualquer bloco de código) criassem caixas pretas, onde o valor de todas as outras variáveis é ignorada, e onde aquele código vá ser executado.

Condicionais, if

Agora vamos ver três estruturas condicionais, que permitem escolher que código será executado. A primeira é o if:

if (condicao) { 
  <bloco de codigo>
}

ou

if (condicao) { 
  <bloco de codigo>
} else {
  <bloco de codigo>
}

ou ainda

if (condicao) { 
  <bloco de codigo>
} else if (condicao 2) {
  <bloco de codigo>
} else if (condicao 3) {
  <bloco de codigo>
} else {
  <bloco de codigo>

O que if faz é executar o bloco de código se, e somente se, a condição for verdadeira. Caso contrário, caso exista um bloco else, ele executa o que está no bloco else. Se existirem vários ifs em sequência, é executado apenas o primeiro bloco de código cuja condição é verdadeira (ou o else final, se existir, caso contrário).

If é a primeira construção de C em que podemos usar chaves opcionais. Caso o bloco de código seja apenas uma linha, podemos omitir as chaves. Ou seja, os dois códigos abaixo são equivalentes:

if (x > 10)
  y -= 2*x;
else 
  y += 4;
if (x > 10) {
  y -= 2*x;
} else {
  y += 4;
}

mas o seguinte código é um erro de sintaxe

if (x > 10)
  y -= 2*x;
  z += 1;
else 
  y += 4;

já que apenas a linha com "y -= …" é contada como dentro do if, tem-se um else solto ali na frente. Ao longo dessa matéria eu prefiro que vocês sempre coloquem as chaves.

  • Uma nota sobre indentação

    Como vocês viram, em todos os exemplos de código que eu coloquei até agora, o programa segue uma formatação parecida. Sempre que você abre um novo bloco de código, coloque alguns espaços (ou um tab, como preferir) e escreva o novo bloco de código alinhado mais para a direita que o anterior. Assim, fica fácil entender a estrutura do código sem precisar processar as chaves. Por exemplo

    bloco 1 
    bloco 1
      bloco 2
      bloco 2
        bloco 3
    bloco 1
    

    não deixa dúvidas sobre o que está "dentro" do que. Pode não parecer óbvio agora, mas com o tempo vocẽs se acostumarão com isso.

Condicionais, switch

Um outro comando para fazer condicionais em C é switch. Ao contrário de if, que opera com qualquer expressão, switch usa apenas o valor de uma expressão e testa valores específicos. Por exemplo,

switch (x%3) {
 case 0: printf("é divisível por 3\n");
   break;
 case 1: printf("tem resto de 1 se vc divide por 3\n");
   break;
 case 2: printf("tem resto 2\n");
   break;
 default: printf("socorro, o mundo não faz mais sentido!\n");
}

A forma geral do comando switch é

switch (<expressao>) {
  case <valor>: 
      <bloco de codigo>
      break;
  case <outro valor>:
      <bloco de codigo>
      break;
  ...
  default:
      <bloco de codigo>
}

Uma possibilidade interessante do switch é que, se você remover os breaks, ele continua executando os blocos em sequência. Por exemplo, um programa bobo para tornar um número divisível por quatro é:

switch (x % 4) {
 case 3: x--;
 case 2: x--;
 case 1: x--;
}

Assim, caso o resto seja 3 todos os decrementos serão executados; caso seja 2, apenas os dois últimos, etc. Switch pode ser usado com caracteres também;

switch(sexo) {
  case 'm': printf("É homem\n");
    break;
  case 'f': printf("É mulher\n");
    break;
  default:
     printf("É...\n");
}

Condicionais, operador ternário

O último jeito de calcular condicionais em C é com o operador ternário. A sua forma geral é

<expressao>? <caso verdadeiro>:<caso falso>

Por exemplo,

x = (x % 2 == 1) ? (3*x+1) : (x/2);

Isso, se x é ímpar, atribui a x o valor 3x + 1, e se x é par atribui o valor x/2.

Eu prefiro que vocês não usem o operador ternário a não ser que seja necessário. E, se usarem, sempre coloquem parênteses.

Author: Alexandre Tachard Passos <alexandre.tp@gmail.com>

Date: 2010-08-18 22:52:32 BRT

HTML generated by org-mode 6.21b in emacs 23