Introduction to the Declaration, definition and use of functions in C language _c language

Source: Internet
Author: User
Tags constant function definition function prototype

"Definition" and "declaration" of functions are not the same thing. The definition of function refers to the establishment of function function, including specifying function name, function value type, formal parameter and its type, function body, etc., which is a complete and independent function unit. And the function of the declaration is to put the function of the name, the function type and the type, number, and order of the formal parameters inform the compilation system so that the function is not included when it is invoked (for example, if the function name is correct, the type and number of the actual participating parameters are the same). --Tan Haoqiang, "C Programming" (fourth edition), Tsinghua University Press, June 2010, p182

This discussion contains a number of conceptual errors that are equally prevalent in many C-language books. In order to illustrate these mistakes, first of all, to review the development of C language and some of the situation.

The first, C-language code can be written like this:

Main ()
{
 printf ("hello,world!\n");
}

Note that this code does not make any description of the identifier printf. This is because the return value of the printf () function is of type int. The C language at the time stated that for a function name without any description, the compiler defaults to the return value of type int, so no description can be made of such a function name. The C language of that period, in many cases int can not write. For example, the main () function returns a value of type int that can not be written.

But it is particularly necessary to note that this "Jingxiang" is outdated, from the C90 standard, this writing has stepped into a gradual abandonment process (although it was not completely abolished at the time). C99 abolishes the implicit function declaration (Remove implicit function declaration), and omitting the int in front of main () is no longer allowed.

In the early days of C, although it was sometimes not necessary to describe the function name, in some cases it was necessary to describe the function name, such as:

Double sqrt ();
int main ()
{
 printf ("%f\n", sqrt (9.));


This is because the function sqrt () returns the type of the value not the int type but the double type, and the compiler needs to know sqrt (9.) When compiling. The type of the expression.

It is not difficult to note that this description of the function name is very simple, and this is the earliest form of a function type description. This description only emphasizes that the function name is a function and its return value type, and it is not detectable if the programmer has a parameter type or a number of error compilers when calling the function because there is no information in "()" in the function type description.

This approach only illustrates the function name and () The result of the operation is the function return value of the data type, can not further check the parameters of the error is this writing deficiencies.

If you do not write the function type description, you can also write the function definition before the function call:

Double square (double x) 
{return
 x * x;
}
int main (void)
{
 printf ("%f\n", Square (3));
 return 0;
}

This indicates that the function definition also has the effect of describing the type of the function name, so in this sense the function definition is also a description of the function type. This approach can check for errors in the number and type of arguments when a function is called.

However, it is not good to explain the function name in this way, as it is necessary to consider which function definition should be written in front and which is written in the following question. If function A calls function B, function B calls function C, function C calls function A, and the order in which the function definition is arranged can be confusing. In addition, this approach is also not conducive to the organization of the Code, in a number of source files composed of the source program, this writing will be more stretched and porous. Therefore, in 1990, the C standard borrowed C + + language to prescribe a new method of describing function name, which is the method of function prototype (functions Propotype) describing function type:

Double square (double); or double square (double x)
int main (void)
{
  printf ("%f\n", Square (3));
  return 0;
}
Double square (double x) 
{return
  x * x;
}

Using this approach, not only can you check the parameter types and the number of errors in the function call, but also solve the source code organization problem, because the programmer no longer have to think about which function to write in front, which is written in the back of this boring problem. This approach comprehensively describes the data type of the function name. Furthermore, the definition of a function that writes the formal parameter and its data type in the form of "()" is also within the scope of the function prototype (functional propotype).

This shows that the old, not the parameters of any description of the function type description, function definition and function of the prototype function type description of the meaning of the function name. In this sense they are all function declarations. In C, the original meaning of the Word Declaration (Declaration) is the meaning and nature of the specified identifier (a declaration specifies the interpretation and attributes of a set of identifier S.), and the definition of an identifier (definition) is also the "declaration" of this marker (declaration). A function definition means including a function body. (a definition of an identifier are a declaration for that identifier that: ... for a function, includes the function body;). A function prototype refers to a function declaration that includes a description parameter type, and it also contains a function definition written in this way.

Now look back at the first sentence in the sample: "The definition of a function and the declaration is not the same thing." Since the function definition itself is a function declaration, how can it be said that they are not the same thing? The logic of this sentence is like saying "man" and "man" are not the same thing. You can say that men and women are not the same thing because they have no intersection. But can not say that men and people are not the same thing, because men are a subset of people, men are a kind of people, how could it be said that men and people is not the same thing?

So what should you call a function declaration without a function body? In the C language, they are called "function type declarations," which are declaration. The main feature of a function type declaration is that the function name is a type of function and its return value, and if the type of the parameter is declared, it is a function-type declaration of the functional prototype.

In the sample "and the function of the declaration is to put the function of the name, the function type and the type, number, and order of the formal parameters inform the compilation system so that when the function is invoked, it does not include the function body, for example, if the function name is correct, and the type and number of the actual participating parameters are the same. The main error is that it confuses the concepts of "function prototype type declaration" and "function declaration", the former concept is only a subset of the latter concept. Function declarations include not only "function type declarations", but also "function definitions" and old-fashioned "function type declarations." Since the function definition itself is a function declaration, it is not possible to determine whether the declaration of a function includes a function body, and the old-fashioned function type declaration (for example, double sqrt ()) also belongs to the function declaration, which does not check for errors in the type and number of arguments. In addition, the function declaration does not check whether the function name is correct or not.

The concept of "function type" in this text also has errors, and the function type describes not only the function return value type, but also the number and type of the parameter (if it is a function prototype), so it cannot be compared with the "type, number" of the formal parameter.

Modern C-language function definitions and function-type declarations are in the style of function prototypes, C99 the old prototype form as obsolete, which means that the prototype form may be banned later.

Main () function
in a variety of C language books, you can see a variety of main () function of the writing, it is very confusing, this is the case? There are two main reasons: one is that with the development and evolution of the C language, the writing of the main () function is changing, as well as the fact that some books are not standardized or misleading.

The original main () function was written very succinctly, at that time the C programmer even a character does not seem to write more. I do not know if the keyboard quality is bad or because the editor is too bad, the time of the C programmers seem to be surprisingly consistent advocating "simplicity"--or even "to Jane."

Main ()
{
 printf ("hello,world\n");
}

This is the oldest of the main () functions, k&r in their classic "The C programming Language" in the first C language source program (1978). This type of writing is the mainstream of that era.

Almost naked, not even #include<stdio.h>? Not in the first edition of "The C programming Language". In the C language of that era, functions that return a value of type int are not declared. However, in the second edition (1988) of the book, the program was changed to:

#include <stdio.h>
Main ()
{
 printf ("hello,world\n");
}

Does a function that returns a value of type int change without declaring a rule? The rules have not changed. What changed is the idea that people are no longer inclined to the "to Jane" of code, and tend to explain the ins and outs of each identifier in code. Starting with C89, it's imperative to have a function declaration before a function call, but it's not enforced, and in C99 it's already mandatory. Since the second edition of the "C Programming Language" was published on the eve of the ANSI C standard promulgation (1989), this change should also be regarded as the bias of ANSI C standard and K&r recognition of the new standard. Although this example does not fully reflect this recognition.

Why does it say that it does not fully reflect this identity? Because the definition of this main () is not written according to the function prototype (functional prototype), the main () function in C90 that takes no arguments should be written like this:

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

But it also stipulates that int can be omitted. C90 () does not write any content as obsolete, although C90 reluctantly tolerated it (the use of function declarators with empty parentheses (not Prototype-format parameter Type declarators) is a obsolescent feature.).

Why should we tolerate it? Because there are a lot of old code still in use.

If you look at the C99 standard, how does this main () write? C99 does not allow an int to be omitted. But the same is not to write any content as outdated, but not completely prohibited, can be seen the stubborn force of habit.

Why does K&r agree with the new standard? Other function definitions and function type declarations in the second edition of the "C programming Language" are basically changed to function prototype style. For example, when explaining the parameters of the main () function, K&r the original main () function

#include <stdio.h>
Main (argc,argv)
int Argc;char *argv[];
{
 *
 ///return 0;

Changed into:

#include <stdio.h>
Main (int argc, char *argv[])
{/* ... */return
 0;
}

The previous writing is almost extinct today, and the latter one () is somewhat strange in today's view, the parameter of Main () is written in function prototype style, but does not write the type of main () return value, giving a bit of Chaine feeling. Although it is not possible to say that it violates C90 (because C90 allows you to not write an int in front of main (), if you write the type int of the return value, it also satisfies the requirements of the modern C99 standard.

Here appears "return 0;" What the hell is going on? This is already commonplace in modern C, and it returns a value to the operating system to indicate in what state the program ended. But in another piece of code, K&r seems to go too far:

#include <stdio.h>
Main (int argc,char *argv[])
{
 int found = 0;
 /*...... Calculate the value of found
 /return found
}

This really some "unconventional", incredibly the results returned to the operating system, quite a breakthrough conventional suspicion.

That first few did "return 0;" What happens to the main () function? According to the C90 standard, it returns an indeterminate value of type int, and if you do not care what the return value is, do not write it. But C99 asked the compiler to help in the compilation of this "return 0", C99 in the need to write int the problem does not indulge the lazy, but here in the lazy way to give accommodation. Q: If you do not care about the return value of the main () function, what is the return value of main () defined as a void type? I've seen it written in many books.

#include <stdio.h>
void Main ()
{
 printf ("This is a C program.\n");
}

This before C99 is a kind of wild way of writing, exactly from where to come out, no one can test. But this is common in mainstream textbooks in previous years. K&r (the inventor of the C language) has not written this, and C90 international standards do not recognize it. Bjarne Stroustrup (founder of the C + + language) in his FAQ on C + +, replied angrily that the word "void Main ()" was not written in C + + or C. In fact, many C language experts think "void main ()" is very evil.

Therefore, before the C99, this is not in line with the standard of the wording. Although the functionality of this code seems to be the output "This is a C program," It is not actually a "C program".

But sometimes it doesn't make a mistake. First, the C language error does not necessarily reflect in the compilation, linking, or running process. You can output a garbage value may be compiled, linked or run, but this does not mean that your code is not wrong, not to say that such a code is correct and meaningful. Second, such a process can cause crashes or warnings in some compilers. This suggests that this formulation is at least not universally applicable. It can be said that, if not the C99 standard, this writing is not lizhuizhide.

Did C99 give this writing a foothold? In a sense, this may be the way to understand. Because K&r did not admit this type of writing, C90 do not recognize this type of writing, C99 although no formal recognition of this writing, but for this writing left a backdoor: "It shall be defined ..." or in some other implementation-defined manner ". This means that if the compiler explicitly claims to allow void main () to be written, then C99 is no longer as simple as C90 to think that the wording violates the C standard.

But anyway, this type of writing is at best a "dialect language" of some compilers, if there is no special reason, such as just working in a particular environment, and only use a specific compiler and do not consider the portability of the program, why not write the general application of the form?

Since a lot of C language experts think "void main ()" is very evil, why does C99 tolerate this kind of writing? It is difficult to determine whether C99 is going to specifically want to "accommodate" this type of writing to the standard list. Because other than void main (), there are other main () functions that are C90 excluded from the standard. And now, these formulations in theory also have the possibility of meeting the C99 standard.

What else is the main () function? Many compilers support the following main () notation:

int main (int argc, char *argv[], char *env[])
{/*/return
 0;
}

There are 3 formal parameters, what is that env for? That parameter enables the program to obtain environment variables.

What do you mean by environment variables? Simply speaking, you can understand some of the data that the operating system records, such as the name of the computer, where the operating system is placed, and so on. This information may be used by the application at run time, which can be obtained by using the env parameter.

What if the compiler does not support the third parameter of main ()? Standard library functions can also achieve the same goal.

#include <stdlib.h>
char *getenv (const char *name);

Can you say void main () and int main (int argc, char *argv[], Char *env[] also conform to the C99 standard? I'm afraid I can't say it yet, but I just can't say that these two kinds of writing must not meet the C99 standard. But these two kinds of writing do not conform to the C90 standard is certain, these two kinds of writing the portability is very poor also certainly. The C99 standard is very vague here, without further defining the meaning of "implementation-defined manner". Unless the compiler declares compliance with the C99 standard and allows the two to be written, it is groundless to assert that the two formulations conform to the C99 standard.

It is said that "C99 suggested that the main function be specified as int", is that right? Obviously not. Because C99 is not absolutely intolerant of main (), the return value is not of type int. The correct argument is that C90 requires that the return value of the main () function must be int. But C90 allows not to write that int, while C99 requires that this "int" be written.

What's the following style?

#include <stdio.h>
int main ()
{
 printf ("This is a C program.\n");
 return 0;
}

This writing is a little nondescript. The type of the return value int wrote, this and C89 advocacy or C99 of the requirements of the same, but () there is nothing to write, and the standard advocated by the style, so neither fish nor fowl. The current standard of writing is still permissible, but it is only a matter of time before the outdated (obsolescent) wording of the standard is tolerated. This is written in the same way as the ancient function parameters:

Main (ARGC,ARGV)
int Argc;char *argv[];
{
 *
 ///return 0;

is a historical waste.

See Before "}" in the function body of main () write a sentence getch (); What's going on here? This is the product of the Times. In the process of turning the PC from the DOS era to the Windows age, the IDE (mainly TC) developed in the DOS ERA was unable to display output after running the program, in order to carefully observe the results of the operation and then return to the IED interface, adding a sentence Artificially lengthen the program's run time (because Getch () waits for the user to enter a character). But this has nothing to do with the structure of main () itself. This statement is not universal, just a stopgap to the outdated IDE. The so-called lack of universal meaning means that first, the real program often does not need this statement, that is, this statement is not related to the function of the program; second, the Getch () function is not a standard function, and only individual compilers support it, and writing this statement on other compilers is likely to be unworkable.

Why not GetChar () This standard library function? The function of GetChar () is somewhat different from the Getch (), which displays the characters typed by the user on a standard output device, which does not display the characters typed by the user, and is closer to the effect of "Press any Key to continue ...".

Some code writes system ("PAUSE") before the end of the main () function, or does it mean that? Yes. This is also a man-made "please press any key to continue ...", regardless of the program functional structure, just for easy observation of output results. But this is better than calling Getch (), because the system () function is a standard library function and is supported by each compiler.

There is a saying, "in the latest C99 standard, only the following two definitions are correct:"

int main (void) {/* */return
 0;
}

And

int main (int argc, char *argv[])
{/*/return
  0;
}

Is that the right idea?

This is clearly not the right statement. But it can be confirmed that the two definitions must be correct. Not only is it right in C99, it is also true for C89.

There is also a way of writing:

int main (void)
{return
 exit_success;
}

What's with the exit_success?

Return exit_success is a refinement of the equivalent of return 0; Exit_success is the symbolic constant defined in stdlib.h, which returns the program exit after the program task completes. Another symbolic constant exit_failure defined in stdlib.h is typically used to exit a program that cannot complete a task.

Is it too dazzling to remember so much? Obviously not necessary. A lot of things are rubbish left over by historical reasons.

If you learn C, which one should you remember or use? is clearly:

int main (void) {/* */return
  0;
}

And

int main (int argc, char *argv[])
{/*/return
  0;
}

First, they are universally applicable, and there is no question of portability;

Second, for the moment, there is no obsolete or imminent ingredient. Of course, if you like elegance, do not write return 0, and write exit_success can also. Incidentally, some learners cannot remember the names of two formal parameters with the parameter main () function. In fact, the names of the two formal parameters can also be taken by themselves, not necessarily with the two names, as long as the type can be remembered. The type of the second parameter can also be char * *, which is equivalent to the original.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.