command_1 ; command_2 ; command_3 ; command_4 ;
Um comando termina no ponto-e-vírgula; isso significa que todos os efeitos do comando serão sacramentados quando a "execução do código fonte" chegar no ponto-e-vírgula. O trecho de código acima consiste da execução, um após o outro, de quatro comandos.
A formatação abaixo é equivalente àquela da linha acima, embora a formatação com um comando por linha seja geralmente mais fácil de ler.
command_1;
command_2; // isso é um comentário que vai até o fim da linha
command_3; /* isso é um comentário que termina em qualquer posição */
command_4;
Não esqueça do ponto-e-vírgula ao final de cada comando. Eu prefiro não deixar espaço em branco entre a última letra do comando e o ponto-e-vírgula; a linguagem aceita as duas formas.
Um comando simples pode ser uma atribuição como a abaixo. Em C, a atribuição é denotada por '=' (igual).
a = b + c;
Comandos podem se logicamente agrupados "cercando" o bloco de comandos com par de chaves. O par de chaves é equivalente ao BEGIN ... END; do Pascal.
{ command_1 ; command_2 ; command_3 ; command_4 ; }
if (expression)
command ;
ou com um bloco de comandos:
if (expression)
{
command_1 ;
command_2 ;
...
}
Ao contrário de Pascal, a condição do comando "if" pode testar qualquer expressão cujo resultado possa ser avaliado para um número, sendo que 0 (zero) é considerado falso e não-zero é verdadeiro.
Contar com que verdadeiro seja qualquer coisa não-zero é uma má ideia porque pode levar a erros difíceis de detectar, e portanto deve ser evitado.
Os if's podem ser aninhados da maneira óbvia:
if (expression1)
if (expression2)
{
command_1 ;
command_2 ;
...
}
Note que os comandos estão endentados (afastados da margem esquerda) para facilitar a leitura. A linguagem C permite formatação livre, mas endentar o código é fundamental para tornar o código legível.
O comando abaixo é logicamente equivalente ao exemplo acima, com a adição das chaves para "cercar" o bloco interno. Sempre que facilitar a leitura, empregue chaves para delimitar um bloco de código.
if (expression1)
{
if (expression2)
{
command_1 ;
command_2 ;
...
}
}
No comando if-else as duas cláusulas são mutuamente exclusivas.
if (expression)
command1 ; // <--- there has to be a semicolon here!
else
command2 ;
ou, com blocos de comandos:
if (expression)
{
command_1if ;
command_2if ;
command_3if ;
}
else
{
command_1else ;
command_2else ;
}
If-else podem ser aninhados:
if (expression_1)
if (expression_2)
command_1 ;
else
command_2 ;
else
command_3 ;
Ou, agrupando com chaves:
if (expression_1)
{
if (expression_2)
command_1 ;
else
command_2 ;
}
else
{
command_3 ;
}
A cláusula ''else'' sempre se combina com o último ''if'' em aberto; caso se deseje forçar outra combinação, deve-se usar chaves {...} para organizar a abertura/fechamento das cláusulas dos "if's".
A expressão deve avaliar para um valor inteiro. Este inteiro deve corresponder a uma das cláusulas ("case"); se o resultado da avaliação não corresponder a nenhuma das cláusulas explícitas, então a cláusula "default" é a escolhida.
Se uma cláusula não for terminada por um "break", os comandos da cláusula seguinte são executados.
switch (expression)
{
case constant_1:
command_1 ;
...
break ;
case constant_2:
command_2 ;
...
break ;
case constant_3: // duas constantes para um mesmo bloco de comandos
case constant_4:
command_3_4 ;
...
break ;
...
default: // se o resultado não "casou" antes, executa estes
command_Na; // comandos
...
break ;
}
Os (vários) comandos de cada cláusula não precisam ser cercados por chaves; o bloco termina no primeiro "break" que for encontrado.
Exemplo: este comando conta o número de carros dentre quatro possibilidades:
ch = getchar(); // lê um caractere que identifica o tipo do carro
switch(ch) // escolhe um dentre os tipos possíveis
{
case ‘C’: // duas possibilidades, C e c
case ‘c’:
corsa++ ;
break ;
case ‘P’:
prisma++ ;
break ;
case ‘p’: // maiúsculas e minúsculas são distintas
palio++ ;
break ;
default:
outros++ ;
break ;
}
A expressão é avaliada, e se o resultado for diferente de zero (FALSO) então os comandos do corpo do "while" são executados.
while (expression)
command ;
ou
while (expression)
{
command_1 ;
command_2 ;
...
}
Exemplo:
i = 0 ; // inicializa a variável de controle
while (i < 100) // testa condição de término
{
printf ("i vale %d\n", i) ; // computa algo com a variável de controle
i++ ; // atualiza a variável de controle
}
O corpo do comando while é executado zero ou mais vezes.
O corpo do laço é executado e a expressão é avaliada. Se o resultado for diferente de zero, então o corpo do laço é executado novamente.
do
command ;
while (expression) ;
ou
do
{
command_1 ;
command_2 ;
...
}
while (expression) ;
Exemplo:
i = 100 ; // inicializa a variável de controle
do
{
printf ("i vale %d\n", i) ; // computa algo com a variável de controle
i-- ; // atualiza a variável de controle
}
while (i > 0) ; // testa condição de término
O corpo do comando do-while é executado uma ou mais vezes.
O comando "for" é o canivete suiço da linguagem C, e é logicamente equivalente ao laço
i = 0 ; // inicializa as variáveis de controle
while (i < 100) // teste da condição
{
... ; // computa algo com a variável de controle
i++ ; // atualiza as variáveis de controle
}
O comando "for" é uma forma compacta de representar o laço acima:
for (initializção ; teste_da_condição ; atualização)
command ;
Note os ponto-e-vírgula que separam as três "seções" do comando.
ou
for (initialização ; teste_da_condição ; atualização)
{
command_1 ;
command_2 ;
...
}
Exemplo: laço de repetição com a variável de controle indo de 0 a 99:
for (i = 0; i < 100; i = i + 1)
printf ("i vale %d", i) ;
O exemplo acima pode ser reescrito como:
i = 0 ; // inicialização
while (i < 100) // condição
{
printf ("i vale %d", i) ;
i++ ; // atualização
}
Uma forma peculiar uso do ''for'' é o laço infinito, que não tem inicialização, nem condição e nem atualização:
for (;;) // while (TRUE) { };
{
}
O material que segue será estudado nas próximas aulas.
O comando ''return'' encerra a função atual e retorna ao ponto de onde ela foi invocada. Um "return" pode aparecer em qualquer local da função, não necessariamente no final dela.
Exemplo:
int compara (int a, int b)
{
if (a > b) return 1 ;
if (a < b) return -1 ;
if (a == b) return 0 ;
}
A função ''exit (int status)'' é provida pela biblioteca de sistema ''stdlib.h'' e permite o encerramento do programa. O status informado como argumento é devolvido ao sistema operacional, mais especificamente à shell que lançou a aplicação.
exit (0) ;
O comando ''break'' só é usado dentro de blocos ''switch'', ''do'', ''while'' ou ''for''. Ao ser acionado, ele salta a execução para o primeiro comando após o bloco atual.
Exemplo:
for (;;)
{
printf ("Aceita? (s/n) ") ;
resp = getchar() ;
if(resp == 's' || resp == 'n')
break;
printf ("\n") ;
}
// o break salta para cá
O comando ''break'' deve ser usado com muito cuidado, pois ele pode tornar o fluxo de execução muito complexo (e portanto sujeito a erros). Como regra geral, evite utilizá-lo, a não ser que seja absolutamente necessário.
O comando ''continue'' é usado em laços ''for'', ''do'' e ''while''. Ele interrompe a iteração atual e inicia a próxima iteração do laço onde se encontra.
Exemplo:
int i;
for (i = -10; i < 10; i++)
{
if (i == 0)
continue; // pula para a próxima iteração
printf("%f\n", 15.0/i);
// ...
}
O comando ''continue'' deve ser usado com muito cuidado, pois ele pode tornar o fluxo de execução muito complexo (e portanto sujeito a erros). Como regra geral, evite utilizá-lo, a não ser que seja absolutamente necessário.
O comando ''goto'' permite saltar a execução para locais definidos por rótulos ou etiquetas (//labels//), como mostra o exemplo a seguir:
goto PARTE2;
// ... (qualquer código)
PARTE2:
i = 0 ;
// ...
O comando ''goto'' deve ser usado com muito cuidado, pois ele pode tornar o fluxo de execução muito complexo (e portanto sujeito a erros). Como regra geral, evite utilizá-lo, a não ser que seja absolutamente necessário.
''assert'' é uma macro que verifica uma asserção (condição) e encerra o programa se ela for falsa (nula). Ao encerrar, uma mensagem de erro indicando a localização da asserção violada é gerada, o que facilita localizar problemas.
#include <assert.h>
int main()
{
...
assert (i >= 0) ;
...
}
Se a condição i >= 0 for falsa, o programa será interrompido e a seguinte mensagem será gerada, indicando o arquivo (''program.c''), a linha (6), a função (''main'') e a asserção violada:
a.out: program.c:6: main: Assertion `i >= 0' failed.
O operador de conjunção (AND) de duas comparações é '&&' (ampersand ampersand).
O operador de disjunção (OR) de duas comparações é '||' (vertical vertical ou pipe pipe).
Para resolver os exercícios, copie o trecho de código abaixo para um
arquivo chamado teste.c, edite-o e então compile este arquivo com o
comando
gcc -Wall teste.c -o teste
./teste
Recorte nas linhas.
/* Esqueleto para os exercícios */
#include <stdio.h> // inclusão de definições
int main (void) // função principal
{
int a, b, c; // declaração das variáveis
a = 10; // valores para os lados dos triângulos
b = 10;
c = 10;
if (a == b) && (b == c) // (a igual b) AND (b igual c)
{
printf ("equilatero: %d %d %d\n", a, b, c); // imprime resultado na tela
}
return (0); // retorno (fim) da função
}
Escreva trechos de programas para:
Dado um número inteiro 0 < n < 4000, escrevê-lo como número romano (exemplo: 1965 = MCMLXV).
Dado N > 1 e dois números naturais i e j diferentes de 0, imprimir em ordem crescente os N primeiros naturais que sejam múltiplos de i, de j ou de ambos. Exemplo: Para N = 6, i = 2 e j = 3 a saída deverá ser: 0, 2, 3, 4, 6, 8.