Different conventions for main() in C [duplicate]

房东的猫 提交于 2019-12-23 06:58:34

问题


My only exposure to programming has been Java,where I have not encountered (up to now) different conventions for writing the main method.I have been following to sources for learning c (K&R AND C Programming A Modern Approach) where they use very different forms of the main method (function).

K&R version up to now:

main() {
    blah blah blah;
}

C Programming A Modern Approach

int main() {
    blah blah blah;
    return 0;
}

OR

int main() {
    blah blah blah; 
    //returns nothing
}

To make matters more confusing I have seen people do :

int main(void) {
    blah blah blah;
}

while they either returned 0 or did not. I don't in my very uneducated assumption think this is only a standards issue but maybe something a bit more conceptual or deep. Could someone shed some light on this issue?


回答1:


  • K&R style is outdated and isn't correct according to the C standard any more.

  • Valid signatures are

    int main(void)
    

    and

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

    or, equivalent because an array type in a function is adjusted to a pointer type anyways:

    int main(int argc, char **argv)
    
  • The signature

    int main()
    

    happens to be valid as well, because an empty argument list means any number of arguments, that aren't described *). AFAIK, this is subject to change, so don't write it this way. Writing void is how you express this function doesn't take arguments in C.

  • Implementations of C are free to provide other implementation-defined entry points. But the two I listed above are the only ones guaranteed by the standard.

  • C99 introduced a special rule for main() that states if the function doesn't return anything, a value of 0 is returned implicitly. So only in main, you can skip the return. My advice is: don't. It's just confusing. But this is an opinion.


*) note this is different in C++, where nothing between the parantheses indeed means: no arguments.




回答2:


Pre-standardized versions of C (known as K&R C) had the concept of a default type of int if none was given. So in K&R this:

main() {

Is the same as:

int main() {

As for the difference between int main() and int main(void), an empty parameter list means the function takes an unspecified number of parameters while (void) as a parameter list means the function takes no parameters. The former is acceptable, but the latter is preferred as it is more explicit.

Regarding the use of the return statement, a function with a non-void return type must use return to return a value, except (starting with the C99 standard) for the main function. In the case of main, a missing return statement implies a return value of 0.

Because the implicit return 0 for main was added in C99, you'll see some code that explicitly returns and some that doesn't depending on which version of the standard the programmer is conforming to.




回答3:


There are two standard signatures for main as of the latest C language standard:

int main( void ) // void indicates "takes no arguments"

and

int main( int argc, char *argv[] ) // or char **argv, it means the same thing in this context

The names argc and argv are arbitrary; you can use different names if you wish.

Implementations may provide additional valid signatures for main - check your compiler documentation.

If your program does not take any command line arguments, use the first form, otherwise use the second.

C function declaration and definition syntax has evolved a bit over time, which is why different references use different conventions.

Implicit Typing

First of all, C originally allowed for implicit int declarations - if the compiler saw a function definition or declaration without a type specifier, it assumed the function returned int:

foo(); // modern equivalent: int foo( void )

This was allowed up until the 1999 standard, although was considered bad style by most of us long before then.

The void keyword was not introduced until the 1989 standard. As a type specifier, it indicates a type with no values. As an identifier in a function parameter list, it indicates that the function takes no arguments.

Before the introduction of the void keyword, there was no good way (other than documentation) to distinguish between functions that returned a value you were meant to use vs. functions that just executed some action. Some of us used the "implicit int" convention to indicate those functions weren't meant to return anything meaningful:

foo();     /* returns int, but return value not meant to be used */
int bar(); /* returns int, return value meant to be used */

Again, this was just a convention, and far from universal. Now we'd use the void keyword:

void foo(); /* does not return a value */
int bar();  /* returns int */

Function Prototype Syntax

Originally, a function definition looked something like this:

foo( bar, bletch, blurga )
  int bar;
  double bletch;
  char *blurga;
{
  /* function body */
}

The parameter list only specified the names of the parameters, not their types; that was done in a separate set of declarations between the function declarator and the opening { of the function body. A function that took no arguments had an empty identifier list in the function definition:

blah( )  
{
  /* function body */
}

Function declarations only specified the name and return type of the function; it didn't specify the parameters at all:

foo( ); /* no bar, bletch, or blurga */

An empty identifier list in a function declaration indicates that the function takes an unspecified number of arguments, not zero arguments. The compiler could check that the return type of the function call was being used correctly, but it could not check that the number and types of parameters in the call were correct.

The 1989 language standard introduced the concept of function prototype syntax, where the type of each parameter was specified along with its name in the parameter list:

foo( int bar, double bletch, char *blurga )
{
  /* function body */
}

This applied to both the function declaration and definition:

foo( int bar, double bletch, char *blurga );

This change allowed the compiler to check that the number and types of parameters in a function call were correct, along with the return type. In addition, the void keyword could be used in the parameter list to indicate that the function took no parameters, in both the definition and declaration:

blah( void ); /* declaration, returns int, takes no parameters */

blah( void )  /* definition */
{
   /* function body */
}

So yeah, depending on which language revision you're working against, main would be written differently:

K&R:

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

C89:

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

C99 and later:

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



回答4:


C standard defines signature for main either as

int main(void)

or

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

Adding return 0; as a last statement in main function is optional.
Standard also says about some implementation defined prototype. int main() is accepted by GCC compiler.

main() is an old school prototype and almost deprecated.



来源:https://stackoverflow.com/questions/45680009/different-conventions-for-main-in-c

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!