tipos retorno predefinidas parametros lenguaje funciones funcion ejemplos con c function-prototypes

retorno - funciones predefinidas en c



¿Cuáles son las firmas válidas para la función main() de C? (5)

Estándar C

Para un entorno alojado (que es el normal), el estándar C99 dice:

5.1.2.2.1 Inicio del programa

La función llamada al inicio del programa se llama main . La implementación no declara ningún prototipo para esta función. Se definirá con un tipo de retorno de int y sin parámetros:

int main(void) { /* ... */ }

o con dos parámetros (a los que se hace referencia aquí como argc y argv , aunque se pueden usar los nombres, ya que son locales para la función en la que se declaran):

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

o equivalente; 9) o de alguna otra manera definida por la implementación.

9) Por lo tanto, int puede ser reemplazado por un nombre typedef definido como int , o el tipo de argv puede escribirse como char **argv , y así sucesivamente.

Estándar C ++

El estándar C ++ 98 dice:

3.6.1 Función principal [basic.start.main]

1 Un programa debe contener una función global llamada main, que es el inicio designado del programa. [...]

2 Una implementación no debe predefinir la función principal. Esta función no debe estar sobrecargada. Tendrá un tipo de retorno de tipo int, pero de lo contrario su tipo está definido por la implementación. Todas las implementaciones permitirán ambas de las siguientes definiciones de main:

int main() { /* ... */ }

y

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

El estándar de C ++ dice explícitamente que "[la función principal] tendrá un tipo de retorno de tipo int, pero de lo contrario su tipo es implementación definida", y requiere las mismas dos firmas que el estándar C. Entonces, un ''void main ()'' no está directamente permitido por el estándar de C ++, aunque no hay nada que pueda hacer para detener una implementación no estándar que permita alternativas.

Extensión común

Clásicamente, los sistemas Unix admiten una tercera variante:

int main(int argc, char **argv, char **envp) { ... }

El tercer argumento es una lista de punteros terminados en nulo para cadenas, cada una de las cuales es una variable de entorno que tiene un nombre, un signo igual y un valor (posiblemente vacío). Si no lo usa, puede acceder al entorno a través del entorno '' extern char **environ; ''. Durante mucho tiempo, no tenía un encabezado que lo declarara, pero el estándar POSIX 2008 ahora requiere que se declare en <unistd.h> .

Esto es reconocido por el estándar C como una extensión común, documentada en el Anexo J:

J.5.1 Argumentos del entorno

¶1 En un entorno alojado, la función principal recibe un tercer argumento, char *envp[] , que apunta a un conjunto de punteros terminados en nulo en char , cada uno de los cuales apunta a una cadena que proporciona información sobre el entorno para esta ejecución del programa (5.1.2.2.1).

Microsoft C

El compilador de Microsoft VS 2010 es interesante. El sitio web dice:

La sintaxis de declaración para main es

int main();

u, opcionalmente,

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

Alternativamente, las funciones main y wmain se pueden declarar como wmain void (sin valor de retorno). Si declara main o wmain como wmain void, no puede devolver un código de salida al proceso principal o al sistema operativo mediante el uso de una declaración return. Para devolver un código de salida cuando main o wmain se declara void , debe usar la función de exit .

No está claro para mí qué sucede (qué código de salida se devuelve al padre o al o) cuando un programa con void main() sale, y el sitio web de MS también está en silencio.

Curiosamente, MS no prescribe la versión de dos argumentos de main() que requieren los estándares C y C ++. Solo prescribe una forma de tres argumentos donde el tercer argumento es char **envp , un puntero a una lista de variables de entorno.

La página de Microsoft también enumera otras alternativas: wmain() que toma cadenas de caracteres anchas, y algunas más.

La versión Microsoft VS 2005 de esta página no enumera void main() como alternativa. Las versions de Microsoft VS 2008 en adelante lo hacen.

¿Cuáles son realmente las firmas válidas para la función principal en C? Lo sé:

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

¿Hay otros válidos?


El estándar actual como en el momento de esta respuesta (C11) menciona explícitamente estos dos:

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

aunque menciona la frase "o equivalente" con la siguiente nota al pie:

Por lo tanto, int puede reemplazarse por un nombre typedef definido como int , o el tipo de argv puede escribirse como char ** argv , y así sucesivamente.

Además, también proporciona más posibilidades (definidas por la implementación).

La sección correspondiente (sección 5.1.2.2.1 en C11, pero este aspecto particular no ha cambiado desde C99) dice:

La función llamada al inicio del programa se llama main. La implementación no declara ningún prototipo para esta función. Se definirá con un tipo de retorno de int y sin parámetros:

int main(void) { /* ... */ }

o con dos parámetros (a los que se hace referencia aquí como argc y argv, aunque se pueden usar los nombres, ya que son locales para la función en la que se declaran):

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

o equivalente; o de alguna otra manera definida por la implementación.

Si se declaran, los parámetros de la función principal obedecerán las siguientes restricciones:

  • El valor de argc debe ser no negativo.

  • argv[argc] será un puntero nulo.

  • Si el valor de argc es mayor que cero, los miembros de la matriz argv[0] a argv[argc-1] inclusive contendrán punteros a las cadenas, que reciben los valores definidos por la implementación por el entorno de host antes del inicio del programa. La intención es suministrar a la información del programa determinada antes del inicio del programa desde otro lugar en el entorno alojado. Si el entorno de host no es capaz de suministrar cadenas con letras en mayúsculas y minúsculas, la implementación se asegurará de que las cadenas se reciban en minúsculas.

  • Si el valor de argc es mayor que cero, la cadena apuntada por argv[0] representa el nombre del programa; argv[0][0] será el carácter nulo si el nombre del programa no está disponible desde el entorno host. Si el valor de argc es mayor que uno, las cadenas apuntadas por argv[1] a argv[argc-1] representan los parámetros del programa.

  • Los parámetros argc y argv y las cadenas apuntadas por la matriz argv serán modificables por el programa y conservarán sus últimos valores almacenados entre el inicio del programa y la terminación del programa.

Tenga en cuenta que esto es para un entorno alojado, los que normalmente ve en los programas C. Un entorno autónomo (como un sistema integrado) está mucho menos restringido, como se indica en 5.1.2.1 del mismo estándar:

En un entorno independiente (en el que la ejecución del programa C puede tener lugar sin ningún beneficio de un sistema operativo), el nombre y el tipo de la función llamada al inicio del programa están definidos por la implementación. Cualquier instalación de biblioteca disponible para un programa independiente, que no sea el conjunto mínimo requerido por la cláusula 4, está definida por la implementación.


POSIX admite execve() , que a su vez admite

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

El argumento agregado es el entorno, es decir, una matriz de cadenas de la forma NAME = VALUE.


http://en.wikipedia.org/wiki/Main_function_(programming)#C_and_C.2B.2B

Además de lo usual int main(int argc, char *argv[]) y POSIX int main(int argc, char **argv, char **envp) , en Mac OS X también es compatible

int main(int argc, char* argv[], char* envp[], char* apple[]);

Por supuesto, es solo para Mac.

En Windows hay

int wmain(int argc, wchar_t* argv[], wchar_t* envp[]);

como la variante Unicode (en realidad, de caracteres anchos). Por supuesto, también está WinMain .


int main(void)

Bajo algunos sistemas operativos (por ejemplo, Windows) también es válido:

int main(int argc, char **argv, char **envp)

donde envp da un ambiente, de lo contrario accesible a través de getenv()