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 😀

No estaba muerto, estaba de parranda

Por si me habíais echado de menos y os empezabais a cuestionar la continuidad de este blog, no, no lo he abandonado aún. Simplemente he estado liadísimo con el juego para el concurso de XNA, que he acabado dejándolo para última hora y me ha tocado pegarme unas sesiones maratonianas.

Eso sí, en cuanto se haga público el fallo publicaré tanto la versión compilada como el código fuente. Ah, y mientras tanto iré preparando algunos postmortems y artículos varios sobre las cosas que me han parecido más interesantes durante el desarrollo. Paciencia, la espera merecerá la pena 😉