preface
Function is very important. Generally, when we learn more and more, we will often use function to simplify the redundancy of main function when dealing with code. Even in the later stage of learning, we will not use function or even write code
Benefits of using functions: For details, click to jump to the original website
1. Reduce complexity
2. Avoid repeating snippets
3. Limit the impact of changes
4. Implicit order
5. Improve performance
6. Centralized control
7. Implicit data structure
8. Implied pointer operation
9. Implicit global variable
1. What is the functionWe often see the concept of function in mathematics, but what about the function in C language?
Definition of function in Wikipedia: subroutine
- In computer science, a subroutine is a part of code in a large program, which is composed of one or more statement blocks
Yes. It is responsible for completing a specific task and has relative independence compared with other codes.- Generally, there are input parameters and return values, which provide encapsulation of the process and hiding of details. These codes are usually integrated into software libraries.
- Library function
- Custom function
2.1 library functions:
Why are there library functions?
-
In the process of programming, we will frequently print information to the screen (printf) according to a certain format.
-
In the process of programming, we often do some string copy (strcpy).
-
In programming, we often calculate, always calculate the k power of n (pow).
Like the basic functions we described above, they are not business code. In order to support portability and improve program efficiency, a series of similar library functions are provided in the basic library of C language to facilitate programmers' software development.
How do you learn library functions?
Let's take a brief look here: www.cplusplus.com or http://zh.cppreference.com (Chinese version)
To sum up, the library functions commonly used in C language are:
- IO function
- String operation function
- Character manipulation function
- Memory operation function
- Time / date function
- Mathematical function
- Other library functions
2.1.1 learning library functions
It is very important to learn how to use library functions by yourself. Learn to check MSDN and cplusplus websites and teach yourself how to use library functions. The purpose is to master the use methods of library functions
After all, we can't remember all library functions, so we should learn to use query tools
For example, by checking MSDN, I can find:
strtok
char *strtok( char *strToken, const char *strDelimit );
memmove
void *memmove( void *dest, const void *src, size_t count );
Try using the library function
Note:
However, the library function must ensure that when using the library function, it must include #include its corresponding header file.
2.2 user defined functions
If library functions can do everything, what do programmers do?
All the more important is the user-defined function, which is simply to write a function by yourself.
Like library functions, custom functions need function names, return value types, and function parameters.
But the difference is that these are designed by ourselves. This gives programmers a lot of room to play. Is it the same as painters and novelists? So are those programmers all artists? ╰( ̄ ω  ̄o)
2.2.1 composition of function:
ret_type fun_name(para1, * ) { statement;//Statement item } ret_type Return type fun_name Function name para1 Function parameters
2.2.2 some chestnuts
get_ Design of Min function
#include <stdio.h> int get_min(int x, int y) { return (x < y) ? (x) : (y);//ternary operators } int main() { int n1 = 10; int n2 = 20; int min = get_min(n1, n2); printf("min = %d\n", min); return 0; }
swap function design
First, I wrote a Swap1 and implemented it as a function, but it seems that I can't complete the task
Change to the correct version of Swap2
Compare it to see if you can find the problem. Sometimes we have to think about whether to pass parameters by value or address
#include <stdio.h> 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 num1 = 1; int num2 = 2; printf("Swap1 Before exchange:num1 = %d num2 = %d\n", num1, num2); Swap1(num1, num2); printf("Swap1 After exchange:num1 = %d num2 = %d\n", num1, num2); Swap2(&num1, &num2); printf("Swap2 After exchange:num1 = %d num2 = %d\n", num1, num2); return 0; }
Value transmission and address transmission of functions (num1, num2 and xy are two completely independent spaces, and the addresses are different)
Since there is no grammatical problem, it must be a logical problem
Through this example, we will introduce the function parameters of the function real participation function
3. Parameters of function3.1 actual parameters (actual parameters):
The parameters really passed to the function are called arguments.
Arguments can be constants, variables, expressions, functions, etc.
No matter what type of arguments are, they must have definite values when making a function call in order to pass these values to the formal parameters.
3.2 formal parameters (formal parameters):
Formal parameters refer to the variables in parentheses after the function name. They are called formal parameters because they are instantiated (memory units are allocated) only when the function is called.
Formal parameters are automatically destroyed when the function call is completed. Therefore, formal parameters are only valid in functions.
3.3 understanding form participation arguments
The parameters x, y, px and py in the above Swap1 and Swap2 functions are formal parameters. Num1 and num2 passed to Swap1 in the main function and & num1 and & num2 passed to Swap2 function are actual parameters.
Here we analyze the arguments and formal parameters of the function: using debugging, we can easily see the process
In Swap1, we passed the value. The two formal parameters xy have changed, but num1 and num2 have not changed after walking
This is because when a function is called, the argument is passed to the formal parameter. The formal parameter is actually a temporary copy of the argument, so the modification of the formal parameter will not affect the argument
In Swap, we pass the address. Because we pass the address, px and py in the function can find num1 and num2 of the main function, which is the function of the pointer
Therefore, px and py can be used to change num1 and num2
Summary:
- Understand the relationship between the value and address of Swap when passing in a function
- In fact, sometimes we need to analyze the situation when designing functions:
Value or address?
This leads to the next chapter
4. Function call:4.1 value transfer call
The formal parameters and arguments of the function occupy different memory blocks respectively, and the modification of the formal parameters will not affect the arguments.
4.2 address calling
- Addressing call is a way to call a function by passing the memory address of the variable created outside the function to the function parameters.
- This parameter transfer method can establish a real relationship between the function and the variables outside the function, that is, the function can be operated directly
As an external variable of a function.
For the previous example
Get before you meet_ Min function or summation function, whether it is a small value or a summation value, we only need the final result. Naturally, we don't need to change the original passed value, so we can solve the problem by passing the value.
However, if we encounter the Swap function, we need to pass the address, because we need to change the value stored in the two variable addresses passed in the past, don't we? So we need to pass the address to change it in order to work
Swap1(num1, num2);//Value transmission Swap2(&num1, &num2);//Byref
4.3 small exercises
- Write a function to judge whether it is a prime number (100-200).
#include<math.h> #include<stdio.h> //A prime number returns 1, not a prime number returns 0 int is_prime(int n) { //2-n-1 trial division int j = 0; for (j = 2; j < sqrt(n); j++) { if (n % j == 0) { return 0;//return is the end } } return 1;//return 1 if you haven't returned before } int main() { int i = 0; for (i = 100; i <= 200; i++) { //Judge whether i is a prime number, and print i if yes if (is_prime(i)==1) { printf("%d ", i); } } return 0; }
- Write a function to realize the binary search of an integer ordered array
#include<stdio.h> int Binary_Search(int arr[], int target,int sz) { int left = 0; int right = sz-1; while (left <=right) { int mid = (left + right) / 2; if (arr[mid] == target) { return mid; } else if(arr[mid]<target) { left = mid + 1; } else if (arr[mid] > target) { right = mid - 1; } } if (left >= right) { return -1; } } int main() { int arr[] = { 1,2,3,4,5,6,7,8,9,10 }; int target = 0; printf("Enter a subscript\n"); scanf("%d", &target); int sz = sizeof(arr) / sizeof(arr[0]); int result=Binary_Search(arr,target,sz); if (-1==result) { printf("The number could not be found\n"); } else { printf("Yes, the subscript is%d\n",result); } }
Note: int sz = sizeof(arr) / sizeof(arr[0]); The position of this sentence is very important
Note that it is best to calculate sz outside the function, otherwise it is easy to transfer arr [] the entire array to the first address accidentally. If sizeof(arr) becomes 4 / 8 bytes during internal operation in the function, resulting in sz size error
- Write a function to judge whether a year is a leap year
int is_leap_year(int i) { if ((i % 4 == 0) && (i % 100 != 0) || (i % 400 == 0)) { return 1; } else { return 0; } } int main() { int y = 0; for (y = 1000; y <= 2000; y++) { if ((is_leap_year(y)) == 1) { printf("%d ",y); } } return 0; }
4. Understand the difference between value transfer and address transfer, and the add function
void add(int *p) { *p+=1; } int main() { int num = 0; add(&num); printf("%d\n", num); return 0; }
Method 2: the function returns an int parameter
int add(int n) { return n+1; } int main() { int num = 0; num = add(num); printf("%d\n", num); return 0; }5. Nested and chained access of functions
According to the actual needs, functions and functions can be combined according to the actual needs, which also enables us to realize a variety of functions, that is, they can call each other.
5.1 nested calls to functions
Instances of nested calls
void golden() { printf("Important things are to be repeated for 3 times\n"); } void state() { int i = 0; for (i = 0; i < 3; i++) { golden(); } } int main() { state(); return 0; }
Note:
Functions can be called nested, but they cannot be defined nested
5.2 chained access to functions
Examples of chain access:
int main() { int len = strlen("Valar Moghulis"); printf("%d\n", len); printf("%d\n",strlen("Valar Moghulis"));//Nested Call return 0; }
Chained access: the return value of a function is used as an argument to another function
Take another look at the following code
int main() { pritnf("%d", printf("%d", printf("43"))); }
Here we can refer to MSDN
Understand:
Because the innermost printf will print 43 for the first time, and the return value is the number of char s printed by printf, the remaining two will return 2 and 1 in turn. Chain access is used here
6. Function declaration and definition6.1 function declaration:
What is a function declaration? What are the points of attention for function declarations?
- Tell the compiler what a function is called, what the parameters are and what the return type is. But is there a function
The statement can't decide.
- The declaration of a function usually appears before the use of the function. To meet the requirements of declaration before use.
- The declaration of the function is usually placed in the header file.
6.2 function definition:
Function definition can determine whether the function is real and valid
The definition of function refers to the specific implementation of the function and explains the function implementation of the function.
6.2.1 function implementation in multiple files
Generally, when we write a project or project, we will habitually create three files instead of writing in one file
for instance
file nameFunctional functionababa.cCreate and implement each functionababa.hDeclaration header file, which implements the declaration of each function and is used to referencetest.cTest run file, the main function is hereFor example, in ABA. H, it says:
//Declaration of function int Ababa(int x, int y);
For example, I wrote in ABA. C:
#include "ababa.h" //Implementation of Add function int ababa(int x, int y) { printf("ABBA ABBA%d\n",x+y); }
Another example is that I want to write a computer:
I can create files and realize their functions in this way, realize different calculator functions in different source files, and finally integrate them into calculators
7. Function recursion7.1 what is recursion?
The programming skill of program calling itself is called dolls.
As an algorithm, recursion is widely used in programming languages. A method in which a procedure 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. The recursive strategy can describe the multiple repeated calculations required in the problem-solving process with only a small amount of program, which greatly reduces the amount of code of the program.
The main way of thinking about recursion is to make big things small
Note: but sometimes it will increase the operation time of the program
7.2 two necessary conditions for recursion
7.2.1 restrictions
Every recursion must be subject to a restriction:
There is a constraint. When this constraint is met, recursion will not continue.
7.2.2 constant approach
All recursion must meet:
After each recursive call, the result is getting closer and closer to this limit. Naturally, it can't be farther and farther away
For example, writing a function to find the length of a string does not allow the creation of temporary variables
7.2.3 examples
7.2.3.1 print each bit of integer in sequenceAccepts an unsigned integer value and prints its bits in order.
#include <stdio.h> void print(int n) { if (n > 9) { print(n / 10); } printf("%d ", n % 10); } int main() { int num = 1234; print(num); return 0; }7.2.3.2 find string length
Write a function to find the length of a string. Temporary variables are not allowed
#include <stdio.h> int my_strlen1(char* s) { int count = 0;//Temporary variables, No while (*s != '\0') { count++; s++; } return count; } int my_strlen(const char* str)//Using recursion { if (*str == '\0') return 0; else return 1 + my_strlen(str + 1); } int main() { char* p = "Icandoallthings"; int len = my_strlen(p); printf("%d\n", len); return 0; }
7.3 recursive exercises
7.3.1 exercise 1
//Find the factorial of n. (results will overflow if not considered) int factorial(int n) { if (n <= 1) return 1; else return n * factorial(n - 1); }
But we found a problem: if we use the factorial function to find the factorial of 10000 (regardless of the correctness of the result), the program will crash.
7.3.2 exercise 2
The process is
Print(1234)
Print(123) 4
Print(12) 3 4
Print(1) 2 3 4
//Accept an integer value (unsigned) and print its bits in order. //For example: input: 1234, output 1 2 3 4 #include <stdio.h> void Print(int n) { if (n > 9) { Print(n / 10); } printf("%d ", n % 10); } int main() { int num = 1234; Print(num); return 0; }
7.3.3 exercise 3
A classic example: find the nth Fibonacci number. (result overflow is not considered)
int Fibonachi(int n) { if (n <= 2) return 1; else return Fibonachi(n - 1) + Fibonachi(n - 2); }
But we found a problem: when using Fibonachi, if we want to calculate the 50th Fibonacci number, it takes a lot of time.
Why?
- We find that many calculations are repeated during the call of fib function. The more, the slower
If we modify the code:
int count = 0;//global variable int Fibonachi(int n) { if(n == 3) count++; if (n <= 2) return 1; else return Fibonachi(n - 1) + Fibonachi(n - 2); }
We can output count to see the number of cycles. It is a very large value.
How can we improve it?
When debugging the factorial function, if your parameter is large, an error will be reported: stack overflow
Why do you report an error stack overflow?
It is known that each call to a function must open up a part of memory space in the stack area, and the stack space allocated by the system to the program is limited. However, if an dead cycle occurs, it may lead to the opening of the stack space all the time, and eventually lead to the depletion of the stack space. This phenomenon is called stack overflow.
Note:
So whenever we find that the error is stack overflow, can we think about whether there may be a problem with the loop
How to solve the above problems:
- Rewrite recursion to non recursion.
- Use static objects instead of nonstatic local objects. In recursive function design, static objects can be used instead
Nonstatic local object (i.e. stack object), which can not only reduce the overhead of generating and releasing nonstatic objects during each recursive call and return, but also save the intermediate state of recursive call and can be accessed by each call layer.
8.1 Hanoi Tower problem
Please read RAIN 7 blog for train of thought analysis
void hanoi(int n, char x, char y, char z) { if (n == 1)//Recursion ends here move(x, z); else { hanoi(n - 1, x, z, y); //Move n-1 plates from the x column to the y column with the help of the z column move(x, z); // Move the remaining disk on the x column to the z column hanoi(n - 1, y, x, z); //Move n-1 disks from the y column to the z column with the help of the x column } } int main() { int n = 0; printf("Please enter the initial number of discs:"); scanf("%d", &n); hanoi(n, 'A', 'B', 'C'); return 0; }
8.2 frog jumping steps
Please read RAIN 7 blog for train of thought analysis
//Frog jumping steps #include <stdio.h> int Fun(int n) { if (n == 1) return 1; else if (n == 2) return 2; else if (n>2) return Fun(n - 1) + Fun(n - 2); } int main() { int n = 0; scanf("%d", &n); int ret=Fun(n); printf("%d\n", ret); return 0; }
Summary:
That's all for functions and recursion. There are still some difficulties in recursion. In the final analysis, functions are still very important. If you think they are OK after reading, I hope you can leave praise and attention