C/Instrucións de control

En Galilibros, o Wikibooks en galego.
< C
Saltar ata a navegación Saltar á procura
C
← Volver a Operadores Instrucións de control Seguir con Funcións


As instrucións de control permiten, como o seu nome indica, controlar o fluxo dun programa. Mediante este tipo de instrucións, pódense establecer condicións para a execución doutras instrucións, crear ciclos de instrucións que se repiten varias veces, saír dun bloque ou dunha función, etc.

Condicións[editar]

Na linguaxe de programación C, certo e falso son cuestións puramente aritméticas, e considérase falso o valor nulo, 0, e certo calquera outro valor. De feito, “o valor máis certo é -1”, e non 1, dado que en binario o computador detecta antes que non é cero o -1, que en binario comeza por 1, que o 1, cuxos bits son todos 0 agás o último.

As condicións que se utilizarán nas instrucións de control poden ser unha variable, unha expresión completa ou mesmo un número. Por exemplo, unha condición podería ser -1, que sería certa. Outra pode ser a, que será certa mentres o valor de a sexa distinto de 0. E outra podería ser «a * (b - c / d)». As posibilidades son inmensas. Coñecendo o uso dos distintos tipos de operadores, todo dependerá do que sexa necesario ter en conta.

Bloques de instrucións[editar]

Cando se cumpre a condición dunha instrución de control, pódese establecer que se execute unha instrución calquera. Porén, cando se queira que se execute máis dunha (que será o caso case sempre), non abonda con escribir a lista de instrucións a continuación da condición. Fai falla indicarlle ao compilador que todas esas instrucións forman parte dun mesmo grupo que se executará cando se cumpra a condición da instrución de control. Isto faise mediante un bloque de instrucións.

Un bloque de instrucións son unha serie de instrucións delimitadas por chaves, «{» e «}». Véxase o seguinte exemplo:

{ // Aquí comeza o bloque de sentencias
  a = 1;
  b = 3;
  c = b - a;
} // e aquí remata.

Por suposto, o uso dos bloques de instrucións só ten sentido cando se pretende que a unha condición respondan máis dunha instrución. Non ten sentido utilizar un bloque nos casos en que só hai unha instrución a executar. A continuación, á hora de explicar a sintaxe das instrucións de control que conteñen condicións, usaranse unhas veces instrucións soltas e outras bloques delas, e cómpre lembrar que o seu uso é indistinto.

break[editar]

A instrución de control break permite saír do bloque de instrucións no que está o fluxo de control do programa. A sintaxe de uso desta sentencia de control pode comprenderse co seguinte exemplo:

instrución 1;
{
  instrución 2;
  break;
  instrución 3;
}
instrución 4;

No que se executarían só as instrucións 1, 2 e 4.

return[editar]

A instrución de control return establece o valor que devolve a función na que está presente. Ao executarse dita sentencia, remata a execución da función na que estaba, e vólvese á función dende a cal se chamou a esta. A súa sintaxe fundamental é a seguinte:

return valor;

Onde valor pode ser tanto unha variable coma un valor.

En caso de que a función non devolva ningún valor, pódese volver á función que a chamou omitindo o valor. Véxase o seguinte exemplo:

return;

if[editar]

A instrución de control if permite establecer unha condición que, de cumprirse, provoque a execución dunha instrución. A súa sintaxe fundamental sería a seguinte:

if(condición)
  sentencia;

Permite ademais establecer unha instrución a executar en caso de que a condición non se cumpra. A sintaxe completa utilizando esta opción sería a seguinte:

if(condición)
  sentencia para cando se cumpra a condición;
else
  sentencia para cando non se cumpra;

E por suposto, dentro dunha instrución de control if (ou else) pode haber outra instrución if, ou calquera outra instrución de control.

switch[editar]

A instrución de control switch permite executar distintas instrucións en función dos valores dunha expresión (ou condición). A súa sintaxe fundamental é a seguinte:

switch(expresión){
  case valor1:	instrución;
  case valor2:  instrución;
  ...
  case valorn:	instrución;
  default: instrución;
}

Para definir unha serie de instrucións para un valor, dentro da instrución de control escríbese case, seguido do valor para o cal se van definir as instrucións, seguido de dous puntos, «:», e seguido da instrución ou instrucións.

En cada case, despois dos dous puntos, pode haber máis dunha instrución. Para isto non fai falla utilizar un bloque, senón que abonda con escribir directamente as instrucións as unhas despois das outras.

Adóitanse seguir as instrucións asignadas a cada opción dunha instrución de control break ou return, mesmo no último caso (xeralmente o default), onde sería completamente innecesario un break. De non utilizarse unha destas instrucións de control, non se executarían só as instrucións asignadas ao case co valor da expresión, senón todas as instrucións dos case seguintes. Mediante o break; sáese do bloque do switch, mentres que mediante o return sáese de toda a función que contén a instrución de control.

Por último, default: indica as instrucións que se executarán en caso de que o valor da expresión non se corresponda con ningún dos case. A súa inclusión na instrución de control é opcional.

“Caída”[editar]

O comportamento de executar as instrucións dos seguintes case se non se engade un break ou un return pode aproveitarse nalgunhas ocasións para obter un comportamento específico. Pero se no mesmo código traballa ou vai traballar máis dun programador, cómpre indicar que isto se está facendo a propósito para evitar que alguén “corrixa o erro”. Isto faise xeralmente mediante o comentario «// CAÍDA», ou se se trata dun proxecto internacional, «// FALL THROUGH». Véxase o seguinte exemplo:

switch(expresión){
case 1:
	printf("O valor da expresión era 1.\n");
	break;
case 2:
	printf("O valor da expresión é 2.\n");
	// CAÍDA
case 3:
	printf("O valor da expresión é 2 ou 3.\n" );
	break;
}

E se a expresión valese 2, imprimiríase o seguinte:

O valor da expresión é 2.
O valor da expresión é 2 ou 3.

Acumulación de valores nun switch[editar]

Este funcionamento do switch de partir do case que se corresponda coa expresión pero executar todas as instrucións dende dito punto ata que se atope cunha instrución de control de saída pode utilizarse para acumular distintos valores para unha mesma instrución ou grupo de instrucións. Véxase para comprendelo o seguinte exemplo:

switch(expresión){
  case 1:
  case 6:  // A función printf() imprime en pantalla o texto pasado como argumento.
  case 10: printf("Verás este texto se a variable vale 1, 6 ou 10.\n");
	 break;
  case 2:  printf("Verás este texto se a variable vale 2.\n");
	 break;
  default: printf("Verás este texto se a variable non vale nin 1, nin 2, nin 6 nin 10.\n");
	 break;
}

Expresións de tipo char nun switch[editar]

Ao entrar nunha instrución de control switch que opera sobre os distintos valores dun carácter, é preciso utilizar un molde, (char), para indicarlle ao switch que non se trata dun número.

switch((char)expresión){
  case 'a': printf("O carácter é «a».\n"); break;
  case 'z': printf("O carácter é «z».\n"); break;
  default : printf("O carácter non é nin «a» nin «z».\n");
}

Ciclos[editar]

Os ciclos consisten en instrucións que se repiten ata que se cumpra unha condición. As instrucións dos ciclos non varían durante a súa execución, pero poden varias os valores das variables, de xeito que as posibilidades vólvense infinitas.

En C existen tres instrucións de control para a creación de ciclos, cada unha coas súas peculiaridades, e se ben xeralmente se poden adaptar todos os ciclos para facer as mesmas funcións, en cada situación resultará máis eficiente, elegante, ou simplemente evidente a utilización dun ciclo concreto. Algo que si que teñen todos os ciclos en común é que a súa execución non se detén no mesmo intre en que a condición se volve falsa, senón cando esta é falsa ao avaliala, algo que se fai xusto antes de comezar a execución da instrución ou bloque de instrucións do ciclo.

Ciclos sen fin[editar]

Cómpre lembrar de cara aos ciclos que se poden crear expresións que sempre son certas, como sería a expresión «-1», de xeito que se conseguiría o que se denomina un “ciclo sen fin”. Por suposto, hai maneiras de saír co ciclo alternativas a que a condición cambie, coma as instrucións de control break ou return. Pero se nun ciclo sen fin non se establece algunha forma de saír del, o programa non deixará de executarse, e haberá que interromper a súa execución manualmente.

continue[editar]

Ademais das instrucións de control break e return, o fluxo de control dos ciclos pode alterarse mediante a instrución continue. Dita instrución, ao executarse, sáltase o resto do ciclo e volve avaliar a condición (e se é certa repite o ciclo, e en caso contrario non o repite).

while[editar]

O ciclo while executa unha instrución (ou bloque de instrucións) mentres se cumpra ─sexa certa (distinta de cero)─ unha expresión. Esta sería a súa sintaxe fundamental:

while(condición)
  instrución;

Se de primeiras xa non se cumpre a condición, o ciclo non se executa ningunha vez.

do while[editar]

O ciclo do while executa unha instrución (ou bloque de instrucións) unha vez, e a continuación repite a súa execución mentres se cumpra ─sexa certa (distinta de cero)─ unha expresión. Esta sería a súa sintaxe fundamental:

do
  instrución;
while(condición);

for[editar]

O ciclo for executa unha instrución inicial ─utilizada xeralmente para establecer o valor inicial dunha variable─, e mentres se cumpra ─sexa certa (distinta de cero)─ unha condición, executa unha instrución (ou bloque de instrucións) seguida dunha instrución final ─que adoita cambiar o valor dalgunha variable de cara a modificar o valor da expresión da condición─ que se executa sempre entre a instrución do ciclo e a seguinte comprobación de se se cumpre a condición. Esta sería a súa sintaxe fundamental:

for(instrución inicial; condición; instrución final)
  instrución;

Este ciclo adoita utilizarse, por exemplo, en casos nos que se quere executar unha ou varias instrucións un número determinado de veces, coma no seguinte exemplo:

// Supoñendo que previamente se declarou a variable «i»...
for(i=0;i<10;i++)
  printf("Non volverei programar en Visual Basic.\n");

No exemplo executaríase a función printf() dez veces.

Mediante comas pódense ademais utilizar varias instrucións iniciais e finais, como no seguinte exemplo:

for(i=1,l=10;i<=10;i++,l--)
  printf("Ciclo “for”: i=%d, l=%d.\n", i, l);
// Os %d substituiríanse polos respectivos valores de «i» e «l».

O resultado sería o seguinte:

Ciclo “for”: i=1, l=10.
Ciclo “for”: i=2, l=9.
Ciclo “for”: i=3, l=8.
Ciclo “for”: i=4, l=7.
Ciclo “for”: i=5, l=6.
Ciclo “for”: i=6, l=5.
Ciclo “for”: i=7, l=4.
Ciclo “for”: i=8, l=3.
Ciclo “for”: i=9, l=2.
Ciclo “for”: i=10, l=1.

Cómpre saber que ao executar unha instrución de control continue neste tipo de ciclo, a continuación execútase a instrución final, logo avalíase a condición, e logo vólvese ao contido do ciclo.

Outra curiosidade deste ciclo é o feito de que a condición, así coma as outras dúas instrucións entre parénteses, pode obviarse, dando como resultado un ciclo sen fin. Valga de exemplo o seguinte código:

for(;;)
  printf("Ciclo sen fin.\n");
// Repite en pantalla «Ciclo sen fin» ata que se interrompa
// manualmente a execución do programa.

goto[editar]

A instrución de control goto é un mecanismo de control que permite saltar dunha liña de código a outra.

O seu uso é sinxelo. Abonda con colocar nunha liña de código unha etiqueta ─un texto calquera─ seguido de dous puntos, «:», e noutra liña de código escribir goto seguido de dita etiqueta. A seguinte sería a súa sintaxe fundamental:

etiqueta:
// ...
goto etiqueta;

O uso desta instrución de control está desaconsellado salvo para os casos nos que sexa imprescindible o seu uso ou en que este sexa moito máis comprensible á hora de ler o código que o seu equivalente sen esta instrución. Algunhas situacións en que podería usarse esta instrución son as seguintes:

  • Saír dun ciclo con moitos bloques (break non pode saír máis que dun bloque). En todos os casos sería posible saír do ciclo sen necesidade de usar o goto, pero pode resultar nun código case ilexible.
  • Desfacer accións de maneira ordenada, como liberar memoria.


C
← Volver a Operadores Instrucións de control Seguir con Funcións