Programar em C/Controle de fluxo: diferenças entre revisões

[edição verificada][revisão pendente]
Conteúdo apagado Conteúdo adicionado
EvertonS (discussão | contribs)
m <source> -> <syntaxhighlight> (phab:T237267)
 
Linha 41:
<div style="background-color: #ddffdd; padding: 10px; margin: 20px;">
'''Note''' que para saber se dois números são iguais devemos usar '''dois sinais de igual'''. Um erro muito comum é esquecer de um deles, transformando a comparação numa atribuição ― por exemplo:
<sourcesyntaxhighlight lang=c>
if (x = 1)
...
</syntaxhighlight>
</source>
O que acontece aqui é que a variável ''x'' recebe o valor 1, de modo que a expressão entre parênteses também terá o valor 1 ― tornando a “condição” sempre verdadeira. Similarmente, se usássemos o número zero, a expressão sempre seria falsa. Portanto, sempre tome cuidado com esse tipo de comparação. A maneira certa de comparar com um número é:
<sourcesyntaxhighlight lang=c>
if (x == 1)
...
</syntaxhighlight>
</source>
</div>
 
Linha 79:
 
Pelo fato de todo valor diferente de zero ser avaliado como verdadeiro e zero como falso, existem as seguintes equivalências (apenas quando estas expressões são usadas como condições):
<sourcesyntaxhighlight lang=c>
(x == 0) equivale a (!x)
(x != 0) equivale a (x)
</syntaxhighlight>
</source>
 
== Testes ==
Linha 92:
O teste '''if''' avalia uma condição e, se ela for verdadeira, executa um bloco de código. A sintaxe correspondente a isso é:
 
<sourcesyntaxhighlight lang=c>
if (condição) {
... /* bloco a ser executado se a condição for verdadeira */
}
</syntaxhighlight>
</source>
 
Mas também podemos especificar um bloco a ser executado caso a condição for falsa. Nesse caso, escrevemos:
 
<sourcesyntaxhighlight lang=c>
if (condição) {
... /* bloco a ser executado se a condição for verdadeira */
Linha 107:
... /* bloco a ser executado se a condição for falsa */
}
</syntaxhighlight>
</source>
 
As chaves podem ser omitidas caso haja '''apenas uma instrução''' no bloco. Por exemplo:
 
<sourcesyntaxhighlight lang=c>
if (x == 5)
printf ("x é igual a 5.\n");
</syntaxhighlight>
</source>
 
Perceba que, se esquecermos as chaves, o compilador não deverá dar nenhum erro; no entanto, tudo que exceder a primeira instrução será executado incondicionalmente, '''mesmo que esteja na mesma linha'''! No exemplo a seguir, a frase "x é igual a 5" seria exibida mesmo que o número não fosse 5!
 
<sourcesyntaxhighlight lang=c>
if (x == 5)
j++; printf ("x é igual a 5.\n");
</syntaxhighlight>
</source>
 
Podemos avaliar diversas condições com os testes if, bastando para isso colocar um novo teste no bloco <tt>else</tt>. Também é possível aninhar blocos <tt>if</tt>, ou seja, colocar um dentro de outro:
 
<sourcesyntaxhighlight lang=c>
if (x > 9) {
printf ("x é maior que 9.\n");
Linha 140:
}
}
</syntaxhighlight>
</source>
 
=== <tt>switch</tt> ===
Linha 146:
O teste '''switch''' compara uma expressão com diversos valores que podem estar associados a blocos de códigos diferentes, e executa o bloco de código correspondente ao valor encontrado. Você também pode especificar um bloco que deve ser executado caso nenhum dos outros valores seja encontrado: é o bloco <tt>default</tt> ("padrão" em inglês).
 
<sourcesyntaxhighlight lang=c>
switch (expressão) {
case valor1:
Linha 158:
instruções;
}
</syntaxhighlight>
</source>
 
Note que no teste '''switch''' não precisamos usar chaves em volta dos blocos, a menos que declaremos variáveis neles. Um exemplo da utilização de '''switch''' seria a criação de um menu:
 
<sourcesyntaxhighlight lang=c>
int opcao;
printf ("[1] Cadastrar cliente\n"
Linha 186:
printf ("Opção inválida!\n");
}
</syntaxhighlight>
</source>
 
A instrução '''break''' indica que deve-se continuar a execução após o final do bloco <tt>switch</tt> (pulando o que estiver no meio). Se ela não fosse usada, para um certo valor encontrado, seriam executadas também as instruções de todos os valores abaixo dele. Em alguns casos, podemos omitir intencionalmente a instrução break. Por exemplo, no exemplo acima, não colocamos uma instrução <tt>break</tt> para o valor zero, pois quando retornamos de uma função (<tt>return 0</tt>) o bloco switch já é abandonado.
Linha 192:
Também podemos querer que uma instrução seja executada para mais de um valor. Vamos supor que no nosso menu as duas primeiras opções fossem "Cadastrar pessoa física" e "Cadastrar pessoa jurídica", e tívessemos uma função que faz o cadastro diferentemente dependendo do valor da variável <tt>pessoa_fisica</tt>. Poderíamos fazer um código assim:
 
<sourcesyntaxhighlight lang=c>
switch (opcao) {
case 1: /* pessoa física */
Linha 201:
...
}
</syntaxhighlight>
</source>
 
Nesse caso, para qualquer uma das duas opções seria executada a função <tt>cadastra</tt>, mas se selecionarmos "pessoa física" a variável será atribuída antes.
Linha 209:
O operador ternário '''<tt>?:</tt>''' é uma alternativa abreviada da estrutura '''if/else'''. Ele avalia uma expressão e retorna um certo valor se ela for verdadeira, ou outro valor se ela for falsa. Sua sintaxe é:
 
<sourcesyntaxhighlight lang=c>
condição ? valorSeVerdadeira : valorSeFalsa
</syntaxhighlight>
</source>
 
Note que, ao contrário de '''if''', ao usarmos o operador condicional <tt>?:</tt> precisamos sempre prover tanto o valor para o caso de a condição ser falsa quanto o valor para o caso de ela ser verdadeira.
Linha 217:
O operador condicional pode ser usado em situações como essa:
 
<sourcesyntaxhighlight lang=c>
int horaAbertura = (diaSemana == DOMINGO) ? 11 : 9;
printf ("Abrimos às %d horas", horaAbertura);
</syntaxhighlight>
</source>
 
Ou seja, se o dia da semana for domingo, a variável <var>horaAbertura</var> será definida para 11; caso contrário, será definida para 9.
Linha 226:
Outro exemplo:
 
<sourcesyntaxhighlight lang=c>
if (numMensagens > 0) {
printf ("Você tem %d mensage%s",
Linha 232:
(numMensagens > 1) ? "ns" : "m");
}
</syntaxhighlight>
</source>
 
Neste caso, o programa utilizaria "mensagens" caso houvesse mais de uma mensagem, e "mensagem" caso houvesse apenas uma mensagem.
Linha 244:
O loop '''<tt>while</tt>''' testa uma condição; se ela for verdadeira, o bloco correspondente é executado e o teste é repetido. Se for falsa, a execução continua logo após o bloco. A sintaxe de <tt>while</tt> é:
 
<sourcesyntaxhighlight lang=c>
while (condição) {
...
}
</syntaxhighlight>
</source>
 
Por exemplo:
 
<sourcesyntaxhighlight lang=c>
while (a < b)
{
Linha 258:
a++;
}
</syntaxhighlight>
</source>
 
Este código seria executado até que <var>a</var> fosse igual a <var>b</var>; se <var>a</var> fosse igual ou maior que <var>b</var>, nada seria executado. Por exemplo, para <var>b</var> = 10 e <var>a</var> &lt; 10, a última mensagem que o usuário veria é "9 é menor que 10".
Linha 264:
Repare que o loop '''while''' é como fosse um '''if''', ou seja, o bloco é executado se a condição for verdadeira. A diferença é que ao final da execução, o while é executado novamente, mas o if não. No loop '''while''' (assim como nos loops '''do''' e '''for''') também podemos usar a sintaxe abreviada para apenas uma instrução:
 
<sourcesyntaxhighlight lang=c>
while (a < b)
a++;
</syntaxhighlight>
</source>
 
==== Loops infinitos ====
Linha 273:
Você pode fazer loops infinitos com '''while''', usando uma condição que é sempre verdadeira, como "1 == 1" ou simplesmente "1" (que, como qualquer valor não-nulo, é considerado "verdadeiro"):
 
<sourcesyntaxhighlight lang=c>
while (1) {
...
}
</syntaxhighlight>
</source>
 
Você pode sair de um loop &mdash; infinito ou não &mdash; com a instrução <tt>break</tt>, que você já viu no teste '''switch''' e será explicada mais abaixo.
Linha 285:
O loop '''"<tt>do</tt> ... <tt>while</tt>"''' é exatamente igual ao '''"while"''' exceto por um aspecto: a condição é testada depois do bloco, o que significa que o bloco é executado pelo menos uma vez. A estrutura <tt>do</tt> ... <tt>while</tt> executa o bloco, testa a condição e, se esta for verdadeira, volta para o bloco de código. Sua sintaxe é:
 
<sourcesyntaxhighlight lang=c>
do {
...
} while (condição);
</syntaxhighlight>
</source>
 
Note que, ao contrário das outras estruturas de controle, '''é necessário colocar um ponto-e-vírgula''' após a condição.
 
<sourcesyntaxhighlight lang=c>
do
{
Linha 300:
}
while (a < b);
</syntaxhighlight>
</source>
 
Um exemplo de utilização de <tt>do</tt> ... <tt>while</tt> é em um menu. Pediríamos que o usuário escolhesse uma opção até que ele escolhesse uma opção válida:
 
<sourcesyntaxhighlight lang=c>
#include <stdio.h>
Linha 331:
return 0;
}
</syntaxhighlight>
</source>
 
=== <tt>for</tt> ===
Linha 339:
[[Ficheiro:For-loop-diagram.png|direita|thumb|150px | Diagrama de fluxo de dados da estrutura "para": A é a atribuição inicial, B é a condição de parada, D é o bloco de código e C é o incremento do passo.]]
 
<sourcesyntaxhighlight lang=c>
for (inicialização; condição; incremento) {
instruções;
}
</syntaxhighlight>
</source>
 
 
E equivale a
 
<sourcesyntaxhighlight lang=c>
inicialização;
while (condição) {
Linha 354:
incremento;
}
</syntaxhighlight>
</source>
 
Um exemplo do uso de '''for''':
 
<sourcesyntaxhighlight lang=c>
for (a = 1; a < 10; a++) {
if(a == 1)
Linha 365:
printf("Valor de a : %i ", a );
}
</syntaxhighlight>
</source>
 
Nesse exemplo, primeiro definimos o valor de <var>a</var> como 1; depois, o código (...) é repetido enquanto <var>a</var> for menor que dez, incrementando em uma unidade o valor de <var>a</var> após cada execução do código. Analisando essas condições, você podera perceber que o código será executado nove vezes: na primeira execução, temos <tt>a = 1</tt>; após a nona execução, <var>a</var> é igual a 10, e portanto o bloco não será mais repetido.
Linha 371:
Também podemos dar mais de uma instrução de inicialização ou de incremento (separadas por vírgula), além de poder usar naturalmente condições compostas com o uso dos operadores lógicos:
 
<sourcesyntaxhighlight lang=c>
for (a = 1, b = 1; a < 10 && (b / a) < 20; a++, b *= 2) {
...
}
</syntaxhighlight>
</source>
 
Nesse exemplo, "a" e "b" são inicializados com o valor 1. A cada loop, o valor de "a" é incrementado em uma unidade e o de "b" é dobrado. Isso ocorre enquanto "a" for menor que 10 e a razão entre "b" e "a" for menor que 20. Se você construir uma tabela com os valores de cada variável a cada loop (ou colocar algum contador dentro do loop), verá que ocorrem oito execuções.
Linha 383:
Podemos omitir qualquer um dos elementos do '''for''' se desejarmos. Se omitirmos a inicialização e o incremento, o comportamento será exatamente igual ao de '''while'''. Se omitirmos a condição, ficaremos com um loop infinito:
 
<sourcesyntaxhighlight lang=c>
for (inicialização; ; incremento) {
...
}
</syntaxhighlight>
</source>
 
Podemos também omitir o bloco de código, se nos interessar apenas fazer incrementos ou se quisermos esperar por alguma situação que é estabelecida por uma função externa; nesse caso, usamos o ponto-e-vírgula após os parênteses de '''for'''. Isso também é valido para o loop '''while''':
 
<sourcesyntaxhighlight lang=c>
for (inicialização; condição; incremento) ;
while (condição) ;
</syntaxhighlight>
</source>
 
Por exemplo, suponha que temos uma biblioteca gráfica que tem uma função chamada graphicsReady(), que indica se podemos executar operações gráficas. Este código executaria a função repetidas vezes até que ela retornasse "verdadeiro" e então pudéssemos continuar com o programa:
 
<sourcesyntaxhighlight lang=c>
while (!graphicsReady()) ;
</syntaxhighlight>
</source>
 
=== <tt>break</tt> e <tt>continue</tt> ===
Linha 406:
Você já viu '''<tt>break</tt>''' sendo usado para sair do teste '''switch'''; no entanto, ele funciona também nos loops &mdash; <tt>while</tt>, <tt>do</tt> e <tt>for</tt>. Nos três casos, ele sai do último loop iniciado (mesmo que haja mais de um). Por exemplo:
 
<sourcesyntaxhighlight lang=c>
while (1) {
if (a > b)
Linha 412:
a++;
}
</syntaxhighlight>
</source>
 
'''break''' sempre faz com que a execução do programa continue na primeira instrução seguinte ao loop ou bloco.
Linha 418:
A instrução '''<tt>continue</tt>''' é parecida com '''break''', porém ao executá-la saltamos para a próxima iteração loop ao invés de terminá-lo. Usar '''continue''' equivale a chegar ao final do bloco; os incrementos são realizados (se estivermos em um loop '''for''') e a condição é reavaliada (qualquer que seja o loop atual).
 
<sourcesyntaxhighlight lang=c>
#include <stdio.h>
Linha 453:
return 0;
}
</syntaxhighlight>
</source>
 
Esse exemplo recebe uma opção do usuário. Se ele digitar uma opção inválida (ou seja, não for um número de 1 a 5), a instrução '''continue''' voltará ao começo do loop e o programa pedirá novamente a entrada do usuário. Se ele digitar uma opção válida, o programa seguirá normalmente.
Linha 461:
O '''<tt>goto</tt>''' é uma instrução que salta incondicionalmente para um local específico no programa. Esse local é identificado por um rótulo. A sintaxe da instrução '''goto''' é:
 
<sourcesyntaxhighlight lang=c>
goto nome_do_rótulo;
</syntaxhighlight>
</source>
 
Os nomes de rótulo são identificadores sufixados por dois-pontos (<tt>:</tt>), no começo de uma linha (podendo ser precedidos por espaços). Por exemplo:
 
<sourcesyntaxhighlight lang=c>
nome_do_rótulo:
...
goto nome_do_rótulo;
</syntaxhighlight>
</source>
 
Muitos programadores evitam usar o <tt>goto</tt> pois a maioria dos saltos pode ser feita de maneira mais clara com outras estruturas da linguagem C. Na maioria das aplicações usuais, pode-se substituir o <tt>goto</tt> por testes, loops e chamadas de funções.
Linha 483:
Para utilizá-la deve-se colocar um include para o arquivo de cabeçalho stdlib.h. Esta função aborta a execução do programa. Pode ser chamada de qualquer ponto no programa e faz com que o programa termine e retorne, para o sistema operacional, o código_de_retorno. A convenção mais usada é que um programa retorne zero no caso de um término normal e retorne um número não nulo no caso de ter ocorrido um problema.
 
<sourcesyntaxhighlight lang="C">
#include <stdio.h>
#include <stdlib.h> /* Para a função exit() */
Linha 500:
return 0;
}
</syntaxhighlight>
</source>
 
{{AutoCat}}