Funciones, bucles, y estructuras de decisión y control

En cuanto a funciones, las características más propias de C++ son los parámetros por defecto:


int multiplica(int x, int y = 2)
{
  return x * y;
}


En caso de que la función multiplica tenga un prototipo, sólo debe especificarse el/los parámetro(s) por defecto en el prototipo.

Ahora es posible llamar a la función:


std::cout << multiplica(5) << std::endl; // Imprime 10


Una segunda característica es la sobrecarga de funciones (esta más común). Es importante recordar que lo que distingue a una función sobrecargada de otra es el tipo y/o el número de los parámetros, pero nunca el tipo de retorno. El compilador no sabrá decidir entre una función con idénticos parámetros (en número y tipos) y distinto tipo de retorno.

Con lo único que debemos tener cuidado es con la combinación de la sobrecarga y el parámetro por defecto;


int multiplica(int x)
{
  return x * 2;
}

int multiplica(int x, int y = 2)
{
  return x * y;
}


Ahora, en caso de hacer la llamada multiplica( 6 ), el compilador no sabrá si nos referimos a la una o a la otra. Se producirá un error en tiempo de compilación.

Otra característica de C++, heredada de C, es el uso de continue, break y goto. En Java es posible utilizar break donde en C++ utilizaríamos goto, puesto que permite break's con etiquetas.

Un ejemplo de break lícito es la búsqueda secuencial (como no hemos visto todavía matrices ni vectores, el ejemplo queda un poco cojo):


int busca(int x)
  int i;
  for(i = 0; i < 1000; ++i) {
    if ( x == i ) break;
  }
  return i;
}


El problema es que break no permite salir de dos (o más de uno) bucles anidados. La única forma de salir correctamente es utilizar goto (éste es uno de esos pocos [escasos] casos en los que utilizar goto está justificado).


int i = 0;
for(int j = 0; j < 1000; ++j) {
  i = 0;
  for(i = 0; i < 1000; ++i) {
    if ( x == i ) goto fin;
  }
}
fin:
return
}


Por último, algo que nos permitirá introducir el tema siguiente es el paso por referencia:


void doble(int &x)
  x *= 2;
}

int main()
  int a = 6;
  doble( a );
}


que sólo existe en C++, y que en C se hace con punteros:


void doble(int *ptrX)
  *ptrX *= 2;
}

int main()
{
  int a = 6;
  doble( &a );
}


El paso por referencia de C++ es mucho más cómodo: en C podríamos equivocarnos y cambiar el puntero en lugar de la variable a la que apunta.

Como repetimos constante, fijaos en los diferentes usos que se hace de '*' y de '&' en el código. El primero puede significar multiplicación, declaración de puntero, o acceso a la variable a la que apunta un puntero, y el segundo puede significar paso por referencia, obtener un puntero de una variable, o una operación AND a nivel de bits.

En C++, muchos componentes del lenguaje (operadores, palabras reservadas ....) significan cosas distintan según el contexto en el que se usen.