C language - function (1)

Hello, we meet again. Today we are going to talk about functions. In the first introduction to C language, we talked about some basic points of functions. Now let's re-understand functions and master functions at a deeper level. Let's start our study today.

In mathematics, the functions we encounter are one-dimensional and one-dimensional, and most of them are f(x)=ax+b. What about our functions in C language? Let’s take a look Bar.
1. What is a function?

Definition of function from Wikipedia: Subroutine

  • 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 of one or more statement blocks
    . 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.

2. Classification of C language functions

  • Library Functions

Refers to the functions placed in the C language. These functions are often used by others to unify the code for everyone to use. When we use it, we only need to include the relative header file.

1. IO functions
2. String manipulation functions
3. Character manipulation functions
4. Memory manipulation functions
5. Time/date functions
6. Mathematical functions
7. Other library functions

The above are the library functions we often use. I recommend a few websites for you to check the library functions.
Website
www.cplusplus.com
http://en.cppreference.com (English version)
http://zh.cppreference.com (Chinese)

See here if you have any doubts, that is why there are library functions

To give a simple example, just like we input printf and output scanf, if we have to use code to replace them every time we want to use them, now they can be used directly in C language, greatly increasing efficiency .

insert image description here

This is part of our header files. When we want to use library functions, we must add header files. For example, our simplest #include, our input and output functions need to be used

#include<stdio.h>
int main()
{
    
    
    printf("你们真帅啊!");
	return 0;
}

Based on the above understanding, now I will teach you how to learn functions and make full use of tools
insert image description here

The above is a small tool from MSDN, you can also download and use
insert image description here
insert image description here
this is the header file that needs to be included

Seeing this, we just know what to enter in this function, but we don't know what it is used for. At this time, we can see the following notes
insert image description here
insert image description here

insert image description here

Seeing that the above is all in English, we may all have a headache, but the editor reminds everyone that poor English is not the reason for you not to type the code well. We can all look up the dictionary. Here, the editor will work hard with everyone

We can see that including the terminating null character in Remarks indicates that the inclusion of '\0' will also be passed when passing characters. We are looking at the following example

#include <string.h>
#include <stdio.h>

void main( void )
{
    
    
   char string[80];
   strcpy( string, "Hello world from " );//将Hello world from放入string,并且from后面有\0
   strcat( string, "strcpy " );
   strcat( string, "and " );
   strcat( string, "strcat!" );
   printf( "String = %s\n", string );
}
//String = Hello world from strcpy and strcat!这是输出



Speaking of this, everyone should have a little understanding of the tools we use. In the future, when you encounter functions you don’t know when reading other people’s articles, you can also look them up in this way and make good use of the tools, which will also help us in our study.

  • 2 custom functions

We saw so many header files above, which means that there are many library functions, but why there are so many functions, we have to write the functions ourselves, because we will be programmers in the future, if the library functions can meet the needs If so, there is no need for a programmer.

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

This is the composition of the function. Let’s type the code and write a function. The goal of the function is to find the larger value of the two numbers.

#include<stdio.h>
int max(int x, int y)
{
    
    
	if (x > y)
		return x;
	else
		return y;
}
int main()
{
    
    
	int a = 0;
	int b = 0;
	scanf("%d %d", &a, &b);//输入两个数
	int c = max(a, b);
	printf("%d\n", c);
	return 0;
}

This is a simple code to compare larger values. This is also mentioned in the first introduction to C language. Now let's change to a more difficult example.

swap two numbers

void swap(int x, int y)//不需要返回值用void
{
    
    
	int tmp = 0;
	tmp = x;
	x = y;
	y = tmp;

}
int main()
{
    
    
	int a=10;
	int b = 20;
	printf("交换前:a=%d b=%d\n",a,b);
	swap(a, b);
	printf("交换后:a = % d b = % d\n", a, b);
	return 0;
}

insert image description here

What's going on, we clearly wrote the exchange in the function exchange, but he still didn't exchange, why! ! !
The reason is that our program has a bug, let's explain this code in detail

insert image description here

During the debugging process, we can see the values ​​of a, b and the addresses of a and b. Then we enter the function and we
insert image description here
can find that the function values ​​are the same and during our debugging, xy is also exchanged, but at last The important point is that we can find that their addresses are different, so our exchange in the function will not affect the values ​​of a and b at all

Here we draw a conclusion. When the actual parameter is passed to the formal parameter, the formal parameter is only a temporary copy of the actual parameter, and the modification of the formal parameter will not affect the actual parameter. In the above
code, the actual parameter is the a and b of our main function, and the formal parameter is the function we call. xy

With the above ideas and debugging results, do you think of the pointers we have learned? The following is the correct code

#include<stdio.h>
void swap(int* x, int* y)//不需要返回值用void
{
    
    //接收地址用*
	int tmp = 0;
	tmp = *x;
	*x = *y;
	*y = tmp;

}
int main()
{
    
    
	int a=10;
	int b = 20;
	printf("交换前:a=%d b=%d\n",a,b);
	swap(&a, &b);
	printf("交换后:a = % d b = % d\n", a, b);
	return 0;
}

When we run the code, we pass the pointer to the function, so we exchange the content of the address, *x *y is the value of a and b, so that we can achieve the code effect

3 function parameters

  • actual parameters (actual parameters)

The parameters actually passed to the function are called actual parameters.
Actual parameters can be: constants, variables, expressions, functions, etc.
No matter what type of quantity the actual parameters are, they must have definite values ​​when the function is called, so that these values ​​can be transferred to the formal parameters.

  • Formal parameters (parameters)

Formal parameters refer to the variables in parentheses after the function name, because formal parameters are only instantiated (allocated memory units) when the function is called, so they are called formal parameters. Formal parameters are automatically destroyed when the function call completes. Therefore formal parameters are only valid within the function
.

In our code above, ab is the actual parameter, x y is the formal parameter
4 function call

  1. 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.

  1. 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.

Let's do a few exercises to consolidate our knowledge

  1. Write a function to check whether a number is prime or not.
#include<stdio.h>
#include<math.h>//sqrt要包含的头文件
int su_shu(int n)
{
    
    
	int x = 0;
	for (x = 2; x <= sqrt(n); x++)
	{
    
    
		if (n % x == 0)
		{
    
    
			return 0;
		}
	}
	return 1;
}
int main()
{
    
    
	int n = 0;
	scanf("%d", &n);
	if (su_shu(n)==1)
	{
    
    
		printf("是素数:%d\n", n);
	}
	return 0;
}

The above function is used to judge whether it is a prime number. When we enter a number, enter the function to judge whether it is a prime number. Using sqrt is equivalent to the square root of mathematics. The header file to be included is <math.h>. We Find the maximum prime number and loop to see if the result of it and the root sign can be divisible. If it is not divisible, it means that the number is a prime number. We return 1, and then return to the if statement of our main function to judge and output the prime number.

  1. Write a function to check if a year is a leap year.

insert image description here
The above is the standard for us to judge whether it is a leap year, now let's write this code

#include<stdio.h>
int run_nian(int y)
{
    
    
	if ((y % 4 == 0 && y % 100 != 0) || y % 400 == 0)
	{
    
    
		return 1;
	}
	else
		return 0;
}
int main()
{
    
    
	int year;
	scanf("%d", &year);
	if (run_nian(year) == 1)
	{
    
    
		printf("%d\n", year);
	}
	return 0;
}

In this program, we output if it is a leap year, and we don’t output it if it is not a leap year. We enter the function of leap year. When the number meets the standard of leap year, we return 1, and return 0 if it is not satisfied, which is large, so when the return value is 1 When the number is output for us, it means that this number is a leap year.

  1. Write a function to implement a binary search for an integer sorted array.
    When we see this topic, we must first know that the premise of satisfying binary search is that it is an ordered array, otherwise it cannot be used. First, let’s talk about how binary search is implemented.

insert image description here

#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)
		{
    
    
			right = mid - 1;
		}
		else if (arr[mid] < k)
		{
    
    
			left = 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);
	int sz = sizeof(arr) / sizeof(arr[0]);
	int ret = binary_search(arr, k, sz);
	if (ret == -1)
	{
    
    
		printf("找不到\n");
	}
	else
	{
    
    
		printf("找到了,下标是%d", ret);
	}
	
	return 0;
}

In this program, we pass an array to the function, the number to be searched and the number of the array, so that we also know the subscript of the function. After the function is processed, we will get our mid result. If it does not return - 1, because if it returns a positive number or 0, it may be the subscript of this number. Such a function realizes the function of binary search.

When we write binary search, we must int sz = sizeof(arr) / sizeof(arr[0]);put it in the main function. Why, if we put it in the function, the address passed is the address of the first character, which is a pointer variable, and in our compilation The device is on a 32-bit platform, that is to say, its byte size is 4, so sz is calculated to be 1. Therefore, when an array is passed as a parameter, what is passed is not the entire array, but the address of the first element. In this case, we The result is that you can find it, you can try it yourself, debug and see the result

  1. Write a function that increments the value of num by 1 each time the function is called.
//写一个函数,没调用一次,num加1
#include<stdio.h>
void test(int* p)
{
    
    
	*p = *p + 1;

}
int main()
{
    
    
	int num = 0;
	test(&num);
	printf("%d\n", num);
	test(&num);
	printf("%d\n", num);
	test(&num);
	printf("%d\n", num);
	return 0;
}

5. Nested call and chain access of functions

Functions and functions can be combined according to actual needs, that is, they call each other

  1. nested calls
#include <stdio.h>
void new_line()
{
    
    
 printf("hehe\n");
}
void three_line()
{
    
    
    int i = 0;
 for(i=0; i<3; i++)
   {
    
    
        new_line();
   }
}
int main()
{
    
    
 three_line();
 return 0;
}

When we enter the main function, we encounter three_line();and encounter void three_line()again new_line();, and then enter void new_line(), and finally execute the result, printf("hehe\n");
but we cannot nest definitions like the following code

int main()
{
    
    
 void test()
{
    
    

}
 return 0;
}

Cannot define a function inside a function

  1. chain access
#include <stdio.h>
int main()
{
    
    
    printf("%d", printf("%d", printf("%d", 43)));
    
    //注:printf函数的返回值是打印在屏幕上字符的个数
    return 0;
}

This is an example of chain access, let's analyze this code

First of all, we need to know the printf function.
insert image description here
In this figure, we can see a sentence from Remark
insert image description here
stating that the return value of the printf function is the number of characters printed on the screen. Then we can see that the result of its first print is 43 and then Because 43 is two characters, so 2 is printed, the next 2 is a character, and 1 is printed, then the result is 4321
insert image description here

Speaking of this, we basically understand some basics and usage of functions, and we will continue to understand other content of functions later. That’s all for today’s sharing, thank you! ! !

Guess you like

Origin blog.csdn.net/2301_76895050/article/details/131436685