In the last blog, we mentioned the branches and loops of C language. In this blog, I'll share the relevant knowledge of C language functions. Please open your eyes and have a good look (HA HA).
When it comes to functions, the first thing we think of is mathematical functions. This very interesting and practical knowledge in the field of mathematics can also be said to be tools. Will it have the same effect in the programming world? The answer was: Yes. Not only in mathematics, but also in programming, it is also a very useful tool. That's nonsense. Let's start our next content.
catalogue
1, What are the functions in C language
2, Classification of C language functions
3.1 actual parameters (actual parameters):
2.2 formal parameters (formal parameters):
5, Nested calls and chained access to functions
6, Declaration and definition of functions
7.1 two necessities of recursion
1, What are the functions in C language
The following passage comes from Baidu:
"A function defined in c language is a piece of code that can be reused to complete a function independently. It can receive or not receive the data passed by the user. When defining a function that receives user data, it needs to specify parameters. If it does not receive user data, it does not need to specify parameters. According to this point, the function can be divided into parametric function and nonparametric function. A function is an encapsulated function that can be used With reusable code, it makes our program more modular and does not need to write a lot of repetitive code. The function can be saved in advance and given a unique name. As long as you know its name, you can use this code. "
The following code simply uses the function to print a menu. Here is just a brief description. How to use the function and its form will be discussed later. (the above paragraph is relatively long, which is not easy to understand. I will introduce it in detail below according to my understanding)
II. Classification of C language functions
2.1 library functions
First, let's start with a few library functions we've used
For example:
1) Print a "Hello World!" on the screen, We'll use (printf)
2) We need to enter "Hello World!", To use (scanf)
3) When we want to calculate the k-th power of n, we use (pow)
These are our common library functions. C language provides us with a series of library functions for our convenience.
How many library functions are there? Here's a website. You can understand it.
http://www.cplusplus.com/reference/http://www.cplusplus.com/reference/
There are many library functions we will use, so it is a very easy to use website.
be careful:
To use library functions, you must include #include# the corresponding header file.
2.2 user defined functions
The difference between custom functions and library functions is that we can design our own functions according to the effect we want to achieve.
Composition of custom functions:
Return type} function name (function parameter); (function parameters also have types) (there can be one or more)
Functions are defined first and then called.
Let's take the strlen function (calculating the length of a string) as an example
size_t stands for unsigned integer. Calculate the length of the string. It must not be negative
Const, we need to calculate the length of the string. We can't change the string, so we use const to decorate it
char * character pointer
Let's write a function to calculate the maximum of two numbers.
#include <stdio.h> int Find_Max(int x, int y) { if (x > y) { return x; } else { return y; } //There is a simpler way to write, using the binocular operator //return x > y ? x : y; } int main() { int num1 = 0; int num2 = 0; scanf("%d %d", &num1, &num2); int max = Find_Max(num1, num2); printf("%d\n", max); return 0; }
3, Parameters of function
3.1 actual parameters (actual parameters):
2.2 formal parameters (formal parameters):
The code for finding the maximum value of the two functions above, num1 and num2 are the arguments, and x and y are the formal parameters
Let's take a look at the monitor, & take the address symbol and the address of the formal parameter and the argument. It is obvious that the formal parameter and the argument open up two different addresses, so the formal parameter is equivalent to a temporary copy of the actual parameter.
4, Function call
4.1 value transfer call
The formal parameters and arguments of the function occupy different memory space respectively, and the modification of the formal parameters will not affect the arguments.
4.2 address calling
Let's write a function to exchange the contents of two integer variables
void Swap1(int x, int y) { int tmp = 0; tmp = x; x = y; y = tmp; } void Swap2(int* px, int* py) { int tmp = 0; tmp = *px; *px = *py; *py = tmp; } int main() { int a = 0; int b = 0; scanf("%d %d", &a, &b); printf("Before exchange: a=%d,b=%d\n", a, b); //Swap1(a, b); Swap2(&a, &b); printf("After exchange: a=%d,b=%d\n", a, b); return 0; }
Two functions are written here. We can compare Swap1 and Swap2.
As we have also mentioned above, formal parameters and arguments open up two different memory spaces. Swap1 is interpreted as a value passing call. We just exchange the formal parameters without changing the arguments, while the formal parameters are only a temporary copy of the arguments. When the function is called, the formal parameters will be automatically destroyed, so swap1 cannot achieve the functions we want.
Swap2 passes the address of the argument. The function parameter part is received by the pointer variable (the pointer variable is the storage address), which is the address call. The formal parameter and the argument use the same memory space, which can establish a true relationship between the function and the variables outside the function, that is, the variables outside the function can be directly operated inside the function.
From the above figure, we can see that the addresses of a and px are the same, and the addresses of b and py are the same.
Here are some codes for realizing various problems with functions
(1)
//Print prime numbers between 100 and 200 #include <stdio.h> #include <math.h> int is_prime(int n) { //Number division of 2~n-1 //Trial division of 2~sqrt(n) int j = 0; for (j = 2; j <= sqrt(n); j++) { if (n % j == 0) { return 0; } } return 1; } int main() { int i = 0; for (i = 100; i <= 200; i++) { //Judge whether it is prime //The return value is 1, which means it is a prime number //The return value is 0, which means it is not a prime number if (is_prime(i) == 1) { printf("%d ", i); } } return 0; }
(2)
//Write a function to judge whether it is a leap year #include <stdio.h> int Is_leap_year(int n) { //Rules for judging leap years: //(1) Can be divided by 4, but not by 100 //(2) Can be divided by 400 if (n % 4 == 0 && n % 100 != 0 || n % 400 == 0) { return 1; } return 0; //Concise method //return (((n % 4 == 0) && (n % 100 != 0)) || (n % 400 == 0)); } int main() { int y = 0; scanf("%d", &y); int ret = Is_leap_year(y); //If it is a leap year, return 1 //If it is not a leap year, it returns 0 if (ret == 1) { printf("%d Year is a leap year\n", y); } else { printf("%d Year is not a leap year\n", y); } return 0; }
(4)
//Write a function to realize the binary search of an integer ordered array //Return subscript when found //Return - 1 if not found #include <stdio.h> int binary_search(int arr[], int k, int sz) { int left = 0; int right = sz - 1; while (left <= right) { int mid = left + (right - left) / 2; if (arr[mid] < k) { left = mid + 1; } else if (arr[mid] > k) { right = mid - 1; } else { return mid; } } return -1; } int main() { int arr[] = { 1,2,3,4,5,6,7,8,9,10 }; int k = 0; scanf("%d", &k);//Number of to find int sz = sizeof(arr) / sizeof(arr[0]); int ret = binary_search(arr, k, sz); if (-1 == ret) { printf("Can not find\n"); } else { printf("Found, subscript:%d\n", ret ); } return 0; }
5, Nested calls and chained access to functions
5.1 nested calls to functions
#include <stdio.h> void new_line() { printf("Hello\n"); } void three_line() { int i = 0; for (i = 0; i < 3; i++) { new_line(); } } int main() { three_line(); return 0; }
Nested definition:
So remember this is wrong.
5.2 chain access
This is the code for chain access
There is a typical chain access code
4321 is displayed on the screen. Why is this?
This is the return value of the printf function, which means that each of these functions returns the number of characters printed. If an error occurs, it returns a negative value. Therefore, from the inside to the outside, print 43 first, 43 is two characters, the next print 2, 2 is one character, so finally print 1, and finally print 4321 on the screen.
6, Declaration and definition of functions
6.1 function declaration
1. Tell the compiler what a function name is, what the parameters are and what the return type is. But whether it exists or not depends on the function declaration.
2. The declaration of a function usually appears before the use of the function. To meet the requirements of declaration before use.
3. The function declaration is generally placed in the header file.
6.2 definition of function
The definition of function refers to the specific implementation of the function and explains the function implementation of the function.
The following code is different from the above. The above code will put the custom function on the main function, but if it is written like this, a warning will be reported.
Therefore, it should be noted that the above-mentioned declaration before use. (but it's not often written like this, even if it's the right way)
VII. Function recursion
The programming technique of a program calling itself is called recursion.
As an algorithm, recursion is widely used in programming languages. A method in which a process or function directly or indirectly calls itself in its definition or description. It usually transforms a large and complex problem layer by layer into a smaller problem similar to the original problem.
Recursive strategy: only a small number of programs can describe the multiple repeated calculations required in the problem-solving process, which greatly reduces the amount of code in the program.
The main way of thinking about recursion is to make big things small
Simply put, function recursion means that the function calls itself.
7.1 two necessities of recursion
(1) There is a constraint. When this constraint is met, recursion will not continue.
(2) Getting closer to this constraint after each recursive call
For example:
//Receives an integer value (unsigned) and prints its bits in order void print(int n) { if (n > 9) { print(n / 10); } printf("%d ", n % 10); } int main() { unsigned int num = 0; scanf("%d", &num);//1234 print(num);//The print function can print out each bit of num in order return 0; }
Draw a simple diagram to familiarize yourself with the recursive process:
Let's mention the stack area. Every time the program calls the function, it will open up a memory space on the memory stack area. For example, when the code just now is n = 1234, it will open up a space, and so on. If we don't set a limit condition, and don't get closer to the limit condition as we go on, will recursion continue all the time, The case of dead recursion is formed, but the space of the stack area is limited. If it is opened up without limitation, it will cause stack overflow. The following figure uses the above code to briefly illustrate.
7.2 recursion and iteration
As for recursion, we also introduced that iteration can be simply understood as a loop.
Here are some examples:
(1)
//Calculating factorial of n by recursion int fac(int n) { if (n <= 1) { return 1; } else { return n * fac(n - 1); } } int main() { int n = 0; scanf("%d", &n); int ret = fac(n); printf("%d\n", ret); return 0; }
(2)
//Use recursion to find the nth Fibonacci number. (overflow is not considered) int fib(int n) { if (n <= 2) { return 1; } else { return fib(n - 1) + fib(n - 2); } } int main() { int n = 0; scanf("%d", &n); int ret = fib(n); printf("%d\n", ret); return 0; }
This is written by recursive method, but there will be some small problems with recursive method. If we want to calculate the 40th Fibonacci number, it will not be printed on the screen immediately. That is because calculating the 40th number requires a large amount of calculation. Even the computer has to calculate it for a while. We can imagine how much calculation is.
To calculate the 40th Fibonacci number, as shown in the figure above, you need to calculate from 40 to the first number. If it is the 50th Fibonacci number, it will take longer.
But if you don't use recursive methods, will there be a better method to improve efficiency?
int fib(int n) { int a = 1; int b = 1; int c = 0; int i = 0; if (n <= 2) { return 1; } while (n > 2) { c = a + b; a = b; b = c; n--; } return c; } int main() { int n = 0; scanf("%d", &n); int ret = fib(n); printf("%d\n", ret); return 0; }
The above code does not use the recursive method, but it can also calculate the nth Fibonacci number, and the efficiency of the code is greatly improved. Compared with the recursive method from the nth to the first, this non recursive method from the first to the nth is very fast, so the knowledge is vivid, It can't be said that today we learn recursion and abandon other methods. We still have to find the optimal solution.
Conclusion:
I'll share the relevant knowledge about C language functions here. This blog is written here. I think it's great to write a blog. I feel that every day is very full. I'm looking forward to my next blog. (ha ha, sprinkle flowers after the end)