valores usar retornan que funciones funcion ejemplos ejemplo como comandos codigos c++ c return-value main return-type

usar - funciones que retornan valores en c++



¿Qué debería devolver main() en C y C++? (18)

¿Cuál es la forma correcta (más eficiente) de definir la función main() en C y C ++ - int main() o void main() - y por qué? Si int main() return 1 o return 0 ?

Hay numerosos duplicados de esta pregunta, incluyendo:

Relacionado:


¿Cuál es la forma correcta (más eficiente) de definir la función main () en C y C ++ - int main () o void main () - y por qué?

Esas palabras "(más eficiente)" no cambian la pregunta. A menos que se encuentre en un entorno independiente, hay una forma universalmente correcta de declarar main(), y eso es lo mismo que devolver int.

¿Qué debería main()devolver en C y C ++?

No es lo que debería main() regresar, es lo que main() regresa. main()Es, por supuesto, una función que alguien más llama. No tienes ningún control sobre el código que llama main(). Por lo tanto, debe declarar main()con una firma de tipo correcto para que coincida con su interlocutor. Simplemente no tienes otra opción en el asunto. No tiene que preguntarse qué es más o menos eficiente, o qué es mejor o peor estilo, o algo así, porque la respuesta ya está perfectamente definida, para usted, según los estándares C y C +. Sólo tienes que seguirlos.

Si int main () devuelve 1 o devuelve 0?

0 para el éxito, distinto de cero para el fracaso. Nuevamente, no es algo que deba (o acceder) elegir: está definido por la interfaz que se supone que debe cumplir.


Estándar C - Ambiente Alojado

Para un entorno alojado (que es el normal), el estándar C11 (ISO / IEC 9899: 2011) 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 (referidos aquí como argc y argv , aunque se puede usar cualquier nombre, ya que son locales a la función en la que están declarados):

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

o equivalente; 10) 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 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] través de argv[argc-1] inclusive contendrán punteros a cadenas, a los que el entorno de host proporciona valores definidos por la implementación antes del inicio del programa. La intención es proporcionar a la información del programa determinada antes del inicio del programa desde otro lugar en el entorno alojado. Si el entorno del host no es capaz de suministrar cadenas con letras tanto en mayúsculas como en minúsculas, la implementación garantizará 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 en el entorno host. Si el valor de argc es mayor que uno, las cadenas apuntadas por argv[1] través de argv[argc-1] representan los parámetros del programa.
  • Los parámetros argc y argv y las cadenas señaladas 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.

10) Por lo tanto, int se puede reemplazar por un nombre typedef definido como int , o el tipo de argv se puede escribir como char **argv , y así sucesivamente.

Terminación del programa en C99 o C11

El valor devuelto desde main() se transmite al "entorno" de una manera definida por la implementación.

5.1.2.2.3 Terminación del programa

1 Si el tipo de retorno de la función main es un tipo compatible con int , un retorno de la llamada inicial a la función main es equivalente a llamar a la función de exit con el valor devuelto por la función main como su argumento; 11) alcanzar el } que termina la función main devuelve un valor de 0. Si el tipo de retorno no es compatible con int , el estado de terminación devuelto al entorno de host no está especificado.

11) De acuerdo con 6.2.4, los tiempos de vida de los objetos con la duración del almacenamiento automático declarada en main habrán terminado en el primer caso, incluso cuando no lo hubieran hecho en el segundo.

Tenga en cuenta que 0 es obligatorio como ''éxito''. Puede usar EXIT_FAILURE y EXIT_SUCCESS desde <stdlib.h> si lo prefiere, pero 0 está bien establecido, y también lo es 1. Consulte también ¿Los códigos de salida superiores a 255 son posibles? .

En C89 (y, por lo tanto, en Microsoft C), no hay ninguna declaración sobre qué sucede si la función main() devuelve pero no especifica un valor de retorno; por lo tanto, conduce a un comportamiento indefinido.

7.22.4.4 La función de exit

¶5 Finalmente, el control se devuelve al entorno del host. Si el valor del status es cero o EXIT_SUCCESS , se EXIT_SUCCESS una forma definida por la implementación de la terminación exitosa del estado. Si el valor del status es EXIT_FAILURE , se EXIT_FAILURE una forma definida por la implementación del estado de terminación sin éxito . De lo contrario, el estado devuelto está definido por la implementación.

Estándar C ++ - Ambiente Alojado

El estándar C ++ 11 (ISO / IEC 14882: 2011) dice:

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

¶1 Un programa contendrá 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. Deberá tener un tipo de retorno de tipo int, pero de lo contrario, su tipo está definido por la implementación. Todas las implementaciones deberán permitir las dos definiciones siguientes de main:

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

y

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

En la última forma, argc será el número de argumentos pasados ​​al programa desde el entorno en el que se ejecuta el programa. Si argc es distinto de cero, estos argumentos se proporcionarán en argv[0] través de argv[argc-1] como punteros a los caracteres iniciales de cadenas multibyte terminadas en nulo (NTMBSs) (17.5.2.1.4.2) y argv[0] serán el puntero al carácter inicial de un NTMBS que representa el nombre utilizado para invocar el programa o "" . El valor de argc será no negativo. El valor de argv[argc] será 0. [Nota: se recomienda agregar cualquier parámetro adicional (opcional) después de argv . "Nota final"

¶3 La función main no debe usarse dentro de un programa. El enlace (3.5) de main está definido por la implementación. [...]

¶5 Una declaración de retorno en main tiene el efecto de dejar la función principal (destruir cualquier objeto con duración de almacenamiento automático) y llamar a std::exit con el valor de retorno como argumento. Si el control llega al final de main sin encontrar una declaración de retorno, el efecto es el de ejecutar

return 0;

El estándar de C ++ dice explícitamente que "[la función principal] tendrá un tipo de retorno del tipo int , pero de lo contrario su tipo está definido por la implementación", y requiere las mismas dos firmas que el estándar de C para que se admitan como opciones. Por lo tanto, el estándar C ++ no permite directamente un ''void main ()'', aunque no hay nada que pueda hacer para detener una implementación no estándar que permita alternativas. Tenga en cuenta que C ++ prohíbe al usuario llamar a main (pero el estándar C no).

Hay un párrafo de §18.5 Inicio y terminación en el estándar C ++ 11 que es idéntico al párrafo de §7.22.4.4 La función de exit en el estándar C11 (citada arriba), aparte de una nota al pie (que simplemente documenta que EXIT_SUCCESS y EXIT_FAILURE se definen en <cstdlib> ).

Estándar C - Extensión Común

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

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

El tercer argumento es una lista terminada en nulo de punteros a 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 usa esto, aún puede acceder al entorno a través de '' 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 está reconocido por la norma 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 una matriz terminada en nulo de punteros a 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();

o, opcionalmente,

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

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

No me queda claro qué sucede (qué código de salida se devuelve al padre o sistema operativo) cuando sale un programa con void main() , 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 algunas otras alternativas: wmain() que toma cadenas de caracteres amplias, y algunas más.

La versión de Microsoft Visual Studio 2005 de esta página no incluye el void main() como alternativa. Las versions de Microsoft Visual Studio 2008 adelante lo hacen.

Estándar C - Ambiente libre

Como se indicó anteriormente, los requisitos anteriores se aplican a los entornos alojados. Si está trabajando con un entorno independiente (que es la alternativa a un entorno alojado), entonces el estándar tiene mucho menos que decir. Para un entorno independiente, la función llamada al inicio del programa no necesita llamarse main y no hay restricciones en su tipo de retorno. La norma dice:

5.1.2 Entornos de ejecución

Se definen dos entornos de ejecución: independientes y alojados. En ambos casos, el inicio del programa se produce cuando el entorno de ejecución llama a una función C designada. Todos los objetos con duración de almacenamiento estático se inicializarán (configurados en sus valores iniciales) antes del inicio del programa. La manera y el momento de dicha inicialización no se especifican de otro modo. La terminación del programa devuelve el control al entorno de ejecución.

5.1.2.1 Entorno independiente

En un entorno independiente (en el que la ejecución del programa C puede realizarse 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. Todas las instalaciones de la biblioteca disponibles para un programa independiente, distintas del conjunto mínimo requerido por la cláusula 4, están definidas por la implementación.

El efecto de la terminación del programa en un entorno independiente está definido por la implementación.

La referencia cruzada a la cláusula 4 Conformidad se refiere a esto:

¶5 Un programa que cumpla estrictamente las normas del lenguaje y la biblioteca especificadas en esta Norma Internacional. 3) No producirá resultados dependientes de ningún comportamiento no especificado, indefinido o definido por la implementación, y no deberá exceder ningún límite mínimo de implementación.

¶6 Las dos formas de implementación conforme son alojadas y son independientes . Una implementación alojada conforme aceptará cualquier programa estrictamente conforme. Una implementación independiente conforme debe aceptar cualquier programa estrictamente conforme en el cual el uso de las características especificadas en la cláusula de la biblioteca (cláusula 7) se limite al contenido de los encabezados estándar <float.h> , <iso646.h> , <limits.h> , <stdalign.h> , <stdarg.h> , <stdbool.h> , <stddef.h> , <stdint.h> y <stdnoreturn.h> . Una implementación conforme puede tener extensiones (incluidas funciones de biblioteca adicionales), siempre que no alteren el comportamiento de ningún programa estrictamente conforme. 4)

¶7 Un programa conforme es uno que es aceptable para una implementación conforme. 5)

3) Un programa estrictamente conforme puede usar características condicionales (ver 6.10.8.3) siempre que el uso esté protegido por una directiva de preprocesamiento de inclusión condicional apropiada que utilice la macro relacionada. Por ejemplo:

#ifdef __STDC_IEC_559__ /* FE_UPWARD defined */ /* ... */ fesetround(FE_UPWARD); /* ... */ #endif

4) Esto implica que una implementación conforme no reserva identificadores distintos de los explícitamente reservados en esta Norma Internacional.

5) Los programas que se ajustan estrictamente están destinados a ser portátiles de manera máxima entre las implementaciones conformes. Los programas de conformidad pueden depender de características no portátiles de una implementación conforme.

Es evidente que el único encabezado requerido de un entorno independiente que realmente define cualquier función es <stdarg.h> (e incluso esas pueden ser, y con frecuencia son, solo macros).

Estándar C ++ - Entorno independiente

Al igual que el estándar C reconoce tanto el entorno alojado como el independiente, también lo hace el estándar C ++. (Citas de ISO / IEC 14882: 2011.)

1.4 Cumplimiento de la implementación [intro.compliance]

¶7 Se definen dos tipos de implementaciones: una implementación alojada y una implementación independiente . Para una implementación alojada, esta Norma Internacional define el conjunto de bibliotecas disponibles. Una implementación independiente es aquella en la que la ejecución puede realizarse sin el beneficio de un sistema operativo, y tiene un conjunto de bibliotecas definido por la implementación que incluye ciertas bibliotecas de soporte de idioma (17.6.1.3).

¶8 Una implementación conforme puede tener extensiones (incluidas funciones de biblioteca adicionales), siempre que no alteren el comportamiento de ningún programa bien formado. Las implementaciones son necesarias para diagnosticar programas que utilizan dichas extensiones que están mal formadas de acuerdo con esta Norma Internacional. Sin embargo, al hacerlo, pueden compilar y ejecutar dichos programas.

¶9 Cada implementación debe incluir documentación que identifique todas las construcciones condicionales compatibles que no admita y define todas las características específicas de la localidad. 3

3) Esta documentación también define el comportamiento definido por la implementación; ver 1.9.

17.6.1.3 Implementaciones independientes [cumplimiento]

Se definen dos tipos de implementaciones: alojadas y independientes (1.4). Para una implementación alojada, esta Norma Internacional describe el conjunto de encabezados disponibles.

Una implementación independiente tiene un conjunto de encabezados definidos por la implementación. Este conjunto incluirá al menos los encabezados que se muestran en la Tabla 16.

La versión provista del encabezado <cstdlib> declarará al menos las funciones abort , atexit , at_quick_exit , exit y quick_exit (18.5). Los otros encabezados enumerados en esta tabla deben cumplir los mismos requisitos que para una implementación alojada.

Tabla 16 - Cabeceras de C ++ para implementaciones independientes

Subclause Header(s) <ciso646> 18.2 Types <cstddef> 18.3 Implementation properties <cfloat> <limits> <climits> 18.4 Integer types <cstdint> 18.5 Start and termination <cstdlib> 18.6 Dynamic memory management <new> 18.7 Type identification <typeinfo> 18.8 Exception handling <exception> 18.9 Initializer lists <initializer_list> 18.10 Other runtime support <cstdalign> <cstdarg> <cstdbool> 20.9 Type traits <type_traits> 29 Atomics <atomic>

¿Qué hay de usar int main() en C?

La norma §5.1.2.2.1 de la norma C11 muestra la notación preferida - int main(void) - pero también hay dos ejemplos en la norma que muestran int main() : §6.5.3.4 ¶8 y §6.7.6.3 ¶20 . Ahora, es importante tener en cuenta que los ejemplos no son "normativos"; son sólo ilustrativos. Si hay errores en los ejemplos, no afectan directamente al texto principal del estándar. Dicho esto, son indicativos del comportamiento esperado, por lo que si el estándar incluye int main() en un ejemplo, sugiere que int main() no está prohibido, incluso si no es la notación preferida.

6.5.3.4 Los operadores sizeof y _Alignof

...

¶8 EJEMPLO 3 En este ejemplo, el tamaño de una matriz de longitud variable se calcula y se devuelve desde una función:

#include <stddef.h> size_t fsize3(int n) { char b[n+3]; // variable length array return sizeof b; // execution time sizeof } int main() { size_t size; size = fsize3(10); // fsize3 returns 13 return 0; }


Omitir return 0

Cuando un programa C o C ++ llega al final del maincompilador, se generará automáticamente un código para devolver 0, por lo que no es necesario ponerlo return 0;explícitamente al final main.

Nota: cuando hago esta sugerencia, es casi siempre seguida por uno de los dos tipos de comentarios: "No lo sabía". o "¡Eso es un mal consejo!" Mi razonamiento es que es seguro y útil confiar en el comportamiento del compilador explícitamente admitido por el estándar. Para C, desde C99; ver ISO / IEC 9899: 1999 sección 5.1.2.2.3:

[...] un retorno de la llamada inicial a la mainfunción es equivalente a llamar a la exitfunción con el valor devuelto por la mainfunción como su argumento; Al llegar al }que termina la mainfunción devuelve un valor de 0.

Para C ++, desde el primer estándar en 1998; Ver ISO / IEC 14882: 1998 sección 3.6.1:

Si el control llega al final de main sin encontrar una declaración de devolución, el efecto es el de ejecutar la devolución 0;

Todas las versiones de ambos estándares desde entonces (C99 y C ++ 98) han mantenido la misma idea. Confiamos en las funciones miembro generadas automáticamente en C ++, y pocas personas escriben return;declaraciones explícitas al final de una voidfunción. Las razones contra la omisión parecen reducirse a "se ve raro" . Si, como yo, tiene curiosidad acerca de las razones para el cambio al estándar C, lea esta pregunta . También tenga en cuenta que a principios de la década de 1990, esto se consideraba una "práctica descuidada" porque en ese momento era un comportamiento indefinido (aunque ampliamente admitido).

Así que abogo por omitirlo; otros no están de acuerdo (a menudo con vehemencia). En cualquier caso, si encuentra un código que lo omita, sabrá que el estándar lo admite explícitamente y sabrá qué significa.


Creo que main() debería devolver EXIT_SUCCESS o EXIT_FAILURE . Se definen en stdlib.h


El valor de retorno para main debe indicar cómo salió el programa. La salida normal generalmente se representa con un valor de retorno de 0 de main . La salida anormal generalmente se señala con un retorno distinto de cero, pero no hay un estándar sobre cómo se interpretan los códigos distintos de cero. También como lo señalan otros, void main() está explícitamente prohibido por el estándar C ++ y no debe usarse. Las firmas main C ++ válidas son:

int main()

y

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

que es equivalente a

int main(int argc, char** argv)

También vale la pena tener en cuenta que en C ++, int main() se puede dejar sin un valor de retorno en el punto en el que por defecto devuelve 0. Esto también es cierto con un programa C99. Si el return 0 debe omitirse o no está abierto a debate. El rango de firmas principales del programa C válido es mucho mayor.

Además, la eficiencia no es un problema con la función main . Solo puede ingresarse y dejarse una vez (marcando el inicio y la terminación del programa) de acuerdo con el estándar C ++. Para C, el caso es diferente y se permite volver a ingresar a main() , pero se debe evitar.


La respuesta aceptada parece estar dirigida a C ++, así que pensé que agregaría una respuesta que pertenece a C, y esto difiere de varias maneras.

ISO / CEI 9899: 1989 (C90):

main() debe declararse como:

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

O equivalente. Por ejemplo, int main(int argc, char *argv[]) es equivalente al segundo. Además, el tipo de retorno int se puede omitir ya que es un valor predeterminado.

Si una implementación lo permite, main() se puede declarar de otras maneras, pero esto hace que la implementación del programa esté definida y ya no sea estrictamente conforme.

El estándar define 3 valores para devolución que son estrictamente conformes (es decir, no se basan en el comportamiento definido por la implementación): 0 y EXIT_SUCCESS para una terminación exitosa, y EXIT_FAILURE para una terminación sin éxito. Cualquier otro valor no es estándar y su implementación está definida. main() debe tener una declaración de return explícita al final para evitar un comportamiento indefinido.

Finalmente, no hay nada malo desde el punto de vista de los estándares al llamar a main() desde un programa.

ISO / CEI 9899: 1999 (C99):

Para C99, todo es igual que arriba excepto:

  • El tipo de retorno int no puede ser omitido.
  • Puede omitir la declaración de devolución de main() . Si lo hace, y main() finaliza, hay un return 0 implícito return 0 .

Tenga en cuenta que los estándares C y C ++ definen dos tipos de implementaciones: independientes y alojadas.

  • Entorno alojado C90

    Formas permitidas 1 :

    int main (void) int main (int argc, char *argv[]) main (void) main (int argc, char *argv[]) /*... etc, similar forms with implicit int */

    Comentarios:

    Los dos primeros se declaran explícitamente como los formularios permitidos, los otros se permiten implícitamente porque C90 permitió "int implícito" para el tipo de retorno y los parámetros de función. No se permite ninguna otra forma.

  • Entorno libre C90

    Se permite cualquier forma o nombre de main 2 .

  • Entorno alojado C99

    Formularios permitidos 3 :

    int main (void) int main (int argc, char *argv[]) /* or in some other implementation-defined manner. */

    Comentarios:

    C99 eliminó "int implícito", por lo que main() ya no es válido.

    Se ha introducido una frase extraña y ambigua "o de alguna otra manera definida por la implementación". Esto puede interpretarse como "los parámetros a int main() pueden variar" o como "main puede tener cualquier forma definida por la implementación".

    Algunos compiladores han optado por interpretar el estándar de esta última manera. Podría decirse que uno no puede afirmar fácilmente que no se ajustan estrictamente citando el estándar en sí mismo, ya que es ambiguo.

    Sin embargo, permitir formas completamente salvajes de main() probablemente no fue (?) La intención de esta nueva oración. El razonamiento de C99 (no normativo) implica que la oración se refiere a parámetros adicionales a int main 4 .

    Sin embargo, la sección para la finalización del programa de entorno alojado continúa discutiendo sobre el caso donde main no devuelve int 5 . Aunque esa sección no es normativa sobre cómo debe declararse main, definitivamente implica que main podría declararse de una forma completamente definida por la implementación, incluso en sistemas alojados.

  • Entorno libre C99

    Se permite cualquier forma o nombre de main 6 .

  • Entorno alojado C11

    Formas permitidas 7 :

    int main (void) int main (int argc, char *argv[]) /* or in some other implementation-defined manner. */

  • Entorno libre C11

    Se permite cualquier forma o nombre de main 8 .

Tenga en cuenta que int main() nunca se incluyó como un formulario válido para ninguna implementación hospedada de C en ninguna de las versiones anteriores. En C, a diferencia de C ++, () y (void) tienen diferentes significados. La primera es una característica obsolescente que puede ser eliminada del idioma. Ver direcciones de lenguaje C11 en el futuro:

6.11.6 Declaradores de función

El uso de los declaradores de función con paréntesis vacíos (no los declaradores de tipo de parámetro de formato de prototipo) es una característica obsoleta.

  • C ++ 03 entorno alojado

    Formularios permitidos 9 :

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

    Comentarios:

    Note el paréntesis vacío en la primera forma. C ++ y C son diferentes en este caso, porque en C ++ esto significa que la función no toma parámetros. Pero en C significa que puede tomar cualquier parámetro.

  • Entorno independiente C ++ 03

    El nombre de la función llamada al inicio está definido por la implementación. Si se llama main() debe seguir los formularios 10 indicados:

    // implementation-defined name, or int main () int main (int argc, char *argv[])

  • Entorno alojado en C ++ 11

    Formularios permitidos 11 :

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

    Comentarios:

    El texto de la norma ha sido cambiado pero tiene el mismo significado.

  • Entorno independiente C ++ 11

    El nombre de la función llamada al inicio está definido por la implementación. Si se llama main() debe seguir los formularios 12 indicados:

    // implementation-defined name, or int main () int main (int argc, char *argv[])

Referencias

  1. ANSI X3.159-1989 2.1.2.2 Entorno alojado. "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 (referidos aquí como argc y argv, aunque se puede usar cualquier nombre, ya que son locales a la función en la que están declarados):

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

  2. ANSI X3.159-1989 2.1.2.1 Entorno independiente:

    En un entorno independiente (en el que la ejecución del programa C puede realizarse 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.

  3. ISO 9899: 1999 5.1.2.2 Entorno alojado -> 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 (referidos aquí como argc y argv, aunque se puede usar cualquier nombre, ya que son locales a la función en la que están declarados):

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

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

  4. Justificación de la norma internacional - Lenguajes de programación - C, Revisión 5.10. 5.1.2.2 Entorno alojado -> 5.1.2.2.1 Inicio del programa

    El comportamiento de los argumentos a main y de la interacción de exit, main y atexit (véase §7.20.4.2) se ha codificado para frenar algunas variaciones no deseadas en la representación de cadenas argv y en el significado de los valores devueltos por main.

    La especificación de argc y argv como argumentos a main reconoce la práctica previa extensa. argv [argc] debe ser un puntero nulo para proporcionar una comprobación redundante para el final de la lista, también sobre la base de la práctica común.

    main es la única función que se puede declarar de forma portátil con cero o dos argumentos.(El número de argumentos de otras funciones debe coincidir exactamente entre invocación y definición.) Este caso especial simplemente reconoce la práctica generalizada de dejar de lado los argumentos cuando el programa no accede a las cadenas de argumentos del programa. Si bien muchas implementaciones admiten más de dos argumentos principales, tal práctica no está bendecida ni prohibida por el Estándar; un programa que define main con tres argumentos no es estrictamente conforme (vea §J.5.1.).

  5. ISO 9899: 1999 5.1.2.2 Entorno alojado -> 5.1.2.2.3 Terminación del programa

    Si el tipo de retorno de la función principal es un tipo compatible con int, un retorno de la llamada inicial a la función principal es equivalente a llamar a la función de salida con el valor devuelto por la función principal como su argumento; 11) alcanzar el }que termina la función principal devuelve un valor de 0. Si el tipo de retorno no es compatible con int, el estado de terminación devuelto al entorno de host no está especificado.

  6. ISO 9899: 1999 5.1.2.1 Entorno independiente

    En un entorno independiente (en el que la ejecución del programa C puede realizarse 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.

  7. ISO 9899: 2011 5.1.2.2 Entorno alojado -> 5.1.2.2.1 Inicio del programa

    Esta sección es idéntica a la C99 citada anteriormente.

  8. ISO 9899: 1999 5.1.2.1 Entorno independiente

    Esta sección es idéntica a la C99 citada anteriormente.

  9. ISO 14882: 2003 3.6.1 Función principal

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

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

    y

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

  10. ISO 14882: 2003 3.6.1 Función principal

    Se define por la implementación si se requiere un programa en un entorno independiente para definir una función principal.

  11. ISO 14882: 2011 3.6.1 Función principal

    Una implementación no debe predefinir la función principal. Esta función no debe estar sobrecargada. Deberá tener un tipo de retorno de tipo int, pero de lo contrario su tipo está definido por la implementación. Todas las implementaciones permitirán tanto

    - una función de () devolver int y

    - una función de (int, puntero a puntero a char) que devuelve int

    como el tipo de principal (8.3.5).

  12. ISO 14882: 2011 3.6.1 Función principal

    Esta sección es idéntica a la C ++ 03 citada anteriormente.


main() en C89 y K&R C, los tipos de retorno no especificados por defecto son ''int''.

return 1? return 0?

  1. Si no escribe una declaración de devolución int main(), el cierre {devolverá 0 de forma predeterminada.

  2. return 0o return 1será recibido por el proceso padre. En un shell, entra en una variable de shell, y si está ejecutando su programa desde un shell y no está usando esa variable, entonces no debe preocuparse por el valor de retorno de main().

Ver ¿Cómo puedo obtener lo que mi función principal ha devuelto? .

$ ./a.out $ echo $?

De esta manera puede ver que es la variable la $?que recibe el byte menos significativo del valor de retorno de main().

En las secuencias de comandos de Unix y DOS, return 0en caso de éxito y no cero para error, generalmente se devuelven. Este es el estándar utilizado por las secuencias de comandos de Unix y DOS para averiguar qué sucedió con su programa y controlar todo el flujo.


Aquí hay una pequeña demostración del uso de códigos de retorno ...

Cuando se usan las diversas herramientas que proporciona el terminal de Linux, se puede usar el código de retorno, por ejemplo, para el manejo de errores una vez que se haya completado el proceso. Imagina que el siguiente archivo de texto myfile está presente:

Este es un ejemplo para comprobar cómo funciona grep.

Cuando ejecutas el comando grep se crea un proceso. Una vez que finaliza (y no se interrumpió), devuelve un código entre 0 y 255. Por ejemplo:

$ grep order myfile

Si lo haces

$ echo $? $ 0

obtendrá un 0. ¿Por qué? Porque grep encontró una coincidencia y devolvió un código de salida 0, que es el valor habitual para salir con éxito. Vamos a comprobarlo de nuevo, pero con algo que no está dentro de nuestro archivo de texto y por lo tanto no se encontrará ninguna coincidencia:

$ grep foo myfile $ echo $? $ 1

Como grep no pudo hacer coincidir el token "foo" con el contenido de nuestro archivo, el código de retorno es 1 (este es el caso habitual cuando se produce un error, pero como se indicó anteriormente, hay muchos valores para elegir).

Ahora la siguiente secuencia de comandos bash (simplemente escríbala en un terminal de Linux), aunque muy básica, debería dar una idea del manejo de errores:

$ grep foo myfile $ CHECK=$? $ [ $CHECK -eq 0] && echo ''Match found'' $ [ $CHECK -ne 0] && echo ''No match was found'' $ No match was found

Después de la segunda línea, no se imprime nada en el terminal ya que "foo" hizo que grep devolviera 1 y verificamos si el código de retorno de grep era igual a 0. La segunda declaración condicional hace eco de su mensaje en la última línea, ya que es verdadera debido a CHECK == 1.

Como puede ver si está llamando a esto y ese proceso, a veces es esencial ver lo que ha devuelto (por el valor de retorno de main ()).


Devolver 0 debe decirle al programador que el programa ha completado exitosamente el trabajo.


El sistema operativo puede utilizar el valor de retorno para verificar cómo se cerró el programa.

El valor de retorno 0 generalmente significa OK en la mayoría de los sistemas operativos (los que se me ocurren de todos modos).

También se puede verificar cuando llama a un proceso, y ver si el programa salió y finalizó correctamente.

Es NO sólo una convención de programación.


Si realmente tiene problemas relacionados con la eficiencia de devolver un entero desde un proceso, probablemente debería evitar llamar a ese proceso tantas veces que este valor devuelto se convierta en un problema.

Si está haciendo esto (llame a un proceso tantas veces), debe encontrar una manera de poner su lógica directamente dentro de la persona que llama, o en un archivo DLL, sin asignar un proceso específico para cada llamada; Las asignaciones de procesos múltiples le traen el problema de eficiencia relevante en este caso.

En detalle, si solo quiere saber si devolver 0 es más o menos eficiente que devolver 1, podría depender del compilador en algunos casos, pero genéricamente, suponiendo que se lean desde la misma fuente (local, campo, constante, incrustado en el código, el resultado de la función, etc.) requiere exactamente el mismo número de ciclos de reloj.


Tenía la impresión de que el estándar especifica que main no necesita un valor de retorno ya que un retorno exitoso se basó en el sistema operativo (cero en uno podría ser un éxito o un fracaso en otro), por lo tanto, la ausencia de retorno fue una señal para compilador para insertar la propia devolución con éxito.

Sin embargo por lo general vuelvo 0.


Tenga en cuenta que, aunque está devolviendo un int, algunos sistemas operativos (Windows) truncan el valor devuelto a un solo byte (0-255).


Devuelve 0 en caso de éxito y no cero para error. Este es el estándar utilizado por las secuencias de comandos de UNIX y DOS para averiguar qué sucedió con su programa.


El valor de retorno de main()muestra cómo salió el programa. Si el valor de retorno es zero, significa que la ejecución fue exitosa, mientras que cualquier valor distinto de cero representará que algo salió mal en la ejecución.


En C ++, la función principal se debe declarar como int main () y no void main (), ya que el compilador arroja un error en el caso de void main. La función principal puede tomar cualquier número de argumentos como int main (int k, int l, int arr []) o int main (void).

#include <iostream> using namespace std; int main(void) { // your code goes here cout<<"a"; return 0; }

Salida:

Success #stdin #stdout 0s 4416KB a

Llegando a la parte de devolución, debería devolver solo 0; de lo contrario, el compilador arrojará un error. por ejemplo, si devuelve 1, obtendrá la salida deseada pero también arroja un error de tiempo de ejecución.

Ejemplo

#include <iostream> using namespace std; int main(int k,float m,char g, int arr[]) { // your code goes here k=0; cout<<k; g=''a''; cout<<g; cout<<"a"; return 1; }

Salida:

Runtime error #stdin #stdout 0s 4448KB 0aa


Lo que se devuelve depende de lo que quieras hacer con el ejecutable. Por ejemplo, si está utilizando su programa con un shell de línea de comandos, debe devolver 0 para un éxito y un cero para el fracaso. Entonces podrá utilizar el programa en shells con procesamiento condicional dependiendo del resultado de su código. También puede asignar cualquier valor distinto de cero según su interpretación, por ejemplo, para errores críticos, diferentes puntos de salida del programa podrían terminar un programa con diferentes valores de salida, y está disponible para el shell que realiza la llamada y puede decidir qué hacer inspeccionando el valor devuelto. Si el código no está diseñado para su uso con shells y el valor devuelto no molesta a nadie, entonces puede omitirse. Yo personalmente uso la firmaint main (void) { .. return 0; .. }