Publi

Cosas que damos por hechas en C/C++: int main(int argc, char *argv[])

photo-1444212568492-d2799d30943b_red

Esta serie de posts está dedicada a tod@s mis alumn@s de clases particulares de programación. Iré añadiendo información de diferentes niveles, dificultades, colores y sabores. Espero que les parezca interesante.

Fue en el primer año de carrera, cuando en la asignatura Fundamentos de Programación y luego en Laboratorio de Programación cuando empezábamos a hacer los primeros programas en C; yo hasta entonces no me había atrevido a programar nada en C, prefería Pascal, al menos llegué con una buena base de programación.

El IDE que utilizábamos (Dev-C++) directamente escribía las primeras líneas de programa:

1
2
3
4
5
6
7
8
#include <iostream>

using namespace std;

int main(int argc, char *argv[])
{

}

Comprendo que en 4 meses hay que enseñar a mucha gente a defenderse con la programación, y no es objeto explicarlo todo detalladamente, aunque cuando alguien preguntaba siempre decían: “Eso hay que ponerlo siempre” es más, nada más empezar el curso, poca gente se va a enterar de qué va el asunto

Bien, empezamos por el include (vale, esto sí que lo contaban mis profesores, porque a veces teníamos que incluir alguna cosa más), incluir funciones y clases hechas por otras personas, y no nos tiene que importar cómo están hechas por dentro.

Un concepto más peliagudo y extenso es el de la línea siguiente: using namespace std (nos metemos a pelear con los espacios de nombres; no quiero ser demasiado extenso, pero imaginemos que hay dos casas en una calle, y cada casa aloja a tres personas: Jose, Virginia y Antonio en la casa A; y Alfonso, Manuela y Jose en la casa B. ¿Cómo distinguimos a Jose de la casa A de Jose de la casa B? Suena a pregunta tonta: Pues casaA::Jose y casaB::Jose, son dos personas diferentes.
Lo mismo podemos hacer en C++, podemos tener funciones que se llaman igual en espacios de nombres (o casas) diferentes, y para referirnos a ellos tenemos que decir primero en qué casa están, para que luego el compilador sepa ubicar a cada uno.
Pero como las pulsaciones de teclado de los desarrolladores son oro (sabemos que tenemos que escribir mucho, si podemos ahorrar algo mejor), y sabemos que muchas de las clases y funciones que vamos a utilizar pertenecen a la librería estándar (o std), es decir, estarán en la mansión std decimos:
using namespace std;
o lo que es lo mismo: si no te digo nada, y llamo a alguien que no encuentras, búscalo en std.

Llegamos al main(), podemos definirlo de muchas formas: muchos utilizan void main() (y gcc se queja), otros int main() (que es perfectamente válido), pero algunas veces se introduce toda esa parafernalia rara de int argc, char *argv[], que es impronunciable, y hace daño a la vista, e incluso si lo intentamos escribir las primeras veces, no nos saldrá igual.
Estos parámetros son para los argumentos del programa, es decir, para los parámetros que introduzcamos en la línea de comandos. Para muchos usuarios que vienen de Windows, les resulta raro entender por qué un programa requiere parámetros, pues bien: si abrimos Mi PC, nos vamos a una carpeta y abrimos un documento, cómo sabe Microsoft Office que hemos abierto este documento? Se lo hemos pasado como parámetro sin querer 🙂
Ahora bien, y esto requiere un poco de imaginación si estamos empezando:
argc es un número que indica el número de parámetros que tiene el ejecutable:

1
2
3
4
5
6
7
8
#include <stdio.h>

int main(int argc, char *argv)
{
  printf("Me has pasado: %d parámetros\n", argc);

  return 0;
}

Veamos qué pasa al ejecutarlo:

$ ./params
Me has pasado: 1 parámetros
$ ./params param1 param2 “parametro 3”
Me has pasado: 4 parámetros
$ ./params param1 param2 “parametro 3” “parametro 4”
Me has pasado: 5 parámetros

Nos sobra uno no? Veamos cuáles son esos parámetros:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>

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

  printf("Me has pasado: %d parámetros\n", argc);

  for (i=0; i<argc; i++)
    {
      printf ("Parámetro %d: %s\n",i,argv[i]);
    }

  return 0;
}

Salida:

$ ./params param1 param2 “parametro 3” “parametro 4”
Me has pasado: 5 parámetros
Parámetro 0: ./params
Parámetro 1: param1
Parámetro 2: param2
Parámetro 3: parametro 3
Parámetro 4: parametro 4

Vemos que el parámetro 0 es el propio nombre del ejecutable y comprobamos que si cambiamos el nombre del ejecutable, podemos saberlo con ese parámetro 0. Los demás podemos averiguarlos recorriendo la variable argv. argv es un Array de punteros de tipo char o lo que es lo mismo un array de cadenas de caracteres puesto que cada parámetro es una cadena de caracteres.

Ahora la pregunta del millón, si utilizamos un array, para qué necesitamos argc ¿? Podríamos averiguar el número de elementos del mismo. La respuesta es que no, de ese Array desconocemos el número de elementos que tiene (depende de lo que nos pase el usuario), y si tenemos un método para calcular el número de parámetros que tenemos, que seguro que podremos encontrarlo, será mucho más rápido disponer de ese valor (y escribimos menos)

Actualiación 04/11/2015: Añadida una foto de cabecera.

Foto: Kimson Doan (unsplash)

También podría interesarte...

There are 5 comments left Ir a comentario

  1. Pingback: Bitacoras.com /

  2. Pingback: Cómo gestionar los parámetros de nuestros programas con getopt en C – Poesía Binaria /

  3. Pingback: Cómo procesar múltiples argumentos de entrada en scripts para Bash – Poesía Binaria /

  4. alex caraballo /
    Usando Mozilla Mozilla 11.0 en Windows Windows 7

    interesante soy estudiante de informática y me atrae mucho programar con c.y c++ y estos tutoriales me caen de maravilla

    1. Gaspar Fernández / Post Author
      Usando Mozilla Firefox Mozilla Firefox 48.0 en Ubuntu Linux Ubuntu Linux

      Muchas gracias !! Estoy encantado de haberte ayudado. No dudes en preguntar cualquier duda por aquí 🙂

Leave a Reply