Username: Password:

.Editar, compilar, testar

Editar

Os editores modernos são capazes de reconhecer a síntaxe das linguagens de programação e mostram varios elementos com cores diferentes (palavras reservadas, cadeias de caracteres, comentários etc...). Este processo é chamado «syntax highlighting».

O programa é escrito num ficheiro de texto com um programa chamado genericamente «editor». Este tipo de programa não deve ser confundido com um programa de processamento de texto como o Word ou o Open Office. Um programa de processamento de texto acrescenta ao ficheiro indicações acerca da formatação (tamanho dos caracteres, tipo de letras etc ...), é adaptado à escrita de relatórios ou cartas mas não é adaptado à escrita de programas. Um editor guarda no ficheiro apenas a informação visível no ecrã ou seja o texto. Muitos editores têm a capacidade reconhecer a sintaxe da linguagem de programação usada e apresentam o programa com cores o que facilita a leitura.

O editor é a ferramenta de base do programador. Existem muitas opções conforme o sistema operativo que está a usar (Windows, MacOS ou Linux) e a linguagem de programação. Por exemplo, o Eclipse é um ambiente de programação concebido para o Java; permite a edição, compilação e o teste de programas Java. O Gedit (em Linux) é um editor simples que reconhece a síntaxe das principais linguagens de programação mostrando vários elementos sintacticos com cores. No entanto, não ajuda o utilisador para a apresentação do programa. A escolha de um editor é uma questão de gosto pessoal dado que as caracteristicas de algumas podem agradar a uns e não a outros. A minha preferência vai para Emacs, um editor que funciona em várias plataformas (Windows, Linux, MacOS, ...) e que tem a como caracteristica principal de ser extremamente flexivel. É chamado no manual «the extensible, customizable, self-documenting real-time display editor». É de facto um editor programável, o que não significa que tem que o programar, mas antes que numerosos pacotes de software foram escritos para o adaptar às situações as mais variadas.

Vamos ver nas secções seguintes como editar um programa usando o Emacs.

Se estiver a usar o Ubuntu Linux, o Emacs (quando é instalado) encontra-se no menu Applications > Programming. Se tudo correr bem aparece uma nova janela que mostra a página de rosto do emacs :

(missing image)
Se estiver a usar o Windows NT (no Windows Vista o resultado deve ser igual), depois de clicar no ícone chamado «emacs» aparece uma janela muito semelhante ao caso do Linux :
(missing image)
A primeira observação é que o emacs fala inglês ! Pode clicar nas palavras que aparecem em azul, funcionam de forma semelhante aos links no seu browser.

O primeiro passo consiste em criar um ficheiro onde será escrito o programa selecionando a opção do menu File > Visit New File...:

(missing image)
Em alternativa, pode clicar no ícone indicado :
(missing image)
Pode proceder de ambas as maneiras tanto no Linux como no Windows. A seguir deve escolher um nome para o ficheiro (aqui hello.c):
(missing image)
No Windows, o aspecto da janela é ligeiramente diferente. Pode, como no caso do Linux escolher o directório onde vai ficar o ficheiro :
(missing image)
A seguir deve escolher um nome para o ficheiro :
(missing image)
Atenção ! a extensão do ficheiro deve ser .c.

Agora pode escrever o programa :

(missing image)
Aqui não há diferença na maneira de proceder entre o Linux e o Windows. Aqui está um exemplo de programa semelhante :
(missing image)
(missing image)
A medida que escreve o programa o emacs altera a cor das palavras conforme a categoria. As cores facilitam a leitura do programa mas também fornecem uma informação útil mesmo antes de compilar o programa. No exemplo seguinte, as aspas que fecham a cadeia de caracteres (a seguir a \n) foram omitidas. Como pode ver, as aspas que não foram fechadas (a seguir ao printf) aparecem en vermelho e os caracteres até o fim do programa têm a cor das cadeias de caracteres.
Deve prestar atenção às cores indicadas no editor.

A barra cinzenta, em baixo da janela do Emacs contém informações úteis. Os dois asteriscos (**) que aparecem antes de hello.c indicam que as alterações ainda não foram guardadas no disco. Para gravar as alterações pode usar o menu File > Save

(missing image)
ou carregar no ícone que representa uma disquette na barra de ícones :
(missing image)
Uma vez feita a gravação pode ver que os dois asteriscos na linha em baixo, junto do nome do ficheiro, desapareceram. É a confirmação que o ficheiro foi correctamente gravado.
(missing image)

Compilar e executar

Para compilar o programa há duas opções :

  • usando a linha de comandos,
  • a partir do Emacs.

Já vimos um exemplo de compilação usando a linha de comando aqui. Os comandos estão escritos num terminal como vimos na secção sobre o printf. O comando para compilar um programa C é gcc. Juntamente a este comando temos que indicar o nome do ficheiro a compilar bem como o nome do programa executável :

> gcc hello.c -o hello
A opção -o indica o ficheiro de saida (output). Se o compilador não detecta nenhum erro não escreve nada no terminal. Pode então excutar o seu programa :
> ./hello
Hello world!

O gcc aceita numerosas opções na linha de comando. Está foram do ambito desta secção explorar as opções do gcc, vamos apenas realçar as mais uteis no nosso contexto.

  • -Wall é uma opção que manda o gcc apresentar todas as mensagens de aviso causados por suspeitas de código incorrecto. As situações onde são geradas mensagens de aviso não impedem a compilação do programa mas correspondem a situações que podem dar problemas durante a execução do programa.
  • -ansi é uma opção que determina que o programa a compilar deve seguir a norma ANSI do C. É importante o programa cumprir todos os requizitos da norma de forma a garantir que poderá ser compilado por outro compilador (e não apenas pelo gcc).
Para compilar o seu programa deve usar essas duas opções :
> gcc -Wall -ansi hello.c -o hello
Deve sempre compilar o seu programa usando as opções -Wall -ansi.
No caso do Windows, vamos proceder de forma ligeiramente diferente. Vamos também usar a linha de comando mas desta vez sem sair do emacs. Deve carregar na tecla Alt e simultaneamente na tecla x. Aparece, na linha de baixo do emacs : M-x a seguir ao x escreve shell e carregue no enter.
(missing image)
O aspecto geral da janela é alterado e a linha de comando aparece. Pode entrar os comandos para compilar e experimentar o seu programa.
(missing image)
Duas observações :
  • O emacs «repete» os comandos que inseriu. Não acontece em Linux, deve-se tratar de uma especificidade do Windows.
  • Os caracteres acentuados não aparecem correctamente (aqui aparece \351 em vez de «é»). Não se deve preocupar com este problema, o programa está correcto, é apenas o ambiente de execução que não está correctamente configurado.

O que é que aconteceu ao seu programa ? Continua lá, disponível. Para o voltar a vê-lo novamente deve usar o comando C-x b (o que significa : carregar na tecla Ctrl e simultaneamente na tecla x, tirar os dedos do teclado e carregar no b), aparece :

(missing image)
Este commando serve para trocar o «buffer» actualmente visível. Entre parêntesis é indicado o buffer que o emacs vai mostrar caso carregue no enter. Como corresponde ao seu programa, carregue agora no enter.O seu programa aparece novamente :
(missing image)

O buffer é a memória do computador que contém o seu ficheiro enquanto está a usar o emacs. O emacs é capaz gerir simultaneamente vários buffers, ou seja: pode editar vários ficheiros ao mesmo tempo.

Se repetir o comando C-x b o emacs propõe trocar novamente o buffer, desta vez o valor por defeito é o buffer que contém o shell. Não é muito conveniente ter que trocar o buffer cada vez que quer alterar ou compilar o programa. Pode alargar a janela e a dividir ao meio de forma a poder ver ambos os buffers. O primeiro passo consiste em usar o comando C-x 2 (o que significa : carregar na tecla Ctrl e simultaneamente na tecla x, tirar os dedos do teclado e carregar no 2) :
(missing image)

E o segundo passo consiste em trocar o buffer visivel numa das metades, usando o comando C-x b :

(missing image)

Erros ?

Nem sempre tudo corre como esperado. Erros acontecem ! Existem vários tipos de erro :

  • erros de compilação. Como o nome indica, são erros dectados pelo compilador :
    • Erro na síntaxe de uma instrução.
    • Erros de inatenção : o nome de uma variável pode estar mal escrito, pode faltar um ponto e virgula etc...
  • erros de lógica. São erros de concepção do programa. Por exemplo :
    • o algoritmo está errado. Não entendeu o problema,
    • erro de implementação do algoritmo. O algoritmo pode estar correcto mas a sua implementação na linguagem de programação pode estar errada. Se, por exemplo, o programa não termina, pode ser por causa de um ciclo infinito,
    • o programa encontra-se numa situação não prevista. Pode por exemplo tentar dividir um número por 0.

Erros de compilação

Podemos ver alguns exemplos de erros de compilação com o programa hello.c :
Se faltar a primeira linha :

1 int main (void) {
2   printf("Hello world !\n");
3   return 0;
4 }
> gcc hello.c -o hello
hello.c: In function 'main':
hello.c:2: warning: incompatible implicit declaration of built-in function 'printf'
Não é apenas o emacs que fala inglês, o compilador também... A mensagem de erro contém a linha do programa fonte onde o erro foi detectado. A palavra «warning» indica o tipo de erro neste caso é apenas um aviso. O programa foi compilado e pode ser executado. Quanto à mensagem, significa que a função printf está a ser usada no programa mas não foi convenientemente declarada. Pode não significar muito por enquanto dado que não vimos matéria suficiente relativamente às funções. Em resumo, as funções, tal como as variáveis devem ser declaradas. A declaração da função printf está no ficheiro stdio.h que portanto deve ser incluído. Como o compilador sabe que printf é uma função da biblioteca standard, é capaz de contornar o erro e compilar o programa até o fim.
Pode parecer obvio mas é necessário ler e entender as mensagens de erro emitidas pelo compilador. Todas as mensagens devem ser tomadas em conta. Os erros que estão na origem das mensagens tipo aviso (warning) devem ser corrigidos.

Se faltar um ponto e virgula (na linha 4) :

1 #include <stdio.h>
2
3 int main (void) {
4   printf("Hello world\n")
5   return 0;
6 }
> gcc hello.c -o hello
hello.c: In function 'main':
hello.c:5: error: expected ';' before 'return'
Aqui a mensagem de erro é clara : falta o ponto e virgula. Trata-se de um erro, o programa não foi compilado.

Se faltar aspas (linha 4) :

1 #include <stdio.h>
2
3 int main (void) {
4   printf("Hello world\n);
5   return 0;
6 }
> gcc hello.c -o hello
hello.c:4:10: warning: missing terminating " character
hello.c: In function 'main':
hello.c:4: error: missing terminating " character
hello.c:5: error: expected expression before 'return'
hello.c:6: error: expected ';' before '}' token
A primeira mensagem detecta o erro e indica a posição das aspas que não estão fechadas (coluna 10). Podemos ver neste exemplo que o compilador continua a analisar o programa depois de ter encontrado um erro. As vezes o primeiro erro perturba a análise do programa e o compilador encontra erros onde não há (as linhas 5 e 6 não têm erros).

Mais um exemplo : faltam as aspas antes da palavra Hello (linha 4).

1 #include <stdio.h>
2
3 int main (void) {
4   printf(Hello world\n");
5   return 0;
6 }
> gcc hello.c -o hello
hello.c: In function 'main':
hello.c:4: error: 'Hello' undeclared (first use in this function)
hello.c:4: error: (Each undeclared identifier is reported only once
hello.c:4: error: for each function it appears in.)
hello.c:4: error: expected ')' before 'world'
hello.c:4: error: stray '\' in program
hello.c:4:23: warning: missing terminating " character
hello.c:4: error: missing terminating " character
hello.c:6: error: expected ';' before '}' token
O primeiro erro encontrado é o erro que é emitido quando uma variável não está declarada. Como faltam as aspas, a palavra Hello é entendida pelo compilador como sendo uma variável (que não está declarada). As duas linhas seguintes indicam que quando um tal erro é encontrado, só a primeira ocorência da variável não declarada é assinalada. A seguir o compilador julga que um parentesis falta antes da palavra world. De facto se Hello fosse uma variável, não poderia haver imediatamente a seguir outra variável este erro é portanto deduzido do erro suposto anteriormente (falta de declaração). Este exemplo mostra que o compilador faz suposições sobre a natureza dos erros para continuar a analisar o programa. Neste caso enganou-se a causa do erro não é uma variável não declarada mas umas aspas em falta.
O compilador não tem uma bola de cristal, não tem maneira de advinhar as suas intenções. Pode enganar-se relativamente à causa dos erros, é portanto necessário corrigir os erros na ordem da linhas do programa e voltar a compilar.

Erros de lógica

Os erros de software são vulgarmente chamados «bugs» veja aqui uma explicação sobre a palavra.

Os erros de lógica são mais dificeis detectar. Acontecem quando o resultado do programa não é o esperado. Pode terminar com um erro de execução ou simplesmente dar resultados errados.

Existem ferramentas sofisticadas que permitem observar o estado do programa (conteúdo das variáveis) equanto corre. Para os programas compilados com o gcc o gdb (Gnu Debugger) é geralmente usado. Como o uso do gdb requer aprender novos comandos vamos descrever um método mais basico usando o um exemplo concreto.