Bucles en C, C++ y Objective-C
SOLUCIONARIO
Bucles en C, C++ y Objective-C
2025-03-02
Por
Occam's Razor

#include <stdio.h>

int main (int argc, char *argv[]) {
  int i;
  int a[10];

  for (i = 0; i < 10; i++) a[i] = i + 10;
  i = 0;
  while (i < 10) {
      printf ("%d -> %d\n", i, a[i]);
      i++;
    }
  printf ("---------------------------\n");
  do {
      i--;
      printf ("%d -> %d", i, a[i]);
      if (i > 4) {
          printf ("\n");
          continue;
      }
      printf (" **\n");
      if (i == 1) break;
    } while (i > 0);

  printf ("---------------------------\n");
  for (i = 0; i < 10; printf ("%d ", a[i++]));
  printf ("\n");
}

El lenguaje C nos ofrece tres constructores básicos para repetir instrucciones en nuestros programas (eso es un blucle:) ). En realidad dos de esos constructores son el mismo y existe una cuarta forma de repetir instrucciones que no se suele usar puesto que sigue el paradigma de la programación estructurada.

Los constructor for y while son realmente la misma cosa, siendo for una versión comprimida de while.

La equivalencia sería algo así como:

for (inicializa(); condicion(); repite());

Es lo mismo que

inicializa();
while (condición()) {
  repite();
}

Esta construcción repetirá el código que sigue entre llaves hasta que se cumpla la condición. El bucle for se suele utilizar con un contador, una variable que se inicializa a un cierto valor en el bloque inicializa() y se actualiza en cada iteración del bucle en el bloque repite().

SABIAS QUE?

Para los contadores de los bucles for se suelen utilizar los nombres de variables i, j, k. EL uso de estos nombre tiene su origen en las matemáticas, donde expresiones como sumatorios o series utilizan tradicionalmente estos nombres para los índices. Posteriormente, el lenguaje de programación Fortran (Formula Translator) en sus primeras versiones definía las variables empezando por I hasta N como de tipo entero por defecto y por tanto, como candidatos para contadores de bucles. Si a esto sumamos que Fortran fue un lenguaje científico diseñado para implementar algoritmos matemáticos, hay muchas posibilidades que se diseñara Fortran para seguir el convenio matemático…

Los bucles while como acabamos de decir, también pueden ser usados de esa forma, aunque se suelen elegir cuando la condición de parada del bucle es más general. En esos casos la forma más comprimida de for puede resultar más difícil de leer.

SABIAS QUE

Las distintas partes de for así como la condición de while no tienen porque ser expresiones sencillas. Pueden ser llamadas a funciones e incluso es posible agrupar varias expresiones utilizando la ,.

  for (i = 0, j = 0;
       (i < 10) || (j > 20);
       (j=aread(i)), i++, printf ("%d-%d\n", i, j));

El tercer constructor para implementar bucles en C es do .. while y es similar al constructor while con la diferencia de que el bloque de instrucciones se va a ejecutar siempre, al menos una vez.

La cuarta y última forma de hacer bucles en C es hacerlo como lo haríamos en ensamblador, usando saltos y comparaciones. Algo así como esto:

inicializa ();
bucle:
   procesa ();
   repite();
   if (condicion()) goto bucle;

Podemos generar bucles infinitos en C usando cualquier de estas instrucciones de la siguiente forma:

for (;;) { // bucle infinito }
while (1) { // bucle infinito }
do {// bucle infinito} while (1);
etiqueta:
  // bucle infinito
  goto etiqueta

C ofrece dos instrucciones adicionales para controlar el flujo de ejecución dentro de los bucles. La primera es break que permite terminar el bucle en cualquier momento, reanudando la ejecución del programa justo tras el bucle. La segunda es continue que nos permite forzar la evaluación de la condición de salida del bucle a la vez que reiniciamos la ejecución del bloque. Observad que para los bucles for continue va a evaluar el bloque repite() antes de volver a comprobar la condición, mientras que un bucle while simplemente retornaría a la línea donde se comprueba la condición de salida:

#include <stdio.h>

int main () {
        int i;

        for (i =0; i < 10; i++) {
                if (i == 5) continue;
                printf ("%d\n", i);
        }
        i = 0;
        while (i < 10) {
                if (i == 5) continue;
                printf ("%d\n", i);
                i++;
        }
}

En el programa anterior, el primer bucle mostrará los números del al 9, saltándose el 5. Mientras que el segundo bucle producirá un bucle infinito, puesto que continue devuelve la ejecución a la línea donde comienza el bucle, pero sin modificar el valor de i con lo cual el bucle no puede progresar.

C++ por su parte, dejando a un lado los iteradores de la librería estándar, ofrece desde la versión C++11 una forma sencilla de iterar contenedores. El siguiente código muestra un ejemplo de como usarlo con un array:

#include <iostream>

int main (void)
{
  int a[10];´
  for (int i = 0; i < 10; a[i]=i+10, i++);
  for (auto i : a) std::cout << i << " " ;
  std::cout << std::endl;
}

SABÍAS QUE

La palabra clave auto también fue introducida en C++11 y lo que hace es dejar al compilador la tarea de inferir el tipo de una variable a partir de los valores que se le asignan. En el ejemplo anterior asigna a la variable i el tipo de los elementos del vector. int en este caso.

Objective-C también ofrece una versión simplificada de for para recorrer arrays, si bien, como sucede con C++, todos los tipos de bucle ofrecidos por C funcionan de forma idéntica en estos lenguajes. El siguiente código muestra en ejemplo sobre como recorrer un array usando un for clasico o la versión reducida que ofrece Objective-C

#import <Foundation/Foundation.h>

int main () {
  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]
  NSMutableArray    *a = [NSMutableArray arrayWithObjects: nil];

  for (int i = 0; i < 10; i++)
      [a addObject: [NSNumber numberWithInt: (i + 10)]];

  for (NSNumber *n in a) NSLog (@"Element = %@", n);

  [pool drain];
  return 0;
}

En objective C no tenemos la palabra clave auto así que debemos indicar el tipo de nuestras variables, en este caso, la variable n que usamos para recibir los valores del array en el bucle debe ser de tipo NSNumber puesto que ese es el tipo de los objetos que hemos almacenado en el array.

Observad que los for basados en rango de C++ y Objective-C recorren el contenedor y nos devuelve el valor almacenado en él, no el índice o cualquier otra forma de acceder al valor. Puesto que un contenedor puede ser cualquier cosa, devolver un índice, para ciertos tipos de contenedores simplemente no tiene ningún sentido.

RESUMEN

  • C/C++/Objective-C ofrece bucles for while do while y goto
  • C/C++/Objective-C ofrece instrucciones continue y break
  • C++ for de rango: for (auto i : array)
  • Objective-C for de rango: for ( TYPE *v in array)

SOBRE Occam's Razor
Somos una revista libre que intenta explicar de forma sencilla conceptos tecnológicos y científicos de los que no podemos escapar. Al final, todo es más fácil de lo que parece!

 
Tu publicidad aquí :)