3.- SENTENCIAS DE CONTROL

3.1 LA SENTENCIA while

La sentencia while se utiliza para generar bucles. La forma general de la sentencia es:
                                      while (expresión sentencia;
La sentencia se ejecutará repetidamente mientras el valor de expresión no sea 0. Esta sentencia puede ser simple o compuesta y debe incluir algo que altere el valor de expresión (MUY IMPORTANTE PARA NO HACER UN BUCLE INFINITO)

3.2 LA SENTENCIA do-while

Cuando se construye un bucle utilizando la sentencia while el test para la continuación del bucle se realiza al comienzo de cada pasada. Con la sentencia do-while dicho test se realiza al final de cada pasada, con el siguiente formato:
                                         do    sentencia  while (expresión);
La sentencia se ejecutará repetidamente mientras el valor de expresión no sea 0. Nótese que la sentencia se ejecutará al menos una vez, ya que el test de la condición de repetición no se realiza hasta el final de la pasada por el bucle. La sentencia puede ser simple o compuesta.

3.3 LA SENTENCIA for

Es la sentencia más usada para crear bucles en C. Incluye una expresión que especifica el valor inicial de un índice, otra expresión que determina cuándo se continúa o no el bucle y una tercera expresión que permite que el índice se modifique al final de cada pasada. La forma general de la sentencia es:    
                     for (expresion1;expresion2;expresion3)    sentencia;
Donde expresion1 se utiliza para inicializar algún parámetro (denominado índice) que controla la repetición del bucle, expresion2 representa una condición que debe satisfacerse para que continúe la ejecución del bucle y expresion3 se utiliza para modificar el índice del bucle.
Cuando se ejecuta la sentencia for, expresion2 se evalúa y se comprueba antes de cada pasada a través del bucle, y expresion3 es evaluada al final de cada pasada. Por tanto, la sentencia for es equivalente a:
                            expresion1;
                            while (expresion2)
                            {
                                sentencia;
                                expresion3;
                            }

Desde el punto de vista sintáctico no es necesario que se encuentren presentes las tres expresiones en la sentencia for, aunque deben aparecer los puntos y coma. Las expresiones primera y tercera se pueden suprimir si se inicializa y/o altera el índice de alguna otra forma. Si se omite la segunda expresión, se asume que ésta tiene un valor permanente de cierto y, por tanto, el bucle continuará ejecutándose de forma indefinida a no ser que finalice mediante otro método como una sentencia break o return.

3.4 BUCLES ANIDADOS

Los bucles se pueden anidar uno en otro. Los bucles internos y externos no necesitan ser generados por el mismo tipo de estructura de control. Sin embargo es esencial que un bucle se encuentre completamente incluido dentro del otro. Además, cada bucle debe ser controlado por un índice diferente.

3.5 LA SENTENCIA if-else

Esta sentencia se utiliza para realizar un test lógico y a continuación llevar a cabo una de dos posibles acciones, dependiendo de que el resultado sea cierto o falso.
La parte else de una sentencia if-else es opcional. Por tanto, la sentencia en su forma general más simple se puede escribir
                         if (expresión)    sentencia;
La sentencia se ejecutará sólo si la expresión tiene un valor no nulo (es cierta). La sentencia puede ser simple o compuesta.
La forma general de esta sentencia incluyendo la cláusula else es:
                          if (expresión)   sentencia1;  else   sentencia2;
 Es  posible anidar sentencias if-else una en otra, de la misma forma que los bucles. 

3.6 LA SENTENCIA switch

Hace que se seleccione un grupo de sentencias entre varios grupos disponibles. La selección se basa en el valor de una expresión que se incluye en la sentencia switch. Su forma general es:
            switch (expresión)      //
Donde expresión devuelve un valor entero.
            {
               case valor1: sentencia1_1;
                                   sentencia1_2;
                                   sentencia1_n;
               case valor2
               case valor3: sentencia2_1;
                                   sentencia2_2;
                                   sentencia2_n;
                                  ...
               case valorm: sentenciam_1;
                                    sentenciam_2;
                                    sentenciam_n;
            }

Se puede etiquetar default uno de los grupos de sentencias etiquetados dentro de la sentencia switch. Este grupo se seleccionará si ninguna de las etiquetas case coincide con el valor de expresión. Si ninguna de las etiquetas case coincide con el valor de expresión y no se encuentra presente el grupo default, la sentencia switch no hará nada
La sentencia switch se puede concebir como una alternativa al uso de sentencias if-else anidadas, aunque sólo puede sustituir a aquellas sentencias if-else que comprueben igualdades. En tales situaciones es más conveniente utilizar la sentencia switch.

3.7 LA SENTENCIA break

Se utiliza para terminar la ejecución de bucles o salir de una sentencia switch.
Si se incluye break en un bucle while, do-while o for, entonces se transfiere el control fuera del bucle en el momento en que se encuentra la sentencia break. Esto proporciona una forma conveniente de terminar un bucle cuando se detecta un error o alguna otra condición.
En el caso de varias sentencias while, do-while, for o switch anidadas, una sentencia break causa la transferencia de control fuera de la sentencia más interna en la que se encuentre, pero no de las sentencias más externas.

3.8 LA SENTENCIA  continue

Se utiliza para saltarse el resto de la pasada actual a través de un bucle. El bucle no termina cuando se encuentra una sentencia continue, sencillamente no se ejecutan las sentencias que se encuentran a continuación en él y se salta directamente a la siguiente pasada a través del bucle.


4.- FUNCIONES

4.1 INTRODUCCIÓN

El C utiliza funciones de biblioteca con el fin de realizar un cierto número de operaciones o cálculos de uso común. Sin embargo, C también permite al programador definir sus propias funciones que realicen determinadas tareas. Esto permite dividir un programa en cierto número de componentes más pequeñas.
Una función es un segmento de programa que realiza determinadas tareas bien definidas. Todo programa en C consta de una o más funciones. Una de estas funciones se debe llamar main. La ejecución del programa siempre comenzará por la de las instrucciones contenidas en main.
Cuando se accede a una función desde alguna parte del programa, se ejecutan las instrucciones de que consta. Se puede acceder a una misma función desde varios puntos del programa. Una vez completada la ejecución de una función, se devuelve el control al punto desde el que se accedió a ella.
A la función se le puede pasar información mediante unos identificadores denominados argumentos o parámetros.

Hay tres razones fundamentales para el uso de funciones en C:

- Evitar la repetición innecesaria de código.
- Separando el código en funciones modulares se facilita el diseño y la comprensión de los programas.
- Independencia. El realizar funciones independientes de la función principal e independientes entre sí es una  gran ventaja. Las funciones pueden tener sus propias variables "privadas", es decir, estas variables no pueden ser accedidas desde fuera de la función. Esto significa que el programador no necesita preocuparse por el uso accidental de los mismos nombres de variables en otros puntos del programa.

Para los programadores de Pascal hay que mencionar una diferencia entre el C y el Pascal. En Pascal, las funciones y los procedimientos son dos entidades separadas. Una función en este lenguaje devuelve un valor, mientras que un procedimiento realiza una tarea o devuelve datos a través de argumentos. En C ambas construcciones están combinadas: una función puede devolver datos mediante argumentos y puede devolver, también un valor.

4.2 ESTRUCTURA DE LAS FUNCIONES

Al emplear una función se ven involucrados tres elementos del programa: la definición de la función, la llamada a la función y el prototipo de la función.

La definición de la función
Se denomina definición de la función a la función propiamente dicha. Es de la forma:

            tipo nombre (tipo1 arg1,tipo2 arg2,...,tipon argn)
            {

             }

Hay que hacer notar que la primera línea no finaliza con punto y coma.
Tipo representa el tipo de dato del valor que devuelve la función y si la función no devuelve ningún valor se debe poner void.
Los argumentos, que se denominan en la definición de la función argumentos formales, permiten la transferencia de información desde el punto del programa en donde se llama a la función a ésta. (Los argumentos correspondientes en la llamada a la función se denominan argumentos actuales o reales). Los identificadores utilizados como argumentos formales son locales en el sentido de que no son reconocidos fuera de la función.
Cada argumento formal debe tener el mismo tipo de datos que el correspondiente argumento actual. Esto es, cada argumento formal debe ser del mismo tipo que el dato que recibe desde el punto de llamada.
El resto de la definición de la función es una sentencia compuesta que define las acciones que debe realizar ésta. Se suele llamar a esta sentencia cuerpo de la función.
Se devuelve información desde la función hasta el punto de llamada mediante la sentencia return. La sentencia return también hace que se devuelva el control al punto de llamada.
En términos generales se puede escribir la sentencia return:       return expresión;

Se devuelve el valor de expresión al punto de llamada. La expresión es opcional y si se omite, la sentencia return simplemente devuelve el control al punto del programa desde donde se llamó a la función, sin ninguna transferencia de información.
Sólo se puede incluir una expresión en la sentencia return. Por tanto, una función sólo puede devolver un valor al punto de llamada mediante la sentencia return. Para que la función devuelva más de un valor es necesario otro mecanismo.

Ejemplo de una función que devuelve un valor entero largo:

  long int factorial (int n)
 
{
    long int f=1;
    int i; 
   
for (i=2;i<=n;++i)  f*=i;
   
return (f);

  }

Ejemplo de una función que no devuelve ningún valor:

   void factorial (int n)
     { 
      
long int f=1;
       int i; 
   
   for (i=2;i<=n;++i)  f*=i;
       
      
printf("el factorial de %d es %ld\n",n,f);
      
return;
    }

La llamada o acceso a la función

La llamada a un función se realiza de forma diferente según que la función devuelva o no un valor al punto de llamada.
Si la función no devuelve ningún valor (void) se accede a ella especificando su nombre, seguido de una lista de argumentos cerrados entre paréntesis y separados por comas.
Si la función devuelve un valor se debe acceder a ella desde una expresión.
En ambos casos si la función no requiere argumentos se deben especificar los paréntesis vacíos.
Los argumentos actuales pueden ser constantes, variables o expresiones más complejas. No obstante cada argumento actual debe ser del mismo tipo de datos que el argumento formal correspondiente.

Ejemplos de llamada a una función:
Para el caso de la función factorial que devuelve un valor:

printf("el factorial de %d es %ld\n",n,factorial(n));       ó         fact=factorial(n);         ó

a = a + factorial(n);        ó        if (factorial(n)>50)       ó          switch(factorial(n))

Para el caso de la función factorial que no devuelve nada:               factorial(n);

Prototipo de la función (declaración)

Este es el tercer elemento relacionado con una función. Está formado por una línea antes del comienzo de main(). Esta línea es igual que la primera línea de la definición de la función, excepto que termina en punto y coma. Su propósito es decirle al compilador el nombre de la función, el tipo de dato que devuelve la función (si hay alguno) y el número y tipo de los argumentos de la función (si los hay).
Lo que hay que recordar sobre el prototipo es que los tipos de datos del prototipo y de la definición de la función deben coincidir.

4.3 TIPOS DE ALMACENAMIENTO

Hay dos formas diferente de caracterizar variables: por su tipo de dato y por su tipo de almacenamiento. El tipo de dato refiere al tipo de información representada por una variable. El tipo de almacenamiento refiere a la permanencia de la variable y a su ámbito dentro del programa, que es la porción del programa en la cual se reconoce la variable.
Hay cuatro especificaciones de tipo de almacenamiento diferentes en C: automática, externa, estática y registro. Están identificadas por las palabras clave auto, extern, static y register, respectivamente.
A veces, el tipo de almacenamiento asociado a una variable se puede establecer simplemente por la localización de su declaración en el programa. En otras situaciones, la palabra clave que especifica el tipo de almacenamiento se tiene que colocar al principio de la declaración de la variable.

                       auto int a,b;                   extern float r1;                          static int i=0;

VARIABLES AUTOMATICAS

Se declaran siempre dentro de la función y son locales a la función donde han sido declaradas; es decir, su ámbito está reducido a la función. Las variables automáticas definidas en funciones diferentes serán independientes unas de otras, incluso si tienen el mismo nombre.
Cualquier variable declarada dentro de una función se interpreta como una variable automática a menos que se especifique un tipo de almacenamiento distinto.
Como la localización de la variable dentro del programa determina el tipo de almacenamiento automático, no se necesita la palabra clave auto al principio de cada declaración de variable.
Si una variable automática no es inicializada, su valor inicial será impredecible.
Cualquier valor asignado a una variable automática dentro de una función se pierde al salir de la función.

VARIABLES EXTERNAS

Las variables externas, en contraste con las automáticas, no están confinadas a funciones simples. Su ámbito se extiende desde el punto de definición hasta el resto del programa.
Como las variables externas se reconocen globalmente, pueden accederse desde cualquier función que caiga dentro de su ámbito. Mantienen los valores asignados dentro de este ámbito.
El uso de variables externas proporciona un mecanismo adecuado de transferencia de información entre funciones.

VARIABLES ESTÁTICAS

Las variables estáticas se definen dentro de funciones individuales y tienen, por tanto el mismo ámbito que las variables automáticas. Sin embargo, a diferencia de estas, las variables estáticas retienen sus valores durante toda la vida del programa. Como consecuencia, si se sale de una función y posteriormente se vuelve a entrar, las variables estáticas definidas dentro de esa función retendrán sus valores previos.
Su definición tiene que comenzar con la designación del tipo de almacenamiento static.
Se pueden usar las variables estáticas dentro de una función de la misma manera que las otras variables. Sin embargo, no pueden ser accedidas desde fuera de la función que las define.
Se pueden incluir valores iniciales en las declaraciones de variables estáticas.
A todas las variables estáticas cuyas declaraciones no incluyan valores iniciales explícitos se les asignará el valor 0.

VARIABLES REGISTRO

Los registros son áreas especiales de almacenamiento dentro de la unidad central. En C los valores de las variables registro se almacenan dentro dichos registros, reduciendo de ese modo el tiempo de acceso a los valores de dichas variables.
Para asignar a una variable este tipo de almacenamiento es suficiente con anteponer en la declaración la palabra clave register. Pero sólo puede haber dos o tres variables registro dentro de una función. El número exacto depende del ordenador y del compilador. Normalmente sólo las variables entera tienen este tipo de almacenamiento.


Indice

Ejercicios del Bloque 1

Inicio