Viejas joyas…

Yendo de camino al Carrefour del centro comercial de al lado de la Universidad, hemos pasado por delante de Juguetilandia y tras ver en el escaparate un cartel en el que anunciaban la liquidación de juegos antiguos (GameCube, PlayStation 2, XBox y Game Boy Advance), hemos decidido pasar a ver con qué nos encontrábamos.

Casi todo el stock eran los típicos juegos malillos que nadie quiere, pero me he llevado una sorpresa al encontrarme con algunas copias sueltas de Final Fantasy IV Advance, Sword of Mana y Tales of Phantasia, a 6€ cada uno (10€ si te llevabas dos).

Y aquí las tengo, aunque ahora me da pena desprecintar los cartuchos, con lo bonitos que son con el plástico aún puesto:

rpgs

Mañana volveré a ver qué queda de PlayStation 2, porque de XBox he mirado por encima y el único juego que se salvaba era el Tomb Raider Legend.

Segundo puesto

Con un día de retraso, posteo para decir que finalmente acabé en segundo lugar en el concurso de XNA. Y lo considero más que justo, porque tuve que recortar bastantes features y el juego ganador, Dungeon Sorrows, estaba MUY bien hecho. No me llevé la XBox, pero sí un Wireless Laser Desktop 3000 que tampoco está nada mal.

Ahora todos los concursantes disponemos de dos semanas para maquillar y comentar el código, y subiremos los fuentes completos al codeplex de XNA Community.

Seguiré informando, y a ver si acabo los postmortem de una vez por todas 😉

Uso de la función “main” en C/C++

Escribo este post porque según las estadísticas, en los últimos días he recibido bastantes visitas a través de buscadores intentando encontrar una explicación al uso de la función main en C/C++ (seguro que no es la única sorpresa que me da haber escogido este nombre para el blog…). Qué menos que agradar a mi escaso público y ganarme unos cuantos lectores, así que voy a escribir algo útil de una vez y explicaré todo lo profundamente posible esta función.

En primer lugar, la función nunca debe ser declarada como void. Ésta es una mala práctica que se suele cometer, sobre todo al comenzar la andadura con la programación (lo admito, ¡yo también lo hacía al principio!); si bien algunos compiladores lo aceptan, los más estrictos se quejarán en forma de warning o error. Así que hay que usar int para declarar el tipo, o incluso también se puede obviar, porque el compilador le asignará este tipo por defecto.

void main() // MAL: algunos compiladores se quejarán
{
}

int main() // CORRECTO: la forma adecuada de hacerlo
{
}

main() // CORRECTO: no es la mejor, pero los compiladores que sigan el estándar la darán por buena
{
}

Bien, ahora atacaremos los valores de retorno. Esto es muy sencillo; como hemos declarado la función del tipo int, al llegar al final de su ejecución tendremos que devolver un valor. Normalmente se devuelve 0 para indicar que el programa ha finalizado correctamente, y cualquier otro valor para indicar una ejecución anormal. Pero, si queremos ser completamente estrictos (en algunas plataformas el significado de los valores se invierte, y 0 puede significar que ha ocurrido un fallo de ejecución), emplearemos las macros EXIT_FAILURE y EXIT_SUCCESS. Como su nombre bien indica, la primera devuelve una ejecución errónea, y la segunda indica al proceso padre que todo ha ido como debería. Sus definiciones se encuentran en stdlib.h para el lenguaje C y cstdlib.h para C++.

int main()
{
  return EXIT_SUCCESS;  // El programa terminó la ejecución debidamente
}

int main()
{
  return EXIT_FAILURE;  // El programa encontró algún fallo y no pudo finalizar la ejecución correcta
}

int main()
{
  return 5;  // Valor de retorno personalizado; de esta manera podemos indicarle al proceso que invoca a nuestro programa que ha ocurrido algo determinado (por ejemplo, que no se ha llamado al programa con determinados parámetros)
}

Y por último, hablaremos de los parámetros de la función. Hasta ahora, la hemos definido sin ningún tipo de parámetros, porque según el estándar esto puede hacerse perfectamente; sin embargo, main acepta dos parámetros que se explicarán a continuación (hay que recordar que siempre es o cero o dos parámetros, en caso de emplear cualquier otro número el compilador dará warning o error, dependiendo de lo quisquilloso que sea):

  • Primer parámetro: tipo int. Por costumbre se le llama argc, diminutivo de argument count, pero se le puede llamar como se desee. Como su propio nombre indica, contiene el número de argumentos que se le pasan al programa. Hay que tener en cuenta que el primer argumento de un programa siempre será el nombre de este, de tal manera que si hacemos la siguiente ejecución

    :> miprograma param1 param2

    nuestro parámetro argc valdrá 3, y por consiguiente, si llamamos al programa sin parámetros, argc equivaldrá a 1.

  • Segundo parámetro: tipo char**. Aunque también puede especificarse como char* argv[], lo importante es indicar que estamos trabajando con un doble puntero a char, esto es, un vector de vectores de caracteres, o para simplificar, un vector de cadenas. Como se ha indicado anteriormente, el nombre más común para llamar a este parámetro es argv, contracción de argument vector, y al principio puede resultar un poco lioso lidiar con él, más aún si no se han usado punteros nunca. Así que simplemente hay que recordar que estamos trabajando con un vector de cadenas, y que cada posición (recordad, su extensión va desde 0 hasta argc-1) guarda uno de los argumentos empleados al llamar a nuestro programa. Para la ejecución de ejemplo del punto anterior, esta sería la traza de nuestros parámetros:

    argc = 3;
    argv[0] = “miprograma”;
    argv[1] = “param1”;
    argv[2] = “param2”;

Y esto es todo por hoy, como veréis tampoco es para tanto, aunque al principio se pueda atragantar. Y aprovecho para animar a todo el que llegue aquí a que formule las preguntas que quiera, intentaré ayudar en la medida de lo posible 😀