Informatica
  Sentencias
 

5 Sentencias

Espero que hayas tenido la paciencia suficiente para llegar hasta aquí, y que no te hayas asustado mucho, ahora empezaremos a entrar en la parte interesante y estaremos en condiciones de añadir algún ejemplo.

El elemento que nos falta para empezar a escribir programas que funcionen son las sentencias.

Existen sentencias de varios tipos, que nos permitirán enfrentarnos a todas las situaciones posibles en programación. Estos tipos son:

  • Bloques
  • Expresiones
    • Llamada a función
    • Asignación
    • Nula
  • Bucles
    • while
    • do while
    • for
  • Etiquetas
    • Etiquetas de identificación
    • case
    • default
  • Saltos
    • break
    • continue
    • goto
    • return
  • Selección
    • if...else
    • switch

Bloques  

Una sentencia compuesta o un bloque es un conjunto de sentencias, que puede estar vacía, encerrada entre llaves "{}". Sintácticamente, un bloque se considera como una única sentencia. También se usa en variables compuestas, como veremos en el capítulo de variables II, y en la definición de cuerpo de funciones. Los bloques pueden estar anidados hasta cualquier profundidad.

Expresiones   

Una expresión seguida de un punto y coma (;), forma una sentencia de expresión. La forma en que el compilador ejecuta una sentencia de este tipo evaluando la expresión. Cualquier efecto derivado de esta evaluación se completará antes de ejecutar la siguiente sentencia.

<expresión>;

Llamadas a función

Esta es la manera de ejecutar las funciones que se definen en otras partes del programa o en el exterior de éste, ya sea una librería estándar o particular. Consiste en el nombre de la función, una lista de parámetros entre paréntesis y un ";".

Por ejemplo, para ejecutar la función que declarábamos en el capítulo 3 usaríamos una sentencia como ésta:

Mayor(124, 1234);

Compliquemos un poco la situación para ilustrar la diferencia entre una sentencia de expresión y una expresión, reflexionemos un poco sobre el siguiente ejemplo:

Mayor(124, Mayor(12, 1234));

Aquí se llama dos veces a la función "Mayor", la primera vez como una sentencia, la segunda como una expresión, que nos proporciona el segundo parámetro de la sentencia. En realidad, el compilador evalúa primero la expresión para obtener el segundo parámetro de la función, y después llama a la función. ¿Complicado?. Puede ser, pero también puede resultar interesante...

En el futuro diremos mucho más sobre este tipo de sentencias, pero por el momento es suficiente.

Asignación

Las sentencias de asignación responden al siguiente esquema:

<variable> <operador de asignación> 
<expresión>;

La expresión de la derecha es evaluada y el valor obtenido es asignado a la variable de la izquierda. El tipo de asignación dependerá del operador utilizado, estos operadores ya los vimos en el capítulo anterior.

La expresión puede ser, por supuesto, una llamada a función. De este modo podemos escribir un ejemplo con la función "Mayor" que tendrá más sentido:

m = Mayor(124, 1234);

Nula

La sentencia nula consiste en un único ";". Sirve para usarla en los casos en los que el compilador espera que aparezca una sentencia, pero en realidad no pretendemos hacer nada. Veremos ejemplo de esto cuando lleguemos a los bucles.

 

Bucles   

Estos tipos de sentencias son el núcleo de cualquier lenguaje de programación, y están presentes en la mayor parte de ellos. Nos permiten realizar tareas repetitivas, y se usan en la resolución de la mayor parte de los problemas.

Bucles "while"

Es la sentencia de bucle más sencilla, y sin embargo es tremendamente potente. La sintaxis es la siguiente:

while (<condición>) <sentencia>

La sentencia es ejecutada repetidamente mientras la condición sea verdadera, ("while" en inglés significa "mientras"). Si no se especifica condición se asume que es "true", y el bucle se ejecutará indefinidamente. Si la primera vez que se evalúa la condición resulta falsa, la sentencia no se ejecutará ninguna vez.

Por ejemplo:

while (x < 100) x = x + 1;

Se incrementará el valor de x mientras x sea menor que 100.

Este ejemplo puede escribirse, usando el C con propiedad y elegancia, de un modo más compacto:

while (x++ < 100);

Aquí vemos el uso de una sentencia nula, observa que el bucle simplemente se repite, y la sentencia ejecutada es ";", es decir, nada.

Bucle "do while"

Esta sentencia va un paso más allá que el "while". La sintaxis es la siguiente:

do <sentencia> while(<condicion>);

La sentencia es ejecutada repetidamente mientras la condición resulte verdadera. Si no se especifica condición se asume que es "true", y el bucle se ejecutará indefinidamente. A diferencia del bucle "while", la evaluación se realiza después de ejecutar la sentencia, de modo que se ejecutará al menos una vez. Por ejemplo:

do
   x = x + 1;
while (x < 100);

Se incrementará el valor de x hasta que x valga 100.

Bucle "for"

Por último el bucle "for", es el más elaborado. La sintaxis es:

for ( [<inicialización>]; [<condición>] 
; [<incremento>] ) <sentencia>

La sentencia es ejecutada repetidamente hasta que la evaluación de la condición resulte falsa.

Antes de la primera iteración se ejecutará la iniciación del bucle, que puede ser una expresión o una declaración. En este apartado se iniciarán las variables usadas en el bucle. Estas variables pueden ser declaradas en este punto, pero en ese caso tendrán validez sólo dentro del bucle "for". Después de cada iteración se ejecutará el incremento de las variables del bucle.

Todas las expresiones son opcionales, si no se especifica la condición se asume que es verdadera. Ejemplos:

for(int i = 0; i < 100; i = i + 1);

Como las expresiones son opcionales, podemos simular bucles "while":

for(;i < 100;) i = i +1;
for(;i++ < 100;);

O bucles infinitos:

for(;;); 

Etiquetas   

Los programas C y C++ se ejecutan
secuencialmente, aunque esta secuencia
puede ser interrumpida de varias maneras.
Las etiquetas son la forma en que se indica
al compilador en qué puntos será reanudada
la ejecución de un programa cuando haya
una ruptura del orden secuencial.

Etiquetas de identificación

Corresponden con la siguiente sintaxis:

<identificador>: <sentencia>

Sirven como puntos de entrada para la
sentencia de salto "goto". Estas etiquetas
tienen el ámbito restringido a la función
dentro de la cual están definidas.
Veremos su uso con más detalle al
analizar la sentencia "goto".

Etiquetas "case" y "default"

Esta etiqueta se circunscribe al ámbito de
la sentencia "switch", y se verá su uso
cuando estudiemos ese apartado. Sintaxis:

switch(<variable>)
{
   case <expresión_constante>: [<sentencias>]
[break;] . . . [default: [<sentencias>]] }


Selección   

Las sentencias de selección permiten
controlar el flujo del programa,
seleccionando distintas sentencias en
función de diferentes valores.

Sentencia "if...else"

Implementa la ejecución condicional de
una sentencia. Sintaxis:

if (<condición>) <sentencia1>
if (<condición>) <sentencia1> else 
<sentencia2>

Se pueden declarar variables dentro
de la condición. Por ejemplo:

if(int val = func(arg))...

En este caso, la variable "val" sólo
estará accesible dentro del ámbito de
la sentencia "if" y, si existe, del "else".

Si la condición es "true" se ejecutará
la sentencia1, si es "false" se ejecutará
la sentencia2.

El "else" es opcional, y no pueden
insertarse sentencias entre la sentencia1
y el "else".

Sentencia "switch"

Cuando se usa la sentencia "switch"
el control se transfiere al punto
etiquetado con el "case" cuya expresión
constante coincida con el valor de la
variable del "switch", no te preocupes,
con un ejemplo estará más claro. A partir
de ese punto todas las sentencias serán
ejecutadas hasta el final del "switch",
es decir hasta llegar al "}". Esto es
así porque las etiquetas sólo marcan los
puntos de entrada después de una ruptura de
la secuencia de ejecución, pero no marcan
las salidas.

Esta característica nos permite ejecutar
las mismas sentencias para varias etiquetas
distintas, y se puede eludir usando la
sentencia de ruptura "break" al final de
las sentencias incluidas en cada "case".

Si no se satisface ningún "case", el
control parará a la siguiente sentencia
después de la etiqueta "default". Esta
etiqueta es opcional y si no aparece se
abandonará el "switch".

Sintaxis:

switch (<variable>) 
{
   case <expresión_constante>: 
[<sentencias>] [break;] . . . [default : [<sentencia>]] }

Por ejemplo:

switch(letra) 
{ 
   case 'a': 
   case 'e': 
   case 'i': 
   case 'o': 
   case 'u': 
      EsVocal = true; 
      break; 
   default: 
      EsVocal = false; 
}

En este ejemplo letra es una variable de
tipo "char" y EsVocal de tipo "bool". Si
el valor de entrada en el "switch"
corresponde a una vocal, EsVocal saldrá
con un valor verdadero, en caso contrario,
saldrá con un valor falso. El ejemplo
ilustra el uso del "break", si letra es
'a', se cumple el primer "case", y la
ejecución continúa en la siguiente
sentencia, ignorando el resto de los
"case" hasta el "break".

Otro ejemplo:

Menor1 = Menor2 = Menor3 = Mayor3 = false;
switch(numero) 
{ 
   case 0:
      Menor1 = true; 
   case 1: 
      Menor2 = true;
   case 2: 
      Menor3 = true; 
      break; 
   default: 
      Mayor3 = true; 
}

Veamos qué pasa en este ejemplo si número
vale 1. Directamente se reanuda la ejecución
en "case 1:", con lo cual Menor2 tomará
el valor "true", lo mismo pasará con Menor3.
Después aparece el "break" y se abandona
el "switch".

Sentencias de salto   

Este tipo de sentencia permite romper la
ejecución secuencial de un programa.

Sentencia de ruptura "break"

El uso de esta sentencia dentro de un bucle
pasa el control a la primera sentencia
después de la sentencia de bucle. Lo mismo
se aplica a la sentencia "switch". Sintaxis:

break

Ejemplo:

y = 0;
x = 0;
while(x < 1000)
{
   if(y == 1000) break;
   y++;
}
x = 1;

En este ejemplo el bucle no terminaría
nunca si no fuera por la línea del "break",
ya que x no cambia. Después del "break"
el programa continuaría en la línea "x = 1".

Sentencia de "continue"

El uso de esta sentencia dentro de un
bucle pasa el control al final de la
sentencia de bucle, justo al punto donde
se evalúa la condición para la permanencia
en el bucle. Sintaxis:

continue

Ejemplo:

y = 0;
x = 0;
while(x < 1000)
{
   x++;
   if(y >= 100) continue;
   y++;
}

En este ejemplo la línea "y++" sólo se
ejecutaría mientras "y" sea menor que 100,
en cualquier otro caso el control pasa a la
línea "}", con lo que el bucle volvería a
evaluarse.

Sentencia de salto "goto"

Con el uso de esta sentencia el control se
transfiere directamente al punto etiquetado
con el identificador especificado. El "goto"
es un mecanismo que está en guerra
permanente, y sin cuartel, con la
programación estructurada. El "goto"
no se usa, se incluye aquí porque existe,
pero siempre puede y debe ser eludido.
Existen mecanismos suficientes para hacer
todo aquello que pueda realizarse con un
"goto". Sintaxis:

goto <identificador>

Ejemplo:

x = 0;
Bucle:
x++;
if(x < 1000) goto Bucle;

Este ejemplo emula el funcionamiento
de un bucle "for" como el siguiente:

for(x = 0; x < 1000; x++);

Sentencia de retorno "return"

Esta sentencia sale de la función donde se
encuentra y devuelve el control a la rutina
que la llamó, opcionalmente con un valor
de retorno. Sintaxis:

return [<expresión>]

Ejemplo:

int Paridad(int x)
{
   if(x % 2) return 1; 
   return 0;
}

Este ejemplo ilustra la implementación
de una función que calcula la paridad de
un parámetro. Si el resto de dividir el
parámetro entre 2 es distinto de cero,
implica que el parámetro es impar, y la
función retorna con valor 1. El resto de
la función no se ejecuta. Si por el
contrario el resto de dividir el parámetro
entre 2 es cero, el parámetro será un
número par y la función retornará con
valor cero.

Sobre las sentencias de
salto y la programación
estructurada

Lo dicho para la sentencia "goto" es
válido en general para todas las sentencias
de salto, salvo el "return" y el "break",
este último tiene un poco más de tolerancia,
sobre todo en las sentencias "switch",
donde resulta imprescindible. En general,
es una buena norma huir de las sentencias
de salto.

Comentarios

No se trata propiamente de un tipo de
sentencias, pero me parece que es el
lugar adecuado para introducir este concepto.
En C pueden introducirse comentarios en
cualquier parte del programa, estos
comentarios ayudarán a seguir el
funcionamiento del programa durante la
depuración o en la actualización del
programa, además de documentarlo. Los
comentarios en C se delimitan entre
/* y */, cualquier cosa que escribamos
en su interior será ignorada por el c
ompilador, sólo está prohibido su uso en
el interior de palabras reservadas o en el
interior de identificadores. Por ejemplo:

main(/*Sin argumentos*/void)

está permitido, sin embargo:

ma/*función*/in(void)

es ilegal, se trata de aclarar y documentar,
no de entorpecer el código.

En C++ se ha incluido otro tipo de
comentarios, que empiezan con //. Estos
comentarios no tienen marca de final,
sino que terminan cuando termina la línea.
Por ejemplo:

void main(void) // Esto es un comentario 
{
}

Las llaves {} no forman parte del comentario.

Palabras reservadas usadas
en este capítulo

break, case, continue, default, do, else,
for, goto, if, return, switch y while.

 
  Hoy habia 1 visitantes (1 clics a subpáginas) ¡Aqui en esta página!  
 
Este sitio web fue creado de forma gratuita con PaginaWebGratis.es. ¿Quieres también tu sitio web propio?
Registrarse gratis