Programas

#include <stdio.h>

int main(void)
{
  printf("To C or not to C, ");
  printf("that is the question.\n");
  return 0;
}

Execução

Para ser executado, um programa em C tem primeiro de ser traduzido para código-máquina.

A tradução é efetuada por programa compilador.

Nestas aulas: vamos usar o GCC (GNU Compiler Collection).


Fases de tradução

Pré-processamento

o pré-processador interpreta diretivas (linhas que começam por #)

Compilação

o compilador traduz o código C para código-máquina

Ligação

o ligador (linker) combina o código-máquina gerado com as bibliotecas necessárias


Em sistemas GNU/Linux: o pré-processador, compilador e ligador são executados em sequência pelo comando gcc.

Compilar, ligar e executar

Invocamos o compilador usando o interpretador de comandos Linux (shell):

$  gcc -o hello hello.c 

Produz um ficheiro hello que podemos executar:

$ ./hello
To C or not to C, that is the question.

Estrutura de programas simples

directivas

int main(void)
{ 
    instruções
}

Directivas

   #include <stdio.h>

Funções

Função main

   int main(void)
   {
      ....
      return 0;
   }

Instruções

  printf("To C or not to C, ");
  printf("that is the question.\n");
  return 0;
   To C or not to C, that is the question.

Instruções (cont.)

  printf(
     "To C or not to C, "
  );
  printf("To C or "); printf("not to C, ");

Comentários

   /* Isto é um comentário */

   /*
     Autor:   Pedro Vasconcelos
     Ficheiro: hello.c
     Programa: Imprime uma mensagem de exemplo
   */

Comentários (cont.)

Atenção: esquecer de fechar um comentário pode fazer com que o compilador ignore parte do programa.

   printf("To be ");    /* comentário aberto
   printf("or not to be; ");   /* fechado */
   printf("that is the question.\n");

Comentários (cont.)

   // Isto é um comentário

Variáveis e atribuições

Tipos

Tipos (cont.)

Declarações

As variáveis têm de ser declaradas antes do uso:

   int altura;
   float raio;

Podemos declarar múltiplas variáveis do mesmo tipo duma só vez:

   int altura, largura, profundidade;
   float raio, massa;

Declarações

Até C89: todas as declarações têm de ocorrer antes das instruções.

int main(void) {
   /* declarações de variáveis */
   int altura, largura;
   float raio;

   /* seguem-se instruções */
   ...
}

Em C99: declarações e instruções podem ser misturadas (desde que a declaração ocorra antes do uso).

Atribuição

Podemos definir ou modificar o valor de uma variável usando uma atribuição.

   int altura;   // declaração
   altura = 8;   // atribuição

Atribuição (cont.)

No lado direito duma atribuição podemos usar expressões e.g.
constantes, varáveis e operações.

   int altura, largura, area;
   altura = 8;
   largura = 3;
   area = altura * largura;
       // area é 24

Exemplo

Um programa para calcular o volume \(V\) de uma caixa retangular.

Exemplo:

 

\[ V = 11 \text{cm} \times 5 \text{cm} \times 6 \text{cm} = 330 \text{cm}^3 \]

volume.c

#include <stdio.h>

int main(void) {
   int l, w, h, v;   // dimensões e volume

   l = 11;    // comprimento
   w = 5;     // largura
   h = 6;     // altura
   v = l*w*h; // cálculo do volume

   printf("LxWxH: %d*%d*%d (cm)\n", l,w,h);
   printf("Volume: %d (cm^3)\n", v);
   return 0;
}

Imprimir valores

Podemos usar a função de bibloteca printf para imprimir valores das variáveis. Exemplo:

   int alt;
   alt = 6;
   printf("Altura: %d cm\n", alt);

Imprime o texto:

   Altura: 6 cm

%d é um campo que é substituido pelo valor duma variável inteira em decimal.

Imprimir valores (cont.)

Para valores float usamos o campo %f.

   float custo;
   custo = 123.45;
   printf("Custo: EUR %f\n", custo);

Resultado:

   Custo: EUR 123.449997

Imprimir valores (cont.)

Para forçar formatação com \(n\) casas decimais usamos %\(.n\)f:

Exemplo:

   printf("Custo: EUR %.2f\n", custo);

Resultado:

   Custo: EUR 123.45

Imprimir valores (cont.)

Podemos formatar vários valores num só printf:

   printf("Altura: %d cm; Custo: EUR %.2f\n",
          alt, custo);

Atenção:

Ler valores

   int n;
   scanf("%d", &n);

Ler valores (cont.)

Para ler um float não necessitamos de especificar casas decimais.

   float x;
   scanf("%f", &x);

Funciona com ou sem casas decimais na entrada; exemplos:

   123
   123.4
   123.4567

Exemplo revisto

Vamos alterar o programa de exemplo anterior para ler as dimensões da caixa.

volume.c revisto

#include <stdio.h>

int main(void) {
   int l, w, h, v;   // dimensões e volume

   printf("L=?"); scanf("%d", &l);
   printf("W=?"); scanf("%d", &w);
   printf("H=?"); scanf("%d", &h);
   v = l*w*h; // cálculo do volume

   printf("LxWxH: %d*%d*%d (cm)\n", l,w,h);
   printf("Volume: %d (cm^3)\n", v);
   return 0;
}

Inicializações

   int x, y;
   y = x + 1;  // variável x não-inicializada

Inicializações (cont.)

   int alt = 8;
   int alt = 8, larg = 5, comp = 11;
   int alt, larg, comp = 11;
     // só inicializa uma variável (comp)

Identificadores

Exemplos válidos:

   times10   get_Next_Char   _done

Exemplos inválidos:

   10times   get-Next-Char   máximo

Idetificadores (cont.)

   get_next_char
   get_next_Char
   get_Next_Char

são identificadores diferentes (seria confuso usá-los num mesmo programa...).

Palavras reservadas

Não podemos usar as seguintes palavras reservadas como identificadores.

auto      enum      restrict   unsigned
break     extern    return     void
case      float     short      volatile
char      for       signed     while
const     goto      sizeof     _Bool
continue  if        static     _Complex
default   inline    struct     _Imaginary
do        int       switch
double    long      typedef
else      register  union

Definir constantes

#define INCHES_PER_METER   39.3701
   /* factor de conversão:
      polegadas por cada metro */

Pre-processamento

O pré-processador substitui as macros textualmente.

Exemplo:

   inches = meters * INCHES_PER_METER;

após processamento fica:

   inches = meters * 39.3701;

Exemplo

Um programa para calcular a área de uma circunferência.

A área de uma círcunferência de raio \(r\) é \[ A = \pi r^2 \] (onde \(\pi\) é a constante \(3.14159\ldots\)).

area.c

#include <stdio.h>

#define PI 3.14159 

int main(void) {
   float raio, area;
   printf("Raio da circunferência?");
   scanf("%f", &raio);
   area = PI * raio * raio;
   printf("Área: %f\n", area);
   return 0;
}

Estrutura de programas

Um programa em C é uma sequência de símbolos ("tokens"):

Estrutura de programas

Exemplo: a instrução

   printf("Área: %f\n", area);

contém sete símbolos:

printf identificador
( pontuação
"Área: %f\n" cadeia de carateres
, pontuação
area identificador
) pontuação
; pontuação

Layout de programas

#include <stdio.h>
#define PI 3.14159 
int main(void) {float raio,area;printf(
"Raio da circunferência?");scanf("%f",&raio);
area=PI*raio*raio;printf("Área: %f\n",area);
return 0;}

Layout de programas

Devemos usar espaços, tabulações e mudança de linha para aumentar a legibilidade do programa:

Salientar a sintaxe

Exemplo

#include <stdio.h>

#define PI 3.14159

int main(void) {
   float raio, area;

   printf("Raio da circunferência?");
   scanf("%f", &raio); 
   area = PI * raio * raio;
        // calcular a área
   printf("Área: %f\n", area);
   return 0;
}