当前位置:网站首页>Fundamentals of C language 9: Functions
Fundamentals of C language 9: Functions
2022-07-06 07:20:00 【jllws1】
Tips1:
keyword :return
Operator :*( One yuan )、&( One yuan )
Functions and how they are defined
How to use parameters and return values
How to use pointer variables as function parameters
Function type
ANSI C Prototype
recursive
How to organize the program ?C The design idea of is , Use functions as building blocks . We've already used it C Functions of the standard library , Such as printf()、scanf()、getchar()、putchar() and strlen(). Now I want to enter Learn how to create your own functions in one step . The relevant processes have been roughly introduced in the previous chapters , This chapter will Consolidate the knowledge learned before and further expand .
9.1 Review functions
First , What is a function ? function (function) A unit of independent program code that performs a specific task . Defines the syntax and how functions are used . although C Functions and other languages in The function in 、 Subroutines 、 The process works the same , But the details are slightly different . Some functions perform certain functions Some action , Such as printf() Print the data to the screen ; Some functions find a value for the program to use , Such as strlen() Returns the length of the specified string to the program . generally speaking , Functions can have both functions to The last two functions .
Why use functions ? First , Using functions can save you the pain of writing duplicate code . Such as If the program needs to complete a task many times , Then just write an appropriate function , You can When using this function , Or use this function in different programs , Just like in many programs putchar() equally . secondly , Even if the program only completes a task once , It's also worth using functions . Because functions make programs more modular , Thus, the readability of the program code is improved , More convenient for later modification 、 perfect . for example , Suppose you want to write a program to complete the following tasks :
Read in a series of numbers ;
Classify these numbers ;
Find the average of these numbers ;
Print a histogram .
You can use the following program :
#include <stdio.h>
#define SIZE 50
int main(void)
{
float list[SIZE];
readlist(list, SIZE);
sort(list, SIZE);
average(list, SIZE);
bargraph(list, SIZE);
return 0;
}
// According to the proposed task, the program framework can be pushed out , Reading input characters in the previous chapter is a typical example ( Comparison refinement )
Of course , And write 4 A function readlist()、sort()、average() and bargraph() Implementation details . Descriptive function names can clearly express the purpose and organizational structure of the function . then , Set separately Count and test each function , Until the function can complete the task normally . If these functions are general enough , It can also be used in other programs .
Many programmers like to think of functions as based on incoming information ( Input ) And its generated value or response action ( Output ) To define the “ Black box ”. If you don't write your own functions , There is no need to care about the internal behavior of the black box . for example , Use printf() when , Just know to pass in the format string to this function Or some parameters and printf() Generated output , There is no need to know printf() Internal code of . Looking at functions in this way helps to focus on the overall design of the program , Not the implementation details of the function . therefore , Before you start writing code , Think carefully about what the function should do , And the relationship between function and program as a whole .
How to understand functions ? First of all, you need to know how to define functions correctly 、 How to call functions and how Establish communication between functions . Let's start with a simple program example , Help readers sort out these inner Rong , Then I'll explain it in detail .
9.1.1 Create and use simple functions
Our first 1 The first goal is to create one that prints on one line 40 A function of an asterisk , And use this function in a program to print the header . Such as the program list 9.1 Shown , The procedure consists of main() and starbar() form .
Program listing 9.1 lethead1.c Program
/* lethead1.c */
#include <stdio.h>
#define NAME "GIGATHINK, INC."
#define ADDRESS "101 Megabuck Plaza"
#define PLACE "Megapolis, CA 94904"
#define WIDTH 40
void starbar(void); /* The function prototype */
int main(void)
{
starbar();
printf("%s\n", NAME);
printf("%s\n", ADDRESS);
printf("%s\n", PLACE);
starbar(); /* Using functions */
return 0;
}
void starbar(void) /* Defined function */
{
int count;
for (count = 1; count <= WIDTH; count++)
putchar('*');
putchar('\n');
}
The output of this program is as follows :
****************************************
GIGATHINK, INC.
101 Megabuck Plaza
Megapolis, CA 94904
****************************************
9.1.2 analysis program
The program should pay attention to the following points .
The program is in 3 Used at starbar identifier : The function prototype (function prototype) Tell the compiler functions starbar() The type of ; Function call (function call) Indicates that the function is executed here ; Function definition (function definition) It clearly specifies what the function should do .
Functions are the same as variables , There are many types of . Any program must declare the type of the function before using it . therefore , stay main() The following... Appears in front of the function definition ANSI C Style function prototype :
void starbar(void)
// Insist on using ANSI C Style function prototype is very good , The return value and parameter type must be specified , If not, use it void Instead of
Be careful , Some older compilers even void Can't even recognize . If you use this compilation device , You have to declare a function that does not return a value as int type . Of course , It's better to change a new editor Translator .
generally speaking , The function prototype specifies the return value type of the function and the parameter type accepted by the function . This information is called the signature of the function (signature). about starbar() Function , The signature is that the function has no return value , No parameters .
The program put starbar() Prototype placed main() In front of . Of course , It can also be placed in main() Inside At the declared variable of . It can be placed in any position .
stay main() in , When the following statement is executed, the starbar() function :
starbar();
This is the call void A form of type function .
When the computer executes to starbar(); When the sentence is , You will find the definition of the function and execute its contents . After execution starbar() After the code in , The computer returns the main calling function (calling function) Move on to the next line ( In this case , The main function is main()), See the picture 9.1( To be more exact , The compiler the C The program is translated into machine language code that performs the above operations ).
In the program strarbar() and main() Is defined in the same form . First, the function header includes the function type 、 Function name and parentheses , Then there is the left curly bracket 、 Variable declarations 、 Function expression statement , End with a right curly bracket ( See the picture 9.2). Be careful , In the function header starbar() There's no semicolon at the back , Tell the compiler that this is the definition starbar(), Instead of calling functions or declaring function prototypes .
The program put starbar() and main() Put it in a file . Of course , You can also put them in two files . Putting functions in a single file is easier to compile , It is convenient to use the same function in different programs by using multiple files . If you put the function in a separate file , To put #define and #include Instructions are also placed in the file . We will discuss the use of multiple files later . Now? , First put all the functions in a file .main() The right curly bracket of tells the compiler where the function ends , hinder starbar() The function header tells the compiler starbar() It's a function .
starbar() Variables in functions count It's a local variable (local variable), It means that this variable only belongs to starbar() function . Other places in the program can include main() Use in count, This does not cause name conflicts , They are different variables of the same name .
// Duplicate names of local variables do not cause conflicts , Local variables only work when calling functions
If you put starbar() As a black box , Then its behavior is to print a line of asterisks . no need Provide any input to this function , Because no other information is required to call it . and , It has no return value , So don't give main() Provide ( Or return ) Any information . In short ,starbar() There is no need to communicate with the calling function .
Next, an example of communication between functions is introduced .
9.1.3 Function parameter
In the program list 9.1 In the output of , If the text can be centered , The letterhead will be more beautiful . You can pass By printing a certain number of spaces before printing text , This is similar to printing a certain number of asterisks (starbar() function ) similar , But now we need to print a certain number of spaces . Although these are two tasks , But the task is very similar , Instead of writing a function for each of them , It's better to write a More general functions , It can be used in two situations . We design a new function show_n_char()( Display a character n Time ). The only thing to change is to use built-in values to display characters and the number of repetitions ,show_n_char() You will use function parameters to pass these values .
Let's make a concrete analysis . Suppose the available space is 40 Characters wide . call show_n_char('*', 40) It should print exactly one line 40 asterisk , It's like starbar() What I did before . The first 2 That's ok GIGATHINK, INT. How to deal with the blank space of ?GIGATHINK, INT. yes 15 Characters wide , therefore The first 1 One version , There is 25 A space . To center the text , The left side of the text should have 12 A space , There is... On the right 13 A space . therefore , You can call show_n_char('*', 12).
show_n_char() And starbar() Very similar , however show_n_char() With parameters . functionally , The former does not add line breaks , The latter will , because show_n_char() Put spaces and text Print in one line . Program listing 9.2 It's a modified version . To emphasize the working principle of parameters , The program uses different parameter forms .
Program listing 9.2 lethead2.c Program
/* lethead2.c */
#include <stdio.h>
#include <string.h> /* by strlen() Provide prototypes */
#define NAME "GIGATHINK, INC."
#define ADDRESS "101 Megabuck Plaza"
#define PLACE "Megapolis, CA 94904"
#define WIDTH 40
#define SPACE ' '
void show_n_char(char ch, int num);
int main(void)
{
int spaces;
show_n_char('*', WIDTH); /* Use symbolic constants as parameters */
putchar('\n');
show_n_char(SPACE, 12); /* Use symbolic constants as parameters */
printf("%s\n", NAME);
spaces = (WIDTH - strlen(ADDRESS)) / 2; /* Calculate how many spaces to skip */
show_n_char(SPACE, spaces); /* Take a variable as a parameter */
printf("%s\n", ADDRESS);
show_n_char(SPACE, (WIDTH - strlen(PLACE)) / 2);
printf("%s\n", PLACE); /* Take an expression as a parameter */
show_n_char('*', WIDTH);
putchar('\n');
return 0;
}
/* show_n_char() Definition of function */
void show_n_char(char ch, int num)
{
int count;
for (count = 1; count <= num; count++)
putchar(ch);
}
The result of this function is as follows :
****************************************
GIGATHINK, INC.
101 Megabuck Plaza
Megapolis, CA 94904
****************************************
Now let's review how to write a function with parameters , Then introduce the usage of this function .
9.1.4 Define functions with formal parameters
The function is defined from ANSI C Style function header starts :
void show_n_char(char ch, int num)
This line tells the compiler show_n_char() Use two parameters ch and num,ch yes char type , num yes int type . These two variables are called formal parameters (formal argument, But the latest bid It is recommended to use formal parameter), It's called formal parameter for short . Just like variables defined in functions , form Parameters are also local variables , Private to this function . This means that using variables with the same name in other functions is not Will cause name conflicts . Every time you call a function , Will assign values to these variables .
Be careful ,ANSI C It is required to declare its type before each variable . in other words , You cannot use a variable list of the same type as a normal variable declaration :
void dibs(int x, y, z) /* Invalid function header */
void dubs(int x, int y, int z) /* Valid function headers */
ANSI C Also accept ANSI C The previous form , But regard it as an abandoned form :
void show_n_char(ch, num)
char ch;
int num;
here , There is only a list of parameter names in parentheses , The type of the parameter is declared later . Be careful , Ordinary local variables are declared after the left curly bracket , The above variable sounds before the left curly bracket of the function bright . If the variables are of the same type , This form can be used to separate the list of variable names with commas , As shown below :
void dibs(x, y, z)
int x, y, z; /* It works */
Current standards are being phased out ANSI The previous form . Readers should know something about this , In order to understand the program written before , But when writing your own program, you should use the current standard form (C99 and C11 The standard continues to warn that these outdated uses are about to be eliminated ).
although show_n_char() from main() Value , But it doesn't return a value . therefore , show_n_char() The type is void. below , Let's learn how to use functions .
9.1.5 Declare the prototype of a function with formal parameters
Before using functions , Use ANSI C Formal declaration function prototype :
void show_n_char(char ch, int num);
When a function accepts arguments , The function prototype uses a comma separated list to indicate the number and type of arguments . According to personal preference , You can also omit the variable name :
void show_n_char(char, int);
Using variable names in the prototype does not actually create variables ,char Represents only one char Variable of type , And so on . Once again, I want to remind readers to pay attention to ,ANSI C Also accept the past declarative function form , That is, there is no parameter list in parentheses :
void show_n_char();
This form will eventually be removed from the standard . Even if it is not eliminated , Now the design of function prototype has more advantages ( I'll introduce you later ). Knowing this form of writing is to understand the code written before in the future .
explain : In the function prototype , Parameter type must have , The parameter name has no actual meaning , But from the perspective of standardization and readability, it is suggested to give a
9.1.6 Call a function with actual parameters
In a function call , The actual parameter (actual argument, It's called argument for short ) Provides ch and num Value . Consider the program list 9.2 pass the civil examinations 1 Secondary call show_n_char():
show_n_char(SPACE, 12);
The actual parameters are space characters and 12. These two values are assigned to show_n_char() Corresponding form in Parameters : Variable ch and num. In short , The formal parameter is the called function (called function) in The variable of , The actual parameter is the main function (calling function) The specific value assigned to the called function . As shown in the example above , The actual parameter can be a constant 、 Variable , Or even more complex expressions . No matter what The actual parameters must be evaluated in whatever form , Then the value is copied to the corresponding formal parameter of the called function Count . Take the program list 9.2 The last call in show_n_char() For example :
show_n_char(SPACE, (WIDTH - strlen(PLACE)) / 2);
This function is composed of 2 The actual argument is a very long expression , Evaluate the expression to 10. then ,10 Assigned to variable num. The called function does not know or care that the incoming value comes from Constant 、 Variable or general expression . Again , The actual parameter is a specific value , This value is assigned Give variables as formal parameters ( See the picture 9.3). Because the value used by the called function is copied from the main calling function , therefore No matter what the called function does to the copied data , Will not affect the original data in the main function .
Be careful : Actual parameters and formal parameters --- The actual argument is the expression that appears in parentheses in the function call . Formal parameters are variables declared in the function header of a function definition . When you call a function , Create variables declared as formal parameters and initialize Is the evaluation result of the actual parameter . Program listing 9.2 in ,'*' and WIDTH Is the first 1 Secondary call show_n_char() Actual parameters when , and SPACE and 11 It's No 2 Secondary call show_n_char() Actual parameters when . In the definition of a function ,ch and num Are the formal parameters of the function .
explain : There's a very important concept , Formal parameters can only be passed in by arguments , Formal parameters cannot return arguments
9.1.7 Black box perspective
From the perspective of black box show_n_char(), The characters to be displayed and the number of times to be displayed are input . The result of execution is to print a specified number of characters . Input is passed to the function in the form of parameters . this Some information clearly shows how to main() Use this function in . and , This can also be used as a design specification for writing this function .
The core part of the black box method is :ch、num and count All are show_n_char() Private local variables . If in main() Variables with the same name are used in , Then they are independent of each other , They don't influence each other . in other words , If main() There is one count Variable , Then changing its value will not change show_n_char() Medium count, vice versa . What happens in the black box is invisible to the main function .
9.1.8 Use return Return value from function
Previously, I introduced how to transfer information from the calling function to the called function . In turn, , The return value of the function can pass information from the called function back to the calling function . For further explanation , We will create a function that returns the smaller of the two parameters . Because functions are designed to handle int Type value , So it was named imin(). in addition , Also create a simple main(), Used for inspection imin() Whether it works properly . This kind of program designed to test functions is sometimes called a driver (driver), The driver calls a function . If the function successfully passes the test , It can be installed in a more important program . Program listing 9.3 Demonstrates the driver and the function that returns the minimum value .
Program listing 9.3 lesser.c Program
/* lesser.c -- Find the smaller of the two integers */
#include <stdio.h>
int imin(int, int);
int main(void)
{
int evil1, evil2;
printf("Enter a pair of integers (q to quit):\n");
while (scanf("%d %d", &evil1, &evil2) == 2)
{
printf("The lesser of %d and %d is %d.\n",
evil1, evil2, imin(evil1, evil2));
printf("Enter a pair of integers (q to quit):\n");
}
printf("Bye.\n");
return 0;
}
int imin(int n, int m)
{
int min;
if (n < m)
min = n;
else
min = m;
return min;
}
recall ,scanf() Returns the number of successfully read data , So if the input is not two integers, it will cause the loop to terminate . Here is a running example :
Enter a pair of integers (q to quit):
509 333
The lesser of 509 and 333 is 333.
Enter a pair of integers (q to quit):
-9393 6
The lesser of -9393 and 6 is -9393.
Enter a pair of integers (q to quit):
q
Bye.
keyword return The value of the following expression is the return value of the function . In this case , The value returned by this function is a variable min Value . because min yes int Variable of type , therefore imin() Class of function Type is also int.
Variable min Belong to imin() Function private , however return The sentence put min The value of returned the calling function . The following sentence is used to put min The value is assigned to lesser:
lesser = imin(n,m);
Can it be written like this :
imin(n,m);
lesser = min; You can't . Because the main function doesn't even know min The existence of . remember ,imin() The variable in is imin() Local variables of . Function call imin(evil1, evil2) Just copy the values of the two variables .
The return value can not only be assigned to variables , It can also be used as part of an expression . for example , It can be like this :
answer = 2 * imin(z, zstar) + 25;
printf("%d\n", imin(-32 + answer, LIMIT));
// More commonly used usage , Treat the expression of the return value as a subexpression of another expression .
The return value is not necessarily the value of the variable , It can also be the value of any expression . for example , You can simplify the program example with the following code :
/* Function that returns the minimum value , The first 2 A version */
imin(int n,int m)
{
return (n < m) ? n : m;
}
The value of the conditional expression is n and m The smaller of them , This value is to be returned to the calling function . Although it is not required to enclose the return value with parentheses , But if you want to make the program more clear or unified style , You can put the return value in parentheses .
If the type of the return value of the function does not match the type declared by the function What will happen ?
int what_if(int n)
{
double z = 100.0 / (double) n;
return z; // What's going to happen ?
}
The actual return value is equivalent to the value obtained by assigning the return value specified in the function to a variable of the same type as the function . So in this case , Is equivalent to z The value is assigned to int Variable of type , Then return int The value of the type variable . for example , Suppose there are the following function calls :
result = what_if(64);
Although in what_if() Function to z The value of is 1.5625, however return Statement returns true int Type value 1.
// amount to int a=10.00 When the declared type is different from the actual value , Subject to type .
Use return Another function of the statement is , Terminate the function and return control to the next statement of the calling function . therefore , Can be written like this imin():
/* Function that returns the minimum value , The first 3 A version */
imin(int n,int m)
{
if (n < m)
return n;
else
return m;
}
many C Programmers think that it is only used once at the end of a function return The sentence is better , Because of this People who make it easier to browse programs understand the control flow of functions . however , Use multiple return There is nothing wrong with the statement . in any case , For users , this 3 The functions of the two versions are the same , Because all inputs and outputs are exactly the same , The difference is the implementation details inside the function . The following version is also ok :
/* Function that returns the minimum value , The first 4 A version */
imin(int n, int m)
{
if (n < m)
return n;
else
return m;
printf("Professor Fleppard is like totally a fopdoodle.\n");
}
return Sentences lead to printf() Statements will never be executed . If Fleppard The professor is in his Use this version of the function in the program , You may never know what the student who wrote this function thinks of him .
in addition , It can also be used in this way
return:
return; This statement will cause the function to terminate , And return the control to the calling function . because return Back There's no expression , So there's no return value , Only in void This form is only used in functions .
explain :return The other function of terminates the function and returns the control to the main function .
9.1.9 Function type
When declaring a function, you must declare the type of the function . Function type with return value should be the same as its return value type , Functions that do not return a value should be declared as void type . If there is no class that declares a function type , The old version of C The compiler will assume that the type of the function is int. This practice stems from C Early stage , that Most of the functions in time are int type . However ,C99 The standard no longer supports int This type of function Suppose you set .
The type declaration is part of the function definition . Remember , Function type refers to the type of return value , Not the type of function parameter . for example , The following function header defines one with two int Type reference A function of numbers , But the return value is double type .
double klink(int a, int b) // Standard writing
Use functions correctly , The procedure is in 1 You must know the type of the function before using it again . One way is , Put the complete function definition on the 1 In front of the second call function . However , This method increases the difficulty of reading the program . and , The function to be used may be in C Library or other files . therefore , The usual practice is to declare functions in advance , Tell the compiler about the function . for example , Program detailed list 9.3 Medium main() The function contains the following lines of code :
#include <stdio.h>
int imin(int, int);
int main(void)
{
int evil1, evil2, lesser;
The first 2 Line code description imin Is a function name , There are two int Type parameters , And return to int class The value of the type . Now? , The compiler calls imin() Function, you know how to deal with .
In the program list 9.3 in , We put the pre declaration of the function outside the calling function . Of course , It can also be placed in the main function . for example , rewrite lesser.c( Program listing 9.3) The beginning of :
#include <stdio.h>
int main(void)
{
int imin(int, int); /* Statement imin() Prototypes of functions */
int evil1, evil2, lesser;
Note in both cases , Function prototypes are declared before using functions .
ANSI C Standard library , Functions are divided into series , Each series has its own header Pieces of . These header files contain, among other things , It also includes the declarations of all functions in this series . for example , stdio.h The header file contains the standard I/O Library function ( Such as ,printf() and scanf()) Statement of .math.h The header file contains declarations of various mathematical functions . for example , The following statement :
double sqrt(double);
Tell the compiler sqrt() The function has one double Type parameters , And return double Type value . Don't confuse the declaration and definition of functions . Function declarations tell the compiler the type of the function , The function The definition provides the actual code . Include... In the program math.h The header file tells the compiler :sqrt() return return double type , however sqrt() The code of the function is in another library function file .
explain : The order in which functions appear is generally : Function declaration ( The function prototype ), Function call , Function definition
9.2 ANSI C The function prototype
stay ANSI C Before standard , The scheme of declaring functions is flawed , Because you only need to declare the type of the function , Don't declare any parameters . Now let's see what problems can be caused by using old-fashioned function declarations .
Here is ANSI Previous function declaration , Tell the compiler imin() return int Type value :
int imin();
However , The above function declaration does not give imin() The number and type of parameters of the function . therefore , Such as Result call imin() The number of parameters used in is incorrect or the type does not match , The compiler won't even notice .
9.2.1 The problem
Let's see with imax() Some examples of functions , The function and imin() Functions are closely related . Program listing 9.4 Demonstrated a program , Declared in the way of declaring functions in the past imax() function , Then use the function incorrectly .
Program listing 9.4 misuse.c Program
/* misuse.c -- Using functions incorrectly */
#include <stdio.h>
int imax(); /* Old style function declarations */
int main(void)
{
printf("The maximum of %d and %d is %d.\n",3, 5, imax(3));
printf("The maximum of %d and %d is %d.\n",3, 5,
imax(3.0, 5.0));
return 0;
}
int imax(n, m)
int n, m;
{
return (n > m ? n : m);
}
The first 1 Secondary call printf() When omitted imax() A parameter of , The first 2 Secondary call printf() Use two Floating point parameters instead of integer parameters . Despite some problems , But the program can compile and run .
Here's how to use Xcode 4.6 Example of output from the run :
The maximum of 3 and 5 is 1606416656.
The maximum of 3 and 5 is 3886.
Use gcc Run the program , The output value is 1359379472 and 1359377160. These two editors The translator is working normally , The reason why the wrong result is output , Because the programs they run do not use function prototypes .
What's wrong with it ? Because different systems have different internal mechanisms , So there are problems The specific situation is also different . The following describes the use of PC and VAX The situation of . The calling function stores its parameters in what is called stack (stack) A temporary storage area for , The called function reads these parameters from the stack . For this example , These two processes are not coordinated . The calling function determines the type of transfer according to the actual parameters in the function call , The called function reads the value according to its formal parameters . therefore , Function call imax(3) Put an integer on the stack . When imax() When the function starts executing , It reads two integers from the stack . In fact, only one integer to be read is stored in the stack , So read the number 2 The first value is when Other values that happen to be on the stack .
The first 2 Second use imax() Function time , It conveys float Type value . This time put two double The value of type is placed on the stack ( recall , When float When the type is passed as a parameter, it will be upgraded to double type ). In our system , Two double The value of type is two 64 The value of a , therefore 128 Bits of data are placed on the stack . When imax() Read two from the stack int Value of type , it Before reading from the stack 64 position . In our system , Every int Type of variable occupancy 32 position . These numbers It corresponds to two integers , The bigger one is 3886.
explain : The mismatching of stack parameters and stack parameters may cause the program to fail , So we need to adhere to the function prototype
9.2.2 ANSI Solutions for
For the problem of parameter mismatch ,ANSI C The standard requires that the type of variable be declared when the function is declared , That is, use the function prototype (function prototype) To declare the return type of the function 、 The number of parameters and the type of each parameter . Unspecified imax() There are two functions int Parameters of type , You can use the following two function prototypes to declare :
int imax(int, int);
int imax(int a, int b); // Function prototype standard writing
The first 1 Two forms use a comma separated list of types , The first 2 Forms add variations after types Quantity name . Be careful , The variable name here is a pseudonym , It does not have to be consistent with the formal parameter name of the function definition . // For all that , It's better to be consistent
I have this information , The compiler can check whether the function call matches the function prototype . Parametric Is the quantity correct? ? Whether the types of parameters match ? With imax() For example , If both parameters are numbers word , But the types don't match , The compiler will convert the type of the actual parameter to the type of the formal parameter . for example ,imax(3.0, 5.0) Will be converted into imax(3, 5). We replace the program manifest with a function prototype 9.4 Function declaration in , Such as Program listing 9.5 Shown .
Program listing 9.5 proto.c Program
/* proto.c -- Using function prototypes */
#include <stdio.h>
int imax(int, int); /* The function prototype */
int main(void)
{
printf("The maximum of %d and %d is %d.\n",
3, 5, imax(3));
printf("The maximum of %d and %d is %d.\n",
3, 5, imax(3.0, 5.0));
return 0;
}
int imax(int n, int m)
{
return (n > m ? n : m);
}
Compiler manifest 9.5 when , Our compiler gives the called imax() Error of too few function parameters Error message .
What happens if there is a type mismatch ? To explore this problem , We use it imax(3, 5) Replace imax(3), Then compile the program again . This time the compiler did not give any error messages , The output of the program is as follows :
The maximum of 3 and 5 is 5.
The maximum of 3 and 5 is 5.
As mentioned above , The first 2 In the call 3.0 and 5.0 Converted to 3 and 5, So that the function can correctly Process input .
Although there is no error message , But our compiler still gives a warning :double convert to int May cause data loss . for example , The following function call :
imax(3.9, 5.4)
amount to :
imax(3, 5)
The difference between an error and a warning is : An error prevented compilation , The warning still allows compilation . some The compiler does not notify the user of similar type conversions , because C This is not required in the standard . however , Many compilers allow users to choose the warning level to control the level of detail when the compiler describes the warning .
9.2.3 No parameters and unspecified parameters
Suppose you have the following function prototype :
void print_name();
One support ANSI C The compiler of assumes that users do not declare functions with function prototypes , It will not check parameters . To show that the function does not have parameters , Should be used in parentheses void Turn off Key word :
void print_name(void);
Support ANSI C The compiler of is interpreted as print_name() No parameters are accepted . Then when calling this function , The compiler checks to ensure that no parameters are used .
Some functions accept ( Such as ,printf() and scanf()) Many parameters . For example, for printf(), The first 1 589 The first parameter is a string , But the type and number of other parameters are not fixed . In this case , ANSI C Partial prototypes are allowed . for example , about printf() You can use the following prototype :
int printf(const char *, ...);
This prototype shows that , The first 1 A parameter is a string ( The first 11 This chapter will introduce in detail ), There may be other unspecified parameters . C Kuo passed through stdarg.h The header file provides a way to define this class ( The number of formal parameters is not fixed ) Standard method of function . The first 16 Relevant contents are introduced in detail in Chapter .
9.2.4 Advantages of function prototypes
The function prototype is C Language is a powerful tool , It allows the compiler to capture when using functions Many mistakes or omissions that may occur . If the compiler does not find these problems , It's hard to detect Come on . Whether function prototypes must be used ? not always . You can also use old-fashioned function declarations ( I.e. no Declare any formal parameter with ), But doing so will do more harm than good .
There is a way to omit function prototypes while retaining the advantages of function prototypes . First of all, understand , And So use function prototypes , Is to make the compiler in the 1 You know how to Use it . therefore , Put the entire function definition on the 1 Before calling this function for the first time , It has the same effect fruit . here , Function definition is also equivalent to function prototype . For smaller functions , This usage is very common :
// The following line of code is the function definition , It is also a function prototype
int imax(int a, int b) { return a > b ? a : b; }
int main()
{
int x, z;
...
z = imax(x, 50);
...
}
// It is more common to define some simple functions with macros later ( If the number of calls is not many , If it doesn't occupy a lot of space )
9.3 recursive ( A little )
C Allow a function to call itself , This calling process is called recursion (recursion). Recursion has Time is elusive , Sometimes it's very convenient and practical . Ending recursion is the difficulty of using recursion , Because if you deliver There is no conditional test part of the return code that terminates recursion , A call to its own function will be infinitely recursive . Where you can use loops, you can usually use recursion . Sometimes it's better to solve problems with loops good , But sometimes recursion is better . Recursive schemes are simpler , But the efficiency is not as high as that of circulation .
9.4 A program that compiles multiple source code files
The easiest way to use multiple functions is to put them all in the same file , Then like compiling Just compile the file like a function file . Other methods vary depending on the operating system , below Examples will be given .
9.4.1 UNIX
Assume that UNIX The system has UNIX C compiler cc( The original cc It has been discontinued , however many UNIX The system gives cc Command is aliased as another compiler command , Typically gcc or clang). hypothesis file1.c and file2.c There are two contents C Function file , The following command will compile Two files and generate a file named a.out The executable of :
cc file1.c file2.c
in addition , Also generated are two named file1.o and file2.o The target file of . If later changed file1.c, and file2.c unchanged , You can compile the 1 File , And with the 2 Merge the object code of files :
cc file1.c file2.o
UNIX Systematic make Command can automatically manage multi file programs , But this is beyond the discussion of this book On scope . Be careful ,OS X Of Terminal Tools can open UNIX Command line environment , But you must first download the command-line compiler (GCC and Clang).
9.4.2 Linux
Assume Linux The system is installed GNU C compiler GCC. hypothesis file1.c and file2.c It's two inside contain C Function file , The following command will compile two files and generate a file named a.out Executable document of Pieces of : gcc file1.c file2.c
in addition , Also generated are two named file1.o and file2.o The target file of . If later changed file1.c, and file2.c unchanged , You can compile the 1 File , And with the 2 File Object code merge :
gcc file1.c file2.o
9.4.3 DOS Command line compiler
most DOS How the command line compiler works and UNIX Of cc Command similar , It's just Just use different names . One of the differences is , The extension of the object file is .obj, Instead of yes .o. Some compilers do not generate object code files , But assembly language or other special code In between .
9.4.4 Windows And Apple's IDE compiler
Windows and Macintosh The compiler in the integrated development environment used by the system is project oriented Of . project (project) Describes the resources used by a particular program . Resources include source code files . such IDE The compiler in creates a project to run a single file program . For multi file programs , To make Use the corresponding menu command , Add source code files to a project . Make sure that all source code documents Items are listed in the project list . many IDE There is no need to list header files in the project list ( That is to expand be known as .h The file of ), Because the project only manages the source code files used , In the source code file #include The instruction manages the header file used in this file . however ,Xcode To add a header file to the project .
explain : Introduction to compiler , Now we basically use the existing compiler with interface , Don't pay too much attention to those dos command .
9.4.5 Use header file
If you put main() Put it in the 1 In a file , Put the function definition on the 2 In a file , So the first 1 Three files still use function prototypes . Put the function prototype in the header file , You don't have to write out the prototype of the function every time you use the function file .C This is what the standard library does , for example , hold I/O Letter Put the prototype on stdio.h in , Put the mathematical function prototype in math.h in . You can also use it yourself Semantic function file .
in addition , Often used in the program C The preprocessor defines symbolic constants . This definition only stores those contain #define Command file . If you put a function of the program into a separate file , You can also use #define Instructions to access each file . The most direct way is to input instructions again in each file , But this method is time-consuming and error prone . in addition , There will also be maintenance problems : If it changes #define Defined value , It must be modified in every file . Better yet , hold #define Put the instruction into the header file , Then use... In each source file #include The directive contains this file that will do .
All in all , Putting function prototypes and defined character constants in header files is a good programming habit . Let's consider an example : Suppose you want to manage 4 Room service in this hotel , The room rate of each hotel is different , But the room rates of all rooms in each hotel are the same . For customers who reserve accommodation for more than one day , The first 2 The room rate for day is 1 Days of 95%, The first 3 The first day is 2 Days of 95%, And so on ( Don't consider this kind of The economic benefits of the strategy ). Design a program that allows users to specify hotels and stay days , Then calculate and display the total cost . meanwhile , The program should realize a menu , Allow users to input data repeatedly , Unless the user chooses to exit .
Program listing 9.9、 Program listing 9.10 And program list 9.11 Demonstrates how to write such a program . The first 1 Program listings contain main() function , Provide the organizational structure of the whole program . The first 2 Program listings contain supported functions , We assume that these functions are in separate files . Last , The procedure is clear single 9.11 Lists a header file , It contains all the custom symbolic constants and function prototypes used in the source files of the program . As mentioned earlier , stay UNIX and DOS Environment ,#include "hotels.h" The double quotation marks in the directive indicate that the included files are located in the current directory ( It is usually the target that contains the source code record ). If you use IDE, You need to know how to merge header files into one project .
Program listing 9.9 usehotel.c Control module
/* usehotel.c -- Room rate procedure */
/* And procedure list 9.10 Compile together */
#include <stdio.h>
#include "hotel.h" /* Define symbolic constants , Declare functions */
int main(void)
{
int nights;
double hotel_rate;
int code;
while ((code = menu()) != QUIT)
{
switch (code)
{
case 1: hotel_rate = HOTEL1;
break;
case 2: hotel_rate = HOTEL2;
break;
case 3: hotel_rate = HOTEL3;
break;
case 4: hotel_rate = HOTEL4;
break;
default: hotel_rate = 0.0;
printf("Oops!\n");
break;
}
nights = getnights();
showprice(hotel_rate, nights);
}
printf("Thank you and goodbye.\n");
return 0;
}
Program listing 9.10 hotel.c Function support module
/* hotel.c -- Hotel management function */
#include <stdio.h>
#include "hotel.h"
int menu(void) // Get a number in a range (1~5)-- Menu selection
{
int code, status;
printf("\n%s%s\n", STARS, STARS);
printf("Enter the number of the desired hotel:\n");
printf("1) Fairfield Arms 2) Hotel Olympic\n");
printf("3) Chertworthy Plaza 4) The Stockton\n");
printf("5) quit\n");
printf("%s%s\n", STARS, STARS);
while ((status = scanf("%d", &code)) != 1 ||
(code < 1 || code > 5))
{
if (status != 1)
scanf("%*s"); // Handle non integer input
printf("Enter an integer from 1 to 5, please.\n");
}
return code;
}
int getnights(void) // Get an integer -- Check in days
{
int nights;
printf("How many nights are needed? ");
while (scanf("%d", &nights) != 1)
{
scanf("%*s"); // Handle non integer input
printf("Please enter an integer, such as 2.\n");
}
return nights;
}
void showprice(double rate, int nights) // Get the price
{
int n;
double total = 0.0;
double factor = 1.0;
for (n = 1; n <= nights; n++, factor *= DISCOUNT)
total += rate * factor;
printf("The total cost will be $%0.2f.\n", total);
}
Program listing 9.11 hotel.h The header file
/* hotel.h -- Symbolic constants and hotel.c Prototypes of all functions in */
#define QUIT 5
#define HOTEL1 180.00
#define HOTEL2 225.00
#define HOTEL3 255.00
#define HOTEL4 355.00
#define DISCOUNT 0.95
#define STARS "**********************************"
// Display the selection list
int menu(void);
// Return booking days
int getnights(void);
// According to the rate 、 Check in days calculation fee
// And display the results
void showprice(double rate, int nights);
Run the example ( A little )
By the way , Several parts of the program are cleverly written .
In especial ,menu() and getnights() Function passed the test scanf() To skip non numeric data , And call scanf("%*s") Skip to the next blank character .
// Meaning and while(getchar()!='\n') identical
Be careful ,menu() How to check non numeric input and out of range data in function :
while ((status = scanf("%d", &code)) != 1 ||(code < 1 || code > 5))
The above code snippet makes use of C Two rules of language : Evaluate logical expressions from left to right ; One Once the evaluation result is false , Stop evaluation immediately . In this case , Only in scanf() Successfully read a whole After that , Will check code Value .
// Enter a range value ( A value and within a range ) Typical methods of .
The previous program builds two functions , Get an integer , A function limits its scope , In this way, two functions can be combined into one function
When using different functions to handle different tasks, you should check the validity of the data . Of course , First written menu() or getnights() This function can not be added for the time being , Just write a simple scanf() namely can . After the basic version runs normally , Then gradually improve each module .
9.5 Find the address :& Operator
The pointer (pointer) yes C Language is the most important thing ( Sometimes it's the most complicated ) One of the concepts , The address used to store variables . Used in front of scanf() The address is used as a parameter in the function . In a nutshell , If the main calling function does not use return The value returned , You must change the value in the calling function through the address . Next , We will introduce functions with address parameters . First, introduce one yuan & Operator Usage of .
One yuan & Operator gives the storage address of the variable . If pooh Is a variable name. , that &pooh yes The address of the variable . You can think of an address as the location of a variable in memory . Suppose there is the following statement :
pooh = 24;
hypothesis pooh The storage address of is 0B76(PC The address is usually expressed in hexadecimal form ). that , The following statement : printf("%d %p\n", pooh, &pooh);
The following will be output (%p Is the translation description of the output address ):
24 0B76
Program listing 9.12 This operator is used in to see where the variables with the same name in different functions are stored .
Program listing 9.12 loccheck.c Program
/* loccheck.c -- See where variables are stored */
#include <stdio.h>
void mikado(int); /* The function prototype */
int main(void)
{
int pooh = 2, bah = 5; /* main() Local variables of */
printf("In main(), pooh = %d and &pooh = %p\n", pooh,&pooh);
printf("In main(), bah = %d and &bah = %p\n", bah, &bah);
mikado(pooh);
return 0;
}
void mikado(int bah) /* Defined function */
{
int pooh = 10; /* mikado() Local variables of */
printf("In mikado(), pooh = %d and &pooh = %p\n", pooh,&pooh);
printf("In mikado(), bah = %d and &bah = %p\n", bah,&bah);
}
Program listing 9.12 Use in ANSI C Of %p Format print address . Our system output is as Next :
In main(), pooh = 2 and &pooh = 0x7fff5fbff8e8
In main(), bah = 5 and &bah = 0x7fff5fbff8e4
In mikado(), pooh = 10 and &pooh = 0x7fff5fbff8b8
In mikado(), bah = 2 and &bah = 0x7fff5fbff8bc
Make a difference ,%p Addresses are also represented in different ways . However , Many implementations are as shown in this example in , Display the address in hexadecimal . By the way , Each hexadecimal number corresponds to 4 position , This example shows 12 Hexadecimal Numbers , Corresponding 48 Bit address .
What does the output of this example illustrate ? First , Two pooh The address of is different , Two bah The address of Also different . therefore , The same as before , Computers regard them as 4 Independent variables . Its Time , Function call mikado(pooh) Put the actual parameters (main() Medium pooh) Value (2) Pass to Formal parameters (mikado() Medium bah). Be careful , This kind of transmission only passes the value . Two changes involved The amount (main() Medium pooh and mikado() Medium bah) It hasn't changed .
// This concept is very important , The transfer of values from function arguments to formal parameters , Parameter addresses are not passed , The program assigns different addresses to different variables
We emphasize the first 2 spot , Because this is not true in all languages . for example , stay FORTRAN in , Subroutines affect the original variables of the calling routine . The variable name of the subroutine may be different from the original variable , But their addresses are the same . however , stay C This is not the case in language . Every C Functions have their own variables . This is preferable , Because doing so can prevent the original variable from being called Side effects in the function were unexpectedly modified . However , As described in the next section , This also brings some trouble .
9.6 Change the variable in the calling function
Sometimes you need to change the variables of other functions in one function . for example , Exchange the values of two variables in ordinary sorting tasks . Suppose you want to exchange two variables x and y Value . The simple idea is :
x = y;
y = x;
It doesn't work at all , Because the implementation to the 2 Line time ,x The original value of has been y The original value of is replaced by . therefore , Write one more line of code , Store x Original value :
temp = x; // When exchanging values, temporarily stored values are put first , Order of attention
x = y;
y = temp;
The above 3 Lines of code can realize the function of exchanging values , It can be written as a function and construct a A driver to test .
stay Program listing 9.13 in , To clearly indicate which function the variable belongs to , stay main() Using variables in x and y, stay intercharge() Use in u and v.
Program listing 9.13 swap1.c Program
/* swap1.c -- The first 1 Versions of the exchange function */
#include <stdio.h>
void interchange(int u, int v); /* Declare functions */
int main(void)
{
int x = 5, y = 10;
printf("Originally x = %d and y = %d.\n", x, y);
interchange(x, y);
printf("Now x = %d and y = %d.\n", x, y);
return 0;
}
void interchange(int u, int v) /* Defined function */
{
int temp;
temp = u;
u = v;
v = temp;
}
After running the program , Output is as follows :
Originally x = 5 and y = 10.
Now x = 5 and y = 10.
The values of the two variables are not exchanged ! We are interchange() Add some print statements to check for errors
( see Program listing 9.14).
Program listing 9.14 swap2.c Program
/* swap2.c -- lookup swap1.c The problem of */
#include <stdio.h>
void interchange(int u, int v);
int main(void)
{
int x = 5, y = 10;
printf("Originally x = %d and y = %d.\n", x, y);
interchange(x, y);
printf("Now x = %d and y = %d.\n", x, y);
return 0;
}
void interchange(int u, int v)
{
int temp;
printf("Originally u = %d and v = %d.\n", u, v);
temp = u;
u = v;
v = temp;
printf("Now u = %d and v = %d.\n", u, v);
}
Here is the output of the program :
Originally x = 5 and y = 10.
Originally u = 5 and v = 10.
Now u = 10 and v = 5.
Now x = 5 and y = 10.
It seems ,interchange() No problem , It's swapped u and v Value . The problem lies in the result Send back main() when .interchange() The variables used are not main() The variables in the . therefore , In exchange for u and v The value of is right x and y The value of has no effect on ! Whether it can be used return Statement returns a value main()? Certainly. , stay interchange() Add the following line at the end of :
return(u);
And then modify main() In the call :
x = interchange(x,y);
This can only change x Value , and y The value of remains unchanged . use return The statement can only put the called function A value of is returned to the calling function , But now we have to return two values . No problem ! however , To use a pointer .
9.7 Introduction to pointer
The pointer ? What is a pointer ? Fundamentally , The pointer (pointer) Is a variable whose value is the memory address ( Or data objects ). just as char The value of a type variable is a character ,int The value of a type variable is an integer , The value of the pointer variable is the address . stay C In language , Pointers have many uses . This chapter will introduce such as How to use pointers as function parameters , And why it should be used like this .
Suppose a pointer variable name is ptr, You can write the following statement :
ptr = &pooh; // hold pooh Address assigned to ptr
For this statement , We said ptr“ Point to ”pooh.ptr and &pooh Is the difference between the ptr It's a variable. , and &pooh Is a constant . perhaps ,ptr Is a modifiable lvalue , and &pooh It's right value . You can also put ptr Point elsewhere :
ptr = &bah; // hold ptr Point to bah, instead of pooh
Now? ptr The value of is bah The address of . To create a pointer variable , First declare the type of the pointer variable . Suppose you want to put ptr Declare as storage int Pointer to address of type variable , We will use the new operator introduced below .
explain : Pointer is C The most powerful function in language , The most essential part , And the hardest part . Will unfold slowly
9.7.1 Indirect operators :*
Suppose that ptr Point to bah, As shown below :
ptr = &bah;
Then use the indirect operator *(indirection operator) Find out what's stored in bah The value in , The Operators are sometimes called dereference operators (dereferencing operator). Don't put indirect calculation Symbol and binary multiplication operator (*) confusion , Although they use the same symbols , But the grammatical function is different .
val = *ptr; // find ptr The value of the point
sentence ptr = &bah; and val = *ptr; Put together, it is equivalent to the following statement :
val = bah;
thus it can be seen , Using address and indirect operators can indirectly complete the function of the above statement , This is also “ Indirect operators ” The origin of the name .
Summary : Pointer related operators
Address operators :&
general comment :
When followed by a variable name ,& Give the address of the variable .
Example : &nurse Said variable nurse The address of .
Address operators :* general comment : Followed by a pointer name or address ,* Give the value stored in the pointer pointing to the address .
Example : nurse = 22;
ptr = &nurse; // Point to nurse The pointer to
val = *ptr; // hold ptr The value on the address pointed to is assigned to val
Perform the above 3 The final result of this statement is to put 22 Assign to val. // amount to val=22
9.7.2 Declaration pointer
I believe readers are already familiar with how to declare int Types and other basic types of variables , So how to declare pointer variables ? You may think so :
pointer ptr; // You cannot declare pointers like this
Why can't we say so ? because When declaring a pointer variable, you must specify the type of the variable to which the pointer points , Because different variable types take up different storage space , Some pointer operations require that you know the operation The size of the object . in addition , The program must know the type of data stored at the specified address .long and float May take up the same storage space , But they store numbers very differently . Here are some examples of pointer declarations :
int * pi; // pi It's pointing int Pointer to type variable
char * pc; // pc It's pointing char Pointer to type variable
float * pf, * pg; // pf、pg Is directed float Pointer to type variable
The type specifier indicates the type of the object the pointer points to , asterisk (*) Indicates the declared variable It's a pointer .int * pi; The statement means pi It's a pointer ,*pi yes int type ( See the picture 9.5)
* And pointer name . Usually , Programmers use spaces when declaring , Omit spaces when dereferencing variables .
pc The value of the point (*pc) yes char type .pc What is the type of ? We describe its type yes “ Point to char Pointer to type ”.pc The value of is an address , Inside most systems , The address is represented by an unsigned integer . however , Don't think of pointers as integers . Some deal with integers The operation of cannot be used to handle pointers , vice versa . for example , You can multiply two integers , But you can't multiply two pointers . therefore , Pointer is actually a new type , It's not an integer type . because this , As mentioned earlier ,ANSI C Specifically for pointers %p Format conversion description .
9.7.3 Use pointers to communicate between functions
We just touched the pointer , The world of pointers is colorful . This section focuses on how to use pointers to solve the communication problem between functions . Please have a look at Program listing 9.15, The program in interchange() Pointer parameters are used in the function . We will analyze the program in detail later .
Program listing 9.15 swap3.c Program
/* swap3.c -- Use pointers to solve the problem of exchanging functions */
#include <stdio.h>
void interchange(int * u, int * v);
int main(void)
{
int x = 5, y = 10;
printf("Originally x = %d and y = %d.\n", x, y);
interchange(&x, &y); // Send the address to the function
printf("Now x = %d and y = %d.\n", x, y);
return 0;
}
void interchange(int * u, int * v)
{
int temp;
temp = *u; // temp get u The value of the object pointed to
*u = *v;
*v = temp;
}
Whether the program can operate normally ? Here is the output of the program :
Originally x = 5 and y = 10.
Now x = 10 and y = 5.
That's all right. , Everything is all right . Next , We analyze the program list 9.15 Operating condition . First Look at function calls : interchange(&x, &y);
This function does not pass x and y Value , It's their address . This means appearing in interchange() Formal parameters in prototypes and definitions u and v Will take the address as their value . therefore , They should be declared as pointers . because x and y Is an integer , therefore u and v Is a pointer to an integer , The statement is as follows :
void interchange (int * u, int * v)
Next , A temporary variable necessary for exchanging values is declared in the function body :
int temp;
Put x The value of is stored in temp in :
temp = *u;
remember ,u The value of is &x, therefore u Point to x. This means using *u Can be said x Value , This is exactly what we need . Don't write like this :
temp = u; /* Don't do this */
Because this sentence is assigned to temp Yes. x The address of (u The value is x The address of ), instead of x Value . The function to exchange is x and y Value , Not their address .
A similar , hold y The value is assigned to x, To use the following statement :
*u = *v;
This statement is equivalent to :
x = y;
Let's summarize what the program example does . We need a function exchange x and y Value . hold x and y Pass the address of to the function , We let interchange() Access these two functions . Use pointers and * Operator , This function can access the values stored in these locations and change them .
It can be omitted ANSI C Formal parameter names in function prototypes of style , As shown below :
void interchange(int *, int *);
// It's not good , As mentioned earlier, although the function parameter name is meaningless , Or not , But don't leave it empty
generally speaking , Two types of information about variables can be passed to functions . If this form of function call , So the message is x Value :
function1(x); // The first 1 There are three forms of function calls ;
If the following form of function call , So the message is x The address of :
function2(&x); // The first 2 There are three forms of function calls ;
The first 1 Each form requires that the formal parameter in the function definition must be an and x Variables of the same type :
int function1(int num) // The first 1 Three forms of function prototypes ;
The first 2 This form requires that the formal parameter in the function definition must be a pointer to the correct type :
int function2(int * ptr) // The first 2 Three forms of function prototypes
If you want to calculate or process values , Then use the second 1 There are three forms of function calls ;
If you want to change the variable of the calling function in the called function , Then use the 2 There are three forms of function calls .
We used it scanf() That's the function . When a program wants to read a value into a variable ( As in this example num), It's called scanf("%d", &num).scanf() Read a value , Then save the value to the specified address .
//scanf() The function inputs a value and puts it on an address , It is equivalent to changing the variable
In this case , Pointer let interchange() Functions change through their own local variables main() in The value of the variable
be familiar with Pascal and Modula-2 Our readers should see that 1 Forms and Pascal The value parameter of is the same , The first 2 Forms and Pascal The variable parameters of are similar .C++ Programmers may think , since C and C++ All use pointer variables , that C There should also be reference variables . Let them down ,C No reference variable . Yes BASIC For programmers , It may be difficult to understand the whole program . If you think the content of this section is obscure , Please do more related programming exercises , You will find that pointers are very simple and practical ( see chart 9.6)
Variable : name 、 Address and value
Through the previous discussion, it is found that , The name of the variable 、 There is a close relationship between the address and the value of the variable . Let's further analyze .
When writing a program , You can think of a variable as having two properties : Name and value ( There are other properties , Such as type , Don't talk about ). After the computer compiles and loads the program , Consider that variables also have two properties : Address and value . The address is the name of the variable inside the computer .
In many languages , The address belongs to the computer , Hide from programmers . However stay C in , Can pass & Operator access address , adopt * Operator to get the value on the address . for example ,&barn Express Variable barn The address of , Use the function name to get the value of the variable . for example ,printf("%d\n", barn) Print barn Value , Use * Operator to get the value stored on the address . If pbarn= &barn;, that *pbarn It means stored in &barn The value on the address .
In short , Ordinary variables take values as basic quantities , Take the address as a pass through & Operator Derived quantity , The pointer variable takes the address as the basic quantity , Take the value as a pass through * The derived quantity obtained by the operator .
Although printing addresses can satisfy readers' curiosity , But it's not & The main use of operators . what's more Use &、* And pointer can manipulate the address and the content on the address , Such as swap3.c Program ( Program listing 9.15) Shown .
explain : The core purpose of using pointers is to use & and * Operators manipulate addresses , And the content on the address
Summary : function
form :
Typical ANSI C The definition of a function is :
Return type name ( Formal parameter declaration list )
The body of the function
The formal parameter declaration list is a comma separated series of variable declarations . Except for formal parameter variables , Other variables of the function are declared within the curly brackets of the function body .
Example :
int diff(int x, int y) // ANSI C
{ // Function body start
int z; // Declare local variables
z = x - y;
return z; // Returns a value
} // End of function body
Transfer value :
Arguments are used to pass values from the calling function to the called function . If the variable a and b The values of 5 and 2, So called :
c = diff(a,b);
hold 5 and 2 Pass to variables respectively x and y.5 and 2 It's called the actual parameter ( It's called argument for short ),diff() Variables in function definitions x and y Called formal parameter ( It's called formal parameter for short ). Use keywords return Transfer to A value in the function is returned to the calling function . In this case , c Accept z Value 3. The called function generally does not Change the variable in the main function , If you want to change , Pointer should be used as parameter . If you want to make it more Multiple values are returned to the calling function , It has to be done .
The return type of the function :
The return type of a function refers to the type of the return value of a function . If the type of the return value is the same as the declared Return type mismatch , The return value will be converted to the return type of the function declaration .
Function signature :
The return type of the function and the list of formal parameters constitute the function signature . therefore , The function signature specifies the type of the value passed into the function and the type of the return value of the function .
Example :
double duff(double, int); // The function prototype
int main(void)
{
double q, x;
int n;
...
q = duff(x,n); // Function call
...
}
double duff(double u, int k) // Function definition
{
double tor;
...
return tor; // return double Type value
}
Typical function use forms -- Including function prototypes , Function calls and function definitions
9.8 Key concepts
If you want to use C Make efficient and flexible programs , You must understand functions . It is very useful to organize large programs into several functions , Even critical . If you let a function handle a task , The program will be better understood , Easier to debug . Understand how functions transfer information from one function to another , in other words , To understand how function parameters and return values work . in addition , To understand function parameters Other local variables are private to the function , therefore , Variables with the same name declared in different functions are completely Different variables . and , Function cannot directly access variables in other functions . This restricted access guarantee Protect the integrity of data . however , When you really need to access the data of another function in a function , You can take a pointer as an argument to a function .
9.9 Summary of this chapter
Functions can be used as building blocks for large programs . Each function should have a separate and well-defined function . Use parameters to pass values to functions , Use keywords return Return the value to the function . If the value returned by the function is not int type , The type of the function must be specified in the function definition and function prototype . If you need to modify the variables of the calling function in the called function , Use an address or pointer as a parameter Count .
ANSI C Provides a powerful tool —— The function prototype , Allow the compiler to verify whether the number and type of parameters used in function calls are correct .
C The function can call itself , This method of calling is called recursion . Some programming problems need to be solved by recursion , But recursion not only consumes more memory , The efficiency is not high , And it takes time .
边栏推荐
- Babbitt | metauniverse daily must read: the group image of Chinese Internet enterprises pouring into metauniverse: "there are only various survival desires, and there is no ambition for forward-lookin
- 【JDBC】快速入门教程
- The psychological process from autojs to ice fox intelligent assistance
- Interface automation test framework: pytest+allure+excel
- Leetcode35. search the insertion position (simple, find the insertion position, different writing methods)
- (4) Web security | penetration testing | network security web site source code and related analysis
- leetcode841. Keys and rooms (medium)
- leetcode841. 钥匙和房间(中等)
- Win10 64 bit Mitsubishi PLC software appears oleaut32 DLL access denied
- 数据仓库建设思维导图
猜你喜欢
leetcode1020. Number of enclaves (medium)
leetcode704. Binary search (find an element, simple, different writing)
Idea console color log
The ECU of 21 Audi q5l 45tfsi brushes is upgraded to master special adjustment, and the horsepower is safely and stably increased to 305 horsepower
作者已死?AI正用藝術征服人類
The way to learn go (I) the basic introduction of go to the first HelloWorld
微信公众号无限回调授权系统源码 全网首发
Configure raspberry pie access network
MVVM of WPF
The ECU of 21 Audi q5l 45tfsi brushes is upgraded to master special adjustment, and the horsepower is safely and stably increased to 305 horsepower
随机推荐
[MySQL learning notes 29] trigger
The ECU of 21 Audi q5l 45tfsi brushes is upgraded to master special adjustment, and the horsepower is safely and stably increased to 305 horsepower
Set picture annotation in markdown
Introduction to the basics of network security
Lesson 12 study notes 2022.02.11
多线程和并发编程(二)
How Navicat imports MySQL scripts
Résumé de la structure du modèle synthétisable
#systemverilog# 可综合模型的结构总结
Typescript interface properties
Configure raspberry pie access network
树莓派串口登录与SSH登录方法
Get/post/put/patch/delete meaning
Week6 weekly report
杰理之AD 系列 MIDI 功能说明【篇】
Summary of Digital IC design written examination questions (I)
树莓派3B更新vim
Cookie技术&Session技术&ServletContext对象
【MySQL学习笔记32】mvcc
leetcode704. 二分查找(查找某个元素,简单,不同写法)