[Elementary C Language] Understanding and Using Functions

1. What is a function
2. Library function
3. Custom function
4. Function parameter
5. Function call
6. Function nested call and chain access
7. Function declaration and definition
8. Function recursion

1. What is a function

There are functions in mathematics, and there are also functions in C language. Let's give a definition first:

Functions are defined as subroutines in Wikipedia:

         In computer science, a subroutine (English: Subroutine, procedure, function, routine, method,
subprogram, callable unit) is a certain part of the code in a large program,
consisting . It is responsible for completing a specific task and is relatively independent from other codes.
Generally, there will be input parameters and a return value , providing the encapsulation of the process and the hiding of details. These codes are often integrated as software libraries.

For example: main function, printf printing function, etc., are all functions in C language.

We can compare a function to a factory, where things are sent in for processing, and when they come out, they will become the products you want.

 The basic structure of a function: function name, return type, function parameters and function body


In the C language, there are two types of functions, library functions and custom functions, which will be introduced one by one below.

2. Library functions

1. Source: A series of library functions are provided in the basic library of C language

2. Library functions:

         Comparing a function to a processing factory, then a library function is a factory with a unique name that has been built . We just need to feed raw materials (data) into this factory and receive products (results). Let's take an example:

  • Calculate the length of a string:
char arr[]="love";//用数组来存放字符串
#include<stdio.h>
#include<string.h>
int main()
{
  char arr[]="love";//定义的数组(原材料)
  int ret=0;//定义一个变量记录字符串的长度(接收产品)
  ret strlen(arr);//送入工厂
  printf("%d\n",ret);//printf也是库函数
  return 0;
}

We can clearly see that we only need to put the array name arr into the strlen function, and then use the variable ret to receive the product.

  • The array name is the address of the first element, and the content of the entire string can be found through the first address, so you only need to send arr into the function.

Note:
    But a secret that the library function must know is: to use the library function, the header file corresponding to #include must be included. So why there are things like #include<stdio.h> (main function, printf function and other functions need to be included), #include<string.h> (strlen function needs to be included). Next, we roughly determine the category of header files that each library function needs to use through the classification of library functions

3. Classification of library functions

     A series of functions with similar functions

  • I/O function

        Input and output functions---<stdio.h>

  • String manipulation functions

         strlen strcpy

  • character manipulation functions

        Determine letter case, conversion, etc.

  • memory manipulation function
  • time/date functions
  • math function

        <math.h>, such as: Pow

  • Other library functions

4. Examples of library functions 

     Pow function: used to calculate the power, such as: 2^3=8

function prototype

double pow (double base, double exponent);//函数原型

 Parameter type: This function can calculate powers of decimals with higher precision, so it can also calculate integer variables. Therefore, the highest result can be a decimal, so the return value is double type.

Function parameter: Because decimals can be calculated, the type of the parameter can also be double type.

The first parameter (double base) is the base, and the second parameter (double exponent) is the power.

So we only need to send the raw material (number to be calculated) to the function (factory) to get the result (product)

 Usage: We now want to calculate the result of 2^3, just need to send it into the function.

#include<tsdio.h>
#include<math.h>//pow函数需要包含的头文件
int main()
{
  int n=0;//创建一个变量用于接收计算的结果
  //n=pow(2,3);这样也可以,不过编译器会有警告
  n=(int)pow(2,3);
  printf("%d\n",n);
  return 0;
}

(int) is a mandatory conversion type, converted to an integer

Summary: pow is a library function that can calculate powers, and the required header file is #include<math,h>

strcpy function: copy the string in A to B

Function prototype:

char * strcpy ( char * destination, const char * source );//函数原型

 Return value type: return the address of the target, so it needs to be received by a pointer, and because it is a string operation function, so char

Function parameters: the first parameter (destination) is the destination pointer (harvest address), which is copied in

                  The second parameter (source) is the source pointer (the place where the shipment is made), the value to be copied

Note: When copying, there will be a \0 (the sign of the end of the string), but the content behind the \0 of the original array still exists, but it is not printed.

usage:

#include<stdio.h>

int main()
{
	char A[] = "#############";
	char B[] = "love you";
	printf("交换前A:%s\n", A);
	printf("交换前B:%s\n", A);
	strcpy(A, B);//过程是从B到A
	printf("交换后B:%s\n",A);
	return 0;
}

 Because the array name is the first address, there is no need to pass the address.

Summary: strcpy is a string copy function, the first parameter is the copied parameter, and the second is the copied parameter

menset function: initialization function for memory settings

void * memset ( void * ptr, int value, size_t num );//函数原型

 Function parameters: the first parameter (ptr) is the operation target; the second parameter (value) is the initialization content, and the third parameter (num) is the number of operations

usage:

#include<stdio.h>
int main()
{
	char arr[] = "love you";//原数组
	printf("%s\n", arr);
	memset(arr,'6',3);操作之后
	printf("%s\n",arr);
	return 0;
}

3. Custom functions

Foreword: Functions such as factories, library functions are official factories that have been made, then custom functions need us to construct the factory and use it ourselves, because the factory has not been made yet, so we can name it ourselves.

1. Composition of custom functions

Function name + return value type + function parameters + function body

Compared with library functions, custom functions have more function bodies than library functions. This part is the function of the factory and needs to be implemented by ourselves.

ret_type fun_name(para1, * )
{
       statement;//语句项
}
ret_type 返回类型
fun_name 函数名
para1 函数参数

The statement item here is the function body

2. Examples of custom functions

(1) Write a function to find the maximum value of two numbers (pass value)

#include <stdio.h>
//get_max函数的设计
int get_max(int x, int y)
{
	return (x > y) ? (x) : (y);
}
int main()
{
	int num1 = 10;
	int num2 = 20;
	int max = get_max(num1, num2);
	printf("max = %d\n", max);
}

(2) Write a function to exchange the values ​​of two integers 

Let's look at the wrong spelling first

 Reason: The values ​​of num1 and num2 are passed to the formal parameters x and y, so x and y just copy a copy of the data. If we modify the data on the copy, it will not affect the original.

Let's see the correct spelling:

#include <stdio.h>
//正确的版本
void Swap2(int* px, int* py)//接收实参的时候,形参是指针变量
{
	int tmp = 0;
	tmp = *px;
	*px = *py;
	*py = tmp;
}
int main()
{
	int num1 = 1;
	int num2 = 2;
	Swap2(&num1, &num2);//注意这里是&num1,&num2
	printf("Swap2::num1 = %d num2 = %d\n", num1, num2);
	return 0;
}

result:

 Reason: The addresses of the variables num1 and num2 are passed to the formal parameters, and the source of the formal parameters can be found through the addresses, and then the direct exchange is successful. call by reference

        It can be understood in this way 1: We pass the website address of the account to others, and others can find our account by logging in to the website, and modify it directly; then we give the copy of the account to others, and it is wrong for others to modify our account on the copy no effect.

       Substantial understanding 2: The location where the variable is stored in the memory can be found through the address of the variable. This location is where the variable data is located, and the data is directly modified at the location to achieve the modification effect.

4. Function parameters and function calls

1. Function parameters: actual parameters (actual parameters) and formal parameters (formal parameters)

Actual parameters:

   The parameters actually passed to the function are called actual parameters. Can be variables, expressions, constants and functions, but must have a definite value.

Example:

Max(520,num1)//520是常量,num1是变量
Max(3+5,&num1)//3+5是表达式,&num1是变量
Max(printf("%d",num1))//函数形式

Formal parameters:

    Used to receive actual parameters. refers to the variable in parentheses after the function name, because the formal parameters are only instantiated (allocated memory units) during the function is called. It only exists in the function and is automatically destroyed when it goes out of the function scope.

Example:

   

2. Memory of actual parameters and formal parameters

Note: The memory units where the actual parameters and formal parameters are located are different, and they are independent 

   We use the code to illustrate:

We check on the compiler:  therefore, the formal parameters are created in the function body, only exist in the function, and are automatically destroyed when the function is out

3. Function call

     call by value and call by reference

  • Call by value: The formal parameters and actual parameters of the function occupy different memory blocks, and the modification of the formal parameters will not affect the actual parameters
  • Call by address: Call by address is a way to call a function by passing the memory address of the variable created outside the function to the function parameter. This way of passing parameters can establish a real connection between the function and the variables outside the function, that is, the inside of the function can directly manipulate the variables outside the function.

Call by value:

#include <stdio.h>
//get_max函数的设计
int get_max(int x, int y)
{
	return (x > y) ? (x) : (y);
}
int main()
{
	int num1 = 10;
	int num2 = 20;
	int max = get_max(num1, num2);//传值调用
	printf("max = %d\n", max);
}

Call by address:

#include <stdio.h>
//正确的版本
void Swap2(int* px, int* py)
{
	int tmp = 0;
	tmp = *px;
	*px = *py;

	*py = tmp;
}
int main()
{
	int num1 = 1;
	int num2 = 2;
	Swap2(&num1, &num2);//传址调用
	printf("Swap2::num1 = %d num2 = %d\n", num1, num2);
	return 0;
}

5. Function chain access and nested use

1. Nested calls

#include <stdio.h>
void new_line()
{
   printf("hehe\n");//在new_line函数内部又调用了printf函数
                    //称为嵌套调用
}
void three_line()
{
   int i = 0;
   for(i=0; i<3; i++)
   {
    new_line();//在three_line函数内又嵌套调用new_line
   }
}
int main()
{
    three_line();
    return 0;
}

Functions can be nested and call each other, but they cannot be nested.

void test()
{
  //int Add(int x,int y);//在函数内部嵌套定义
   Add(x,y)//这样子就可以
}
int main()
{
   test();
   return 0;
}

2. Chain access

     Return value of one function as parameter of another function

#include <stdio.h>
#include <string.h>
int main()
{
   char arr[20] = "hello";
   int ret = strlen(strcat(arr,"bit"));//strcat的返回值作为strlen的参数
   printf("%d\n", ret);
   return 0;
}
#include <stdio.h>
int main()
{
   printf("%d", printf("%d", printf("%d", 43)));//结果4321
   //注:printf函数的返回值是打印在屏幕上字符的个数,打印几个,返回几
return 0;
}

6. Function declaration and definition

1. Function declaration

  •      Tell the compiler what a function is called, what its parameters are, and what its return type is. But whether it exists or not, the function declaration cannot decide.
  • The declaration of a function generally appears before the use of the function. It must be declared before use.
  • Function declarations are generally placed in header files.
  • statement! = define

Example: normal writing


#include<stdio.h>
int Add(int x,int y)//该函数的位置在mian函数前面
{
	return x + y;
}
int main()
{
	int a = 0;
	int b = 0;
	scanf("%d%d",&a,&b);
	int sum = Add(a, b);
	printf("%d\n",sum);
}

Warning compilation writing:

Reason: Because the compiler reads from top to bottom, when the Add function is called, the Add function has not been encountered before, so there will be a warning, and the function will not be found until the end of the run. 

Correct approach: declare before calling the function

int Add(int x,int y);//声明函数写法

 2. Function definition

    The definition of a function refers to the specific realization of the function, explaining the function realization of the function. (function body)

Note: The definition of a function is a special kind of declaration.

Example:

int Add(int x, int y)
{
	return x + y;
}

This whole part is the definition of the function

Seven, function recursion

Preface: Function recursion is a difficult part of the function, and it uses less code to represent a huge process.

1. Let's look at the official definition;

      The programming technique in which a program calls itself is called recursion.
Recursion is widely used as an algorithm in programming languages.
A process or function has a method of calling itself directly or indirectly in its definition or description . It usually converts a large and complex problem layer by layer into a smaller-scale problem similar to the original problem to solve. The recursive strategy is only A small number of programs can be used to describe the multiple repeated calculations required in the problem-solving process, which greatly reduces the amount of code in the program.

Summary: Invoke yourself and make big things small.
 

2. Two conditions for recursion

   Because the idea of ​​recursion is to divide the big things into small things first. When the division can no longer be divided (condition 1), start to execute from the smallest thing to the big thing. If you don’t execute it once, it will be more close to this condition (condition 2)

official:

  • There are restrictions, when the restrictions are met, the recursion will not continue
  • Getting closer and closer to this limit after each recursive call

3. Example

 Question: Accept an integer value (unsigned) and print each bit of it in order.

           For example: input 1234 print result 1 2 3 4

Let's give a knowledge point first: an integer n/10=the number left after removing the single digit, such as: 1234/10=123

An integer n%10=ones digit, such as: 123%10=3

Analysis: We found that the conventional method cannot be used to print 1 2 3 4; if it is to print 4 3 2 1, you can write a loop to take the modulus (%) of 1234 for 4 consecutive times, but now the order is reversed No way.

To print 1, need 1%10=1, print 2, 12%10=2, print 3, 123%10=3, print 4, 1234%10=4

We can find that: input 1234, it needs to be divided into 1, 12, 123 and 1234 to calculate from the smaller one.

   Another way of thinking is: print 1 2 3 4 can be split into this: print (1 2 3) and 4, then print 1 2 3 can be split into print (1 2) and 3, print 1 2 can be split into print 1 and 2; 1 cannot be disassembled at this time, which is the restriction 1. Obviously, this kind of thinking is recursive thinking.

Idea map:

 Code:

#include <stdio.h>
void print(int n)
{
   if(n>9)//条件1
   {
     print(n/10);//不断调用自身
   }
   printf("%d ", n%10);//条件2
}
int main()
{
   int num = 1234;
   print(num);
   return 0;
}

Analysis: As long as the condition of n>9 is satisfied, it will be called continuously, and it will start printing until it is not satisfied.

Code illustration:

 It's obvious: recursion makes big things smaller, expressing the most complex processes with the shortest code


Function recursion is a difficult point and requires more practice. In the future, recursive content will continue to be added; sometimes recursion is too complicated and can be split into non-recursive, that is, iteration.

Guess you like

Origin blog.csdn.net/2301_77053417/article/details/131905354