Advanced explanation of pointer - beginners can understand it

Posted by y.t. on Thu, 20 Jan 2022 23:19:52 +0100

catalogue

πŸ‘πŸ‘1. Character pointer

πŸ‘πŸ‘Examples1

πŸ‘πŸ‘2. Pointer array

πŸ‘πŸ‘Examples2

πŸ‘πŸ‘ 3. Array pointer

πŸ‘πŸ‘3.1 definition of array pointer

πŸ‘πŸ‘3.2 & array name and array name

πŸ‘πŸ‘3.3 use of array pointer

πŸ‘πŸ‘4. Parameter transfer of array and pointer in function

πŸ‘πŸ‘4.1 parameter transfer of one-dimensional array

Β πŸ‘πŸ‘4.2 parameter transfer of two-dimensional array

πŸ‘πŸ‘4.3 parameter transmission of primary pointer

πŸ‘πŸ‘4.4 parameter transmission of secondary pointer

πŸ‘πŸ‘5. Function pointer

πŸ‘πŸ‘6. Function pointer array

πŸ‘πŸ‘Using function pointer array to realize a calculator

πŸ‘πŸ‘ 7. Callback function

Β 

preface:

This is the advanced level of pointer. If you want to get started with pointer, you can pay attention to my other article - c language pointer

If you insist on reading it, you will gain a lot~~

Then set sail

1. Character pointer

We now know that integer pointers, floating-point pointers, character pointers and both types

Character pointer - as the name suggests, it is a pointer, a pointer of type char *

πŸ“ƒ Before I talk about character pointers, let me mention how to create multiple pointers in succession

How to create multiple pointers consecutively:

You might think of using:

int a ,bοΌ›

int* a,b;

perhaps

#define PINT int*

int main(){

int a ,bοΌ›

p a,b;

}

But in fact, the result of this creation is:

Create an integer pointer int*a and an integer variable int b

Create the correct way to open the pointer:

//Scheme 1: directly define twice
int a,b;
int*aοΌ› int*bοΌ›
//Scheme 2 uses typedef redefinition
typedef int* pint
{
	int a,b;
pint pa, pb;//At this point, it is defined that int *pa and int *pb are pointer variables
return 0οΌ›
}

Here is a simple code:

char ch='w';
char* p=ch;
char* p="abcde";

Define a variable ch of char type and put the ch address in the pointer variable p

At this time, p stores the address of character w

This is easy to understand, so what does char* p="abcde" mean

In fact, this time p stores the address of the first element of the string abcde, that is, the address of a

With the first address, it is easy to find the address of subsequent elements

πŸ”’ Examples

    Determine whether the following codes are equal
    char arr1[] = "abcdef";
Β Β  Β char arr2[] = "abcdef";

Β Β  Β const char* str1 = "abcdef";
Β Β  Β const char* str2 = "abcdef";
#include<stdio. h> / / prove equivalence
int main()
{
	char arr1[] = "abcdef";
	char arr2[] = "abcdef";
	const char* str1 = "abcdef";
	const char* str2 = "abcdef";
	if (arr1 == arr2)
		printf("arr1==arr2\n");
	else
		printf("arr1!=arr2\n");
	if (str1 == str2)
		printf("str1==str2\n");
	else
		printf("str1!=str2\n");

	return 0;
}

Why Arr1= arr2οΌ› str1==str2

First create arrays, arr1 and arr2. First apply to the system for two different spaces, and then put abcdef into two different spaces, so the addresses of the two spaces are of course different

Secondly, the abcdef of str1 and str2 are only stored in the read-only storage area (this has nothing to do with const. Const plays an emphasis role. In fact, whether there is const or not means the same), that is, the elements cannot be changed;

At this time, the contents of the two strings are the same, and the system will not waste excess space to store two different contents~

So str1==str2 is formed. In fact, these two variables store the address of a

2. Pointer array

Before that, we know integer arrays, floating-point arrays and so on

An array that stores integer and floating-point numbers

Pointer array is an array that stores pointers. In fact, it is an array that stores different types of pointers

int*arr[5];//Integer pointer array
char*arr[5];//First level character pointer array
char**arr[5];//Secondary character pointer array

Know the definition, how to use it

Examples

Multiple groups of print strings

#include<stdio.h>
int main()//Pointer array
{
	char* arr[] = { "abcdef","ghi" ,"jklmn" };
	//Print
	int i = 0;
	int sz = sizeof (arr) / sizeof (arr[0]);
	for (i = 0; i < sz; i++)
	{
		printf("%s\n",arr[i]);
	}
	return 0;
}

Among them, {char * arr [] = {"ABCDEF", "GHI", "jklmn"} is the pointer array, which stores the pointer of char type,

His role is equivalent to:

char arr1[] = "abcdef";
char arr2[] = "ghi";
char arr3[] = "jklmn";

The result of printing is:

✨✨ Print shaped array

#include<stdio.h>
int main()
{
	//Print shaping number
	int arr1[] = { 1, 2, 3, 4, 5};
	int arr2[] = { 2, 3, 4, 5, 6};
	int arr3[] = { 3, 4, 5, 6, 7};
	int* arr[] = { arr1,arr2,arr3 };
	int i = 0; int j = 0;
	for (i = 0; i < 3; i++)
	{
		for (j = 0; j < 5; j++)
		{
			printf("%d", arr[i][j]);
		}
		printf("\n");
	}
	return 0;
}

 3. Array pointer

3.1 definition of array pointer

With the concept of pointer array, I believe many people know the concept of array pointer

Just like you think

Array pointer - it's a pointer. What pointer is it? The pointer that stores the array

int *pint;//A pointer that can point to shaped data
char *p;//A pointer that can point to character data
char (*p)[10];A pointer that can point to an array

Its types include int(*) [], char(*) []

To interpret, (*) represents a pointer, [] represents an array pointer, and char or int represents the type of elements in the array

🦴 Then int * p1[10] and int (*) p2[10]

What does p1 p2 mean

The former is an array (pointer array) variable

The latter is a pointer (array pointer) variable

3.2 & array name and array name

We know that the array name is the address of the first element (except that the array name is directly connected with sizeof and & array name)

So & what does an array name mean

In fact & the array name is the address of the entire array

#include<stdio.h>
int main()
{
	int arr[20] = { 0 };
	printf("%p\n", arr);
	printf("%p\n", arr+1);
	printf("%p\n", &arr);
	printf("%p\n", &arr+1);
	return 0;
}

It is easy to see in the printed results

Arr and arr+1 are separated by four bytes, which is an integer size

There are 80 bytes between & arr and & arr + 1, which is the size of 20 integers

πŸ“ƒ Next, let's look at a code

int *p[10];
int *(*pp)[10];

In this case, int *p[10], p is the pointer array variable

int *(*pp)[10] this sentence means to define a pointer variable. What pointer? Array pointer, and the elements in this array are int *, with ten int * type data. This is the array pointer~~

Therefore, in general, arr is the address of the first element of the array, and & arr is the address of the whole array

3.3 use of array pointer

Having finished the definition and use rules of array pointers, the following explains the use of array pointers

Given three arrays, print out their values respectively

#include<stdio.h>
print(int (*p)[5],int r,int c)//In this case, int (*p)[5] is an array pointer
{
	int i = 0; int j = 0;
	for(i=0;i<r;i++)
	{
		for(j=0;j<c;j++)
		{
			printf("%d", *(*(p+i) + j)); //*(p+i) is equivalent to getting the address on the first line
		}
	printf("\n");
	}

}
int main()
{
	//Print numbers
	int arr[3][5] = { {1,2,3,4,5},{2,3,4,5,6},{3,4,5,6,7} };
	print(arr,3,5);
	return 0;
}

Printed results:

This problem uses a two-dimensional array

Here, I regard a two-dimensional array as a one-dimensional array, that is, a row as an element

So this number has three elements

Even if the array name of a two-dimensional array is the address of the first line

Of course, the idea of array pointer can also be used in one-dimensional array, but it is not needed in fact. Instead, it becomes troublesome and can be well used in two-dimensional array.

Here's a summary:

int *arr;
int *parr1[10];
int (*parr2)[10];
int(*parr3[10])[10]

int *arr

Is a pointer of type int *;

int *parr1[10]

Is an array of type int * [], and is an array of pointers

int (*parr2)[10]

Is a pointer, the type of pointer is int (*) [], and is a pointer array with ten integer elements

int(*parr3[10])[10]

Is an array. At this time, remove parr3 to get nt (*) []. Here is an array pointer, so this is an array with ten array pointers.

4. Transfer parameters of array and pointer in function

The premise of function parameter transfer is that the formal parameter and the argument are corresponding, that is, what type the argument is, then the formal parameter is also the corresponding type. For example, if the argument is an array, then the formal parameter is an array, and the parameter is a pointer, then the formal parameter is also a pointer.

4.1 parameter transfer of one-dimensional array

#include<stdio.h>
test(arr1[])
{}
test(arr1[10])//In the above two methods, the argument is an array and is received by an array. Since no space is created in the function itself, the purpose can be achieved regardless of the value in [] {} / /~

test(*arr1)
{}          //I mentioned earlier that the array name is the address of the first element. At this time, the array name in the argument is regarded as the address of the first element 
            //Pin to receive

test(*arr2[10])
{}          //This is also the same as the first two. It is also an array to pass parameters and an array to receive

test(**arr2)
{}          //Here, the second level pointer is used to receive, and the argument is the first level pointer, so the pointer of the first level pointer can be received with the second level pointer
int main()
{
int arr1[10]={0};
int* arr2[10]={0};
test(arr1);
test(arr2);
return 0;
}

4.2 parameter transfer of two-dimensional array

#include<stdio.h>
//Through array
test(int arr[10][10])      //When the secondary pointer transfers parameters, it is in the form of an array. The rows in [] can be omitted, but the columns cannot be omitted
{}                         //Columns can let the system know how many elements there are in a row, so as to allocate how much space, so as to know each element 
                           //So test(int arr[10][10]) and test(int arr[][10]) are possible 
                           //Pass parameters, but test(int arr [] []) is obviously not allowed.
test(int arr[][])
{}
test(int arr[][10])
{}
//Through pointer
test(int *arr)
{}
test(int (*arr)[10])      //We know that the argument passes the address of the first element, and the address of the first element here is the address of the first line element 
{}                        //Address, that is, the address of the array, so you need an array pointer to receive it
                          //Therefore, test(int (*arr)[10]) is required to receive, and the primary pointer and the secondary pointer are obviously unavailable 

test(int** arr)
{}
int main()//Secondary pointer transfer parameter
{
	int arr[10][10] = { 0 };
	test(arr);
	return 0;
}

4.3 parameter transmission of primary pointer

#include<stdio.h>
test(int *p)
{}
int main()
{
	int a = 10;
	int* par = &a;
	int arr[10];

	test(par);
	test(arr);
	test(*a);      //When the first level pointer passes parameters, the formal parameter is a pointer, so the argument can pass parameters in these three ways

	return 0;
}

4.4 parameter transmission of secondary pointer

#include<stdio. h> / / when a second-level pointer passes a parameter, the formal parameter is a second-level pointer. What are the methods of the argument
test(int** p)
{}
int main()
{
	//Secondary pointer transfer parameter
	char a = 'w';
	char* p = &a;
	char** pp = &p;
	char* arr[10] = { 0 };

	test(&p);        //Get the address through the first level pointer p
	test(pp);        //Parameters are transmitted through the secondary pointer and received with the secondary pointer
	test(arr);       //Passed by char * () type pointer array name

	return 0;
}

5. Function pointer

The array pointer is the address of the array

Then the function pointer also stores the function address

πŸ“Œ The question is, do functions have pointers

#include<stdio.h>
int Add(int x,int y)
{
	int sum = 0;
	sum = x + y;
}
int main()
{
	//Prove that the function has an address
	int a = 0;
	int b = 0;
	printf("%p", &Add);
    printf("%p\n", Add);
//Define a function pointer variable
    int (*pf)(int,int)=&Add;  //At this time, pf is the pointer variable of the function. You can call the function with pf
	return 0;                 //In parentheses are the types of parameters
}

This code proves that the function also has an address, and the function of taking the address plus the function name is the same as the function name. Since the function has an address, you can call the function through the pointer

Call this function:

#include<stdio.h>
int  Add(int x,int y)
{
	int sum = 0;
	sum = x + y;
	return sum;
}
int main()
{
	int (*pf)(int,int) = &Add;
	int ret1=(*pf)(2, 3); //Don't forget
	int ret2 = (pf)(2, 3);//The brackets here can be omitted
	printf("%d\n", ret1);
	printf("%d\n", ret2);

	return 0;
}

Printed results:

It can be seen that the use effect of pf and * pf in the main function is the same, and the printing result is the same, so whether there is * can achieve the same purpose, but * represents dereference, which is easy to understand~

Here is an interesting code:

void(* signal (int,void (*) (int)) )(int)

What does this code mean? Does it look a little dizzy

In fact, signal (int, void(*)(int)) is proposed, and the rest is void(*)(int), where signal is a function declaration.

First, this is a function pointer. There are two parameters. One parameter is int and the other is a function pointer. Its return value is void(*)(int), that is, a function pointer.

This function can be simplified by redefining void(*)(int) as a new variable

You might think it's typedef void(*)(int) pfun_t

This is really easy to understand. After all, it is the same as the structure we have learned

But the real result is typedef void(*pfun_t)(int), where pfun_ T in the middle, I also played an important role in learning this way.

The result of the simplification of void (* signal (int, void (*) (int)) (int) is pfun-t signal(int,void (*) (int))

pfun-t is a type name, not a type name

6. Function pointer array

We learned the integer pointer array and character pointer array. Like them, the function pointer array is also an array, but the elements in the array are integer pointers.

The function pointer array can call multiple functions at one time

#include<stdio.h>
int Add(int x, int y)
{
	return x + y;
}
int Sub(int x, int y)
{
	return x - y;
}
int Mul(int x, int y)
{
	return x * y;
}
int Div(int x, int y)
{
	return x / y;
}
int main()
{ 
    //int (*pf1)(int, int)=&Add;
    //int (*pf2)(int, int)=&Sub;
    //int (*pf3)(int, int)=&Mul;
    //int (*pf4)(int, int)=&Div;
	int (*pfAdd[4])(int, int) = { &Add ,&Sub,&Mul,&Div };//Array pointers can be well defined many times
	int i = 0;
	for (i = 0; i < 4; i++)
	{
		printf("%d\n", *(pfAdd[i])(8, 4));
	}
	return 0;
}

Through a simple array call, you can realize the operation of addition, subtraction, multiplication and division. What's the use of function pointer array

Since the function pointer array can realize addition, subtraction, multiplication and division at the same time, it can certainly implement a calculator

Using function pointer array to realize a calculator

#include<stdio.h>
int Add(int x, int y)
{
	return x + y;
}
int Sub(int x, int y)
{
	return x - y;
}
int Mul(int x, int y)
{
	return x * y;
}
int Div(int x, int y)
{
	return x / y;
}
menu()
{
	printf("*****************************************\n");
	printf("********  1.Add     2.Sub     ***********\n");
	printf("********  3.Mul     4.Div     ***********\n");
	printf("********  0.exit              ***********\n");
	printf("*****************************************\n");

}
int main()//Use function pointers to implement a calculator
{
	int x = 0;
	int y = 0;
	int input = 0;
	int ret = 0;
	int (*pfArr[5])(int, int) = { 0, &Add ,& Sub,& Mul,& Div };
	do
	{
		menu();
		printf("Please select:>");
		scanf_s("%d", &input);
		if (input == 0)
		{
			printf("Computer to shut down");
		}
		else if (input >= 1 && input <= 4)
		{
			printf("Please enter x And y:>");
			scanf_s("%d %d", &x, &y);
			ret = pfArr[input](x, y);
			printf("%d\n", ret);
		}
		else
			printf("Selection error");
	} while (input);
	return 0;
}

 7. Callback function

πŸ“ŒπŸ“Œ A callback function is a function called through a function pointer. If the pointer (address) of a function is used as a parameter and passed to another function, when the function calls the function referred to, we say it is a callback function.

Next, use the callback function to implement the calculator implemented last time with the function pointer array

#include<stdio.h>
int Add(int x, int y)
{
	return x + y;
}
int Sub(int x, int y)
{
	return x - y;
}
int Mul(int x, int y)
{
	return x * y;
}
int Div(int x, int y)
{
	return x / y;
}
menu()
{
	printf("*****************************************\n");
	printf("********  1.Add     2.Sub     ***********\n");
	printf("********  3.Mul     4.Div     ***********\n");
	printf("********  0.exit              ***********\n");
	printf("*****************************************\n");
}
void calc(int (*pf)(int, int))
{
	int x = 0; int y = 0;
	printf("Please enter two numbers:>");
	scanf_s("%d %d", &x, &y);
	int ret = pf( x, y);
	printf("%d\n", ret);
}
int main()
{ 
	int input = 0;
	do
	{
		printf("Please select:\n");
		menu();
 		scanf_s("%d", &input);
		switch(input)
		{
		case 1:
				calc(Add);
				break;      
		case 2:
				calc(Sub);
				break;
		case 3:
				calc(Mul);
				break;
		case 4:
				calc(Div);
				break;
		case 0:
			printf("Exit calculator");
			break;
		default:
			printf("Selection error");
			break;
		}
	} while (input);
	return 0;
}

The callback function well omits the repeated code process inside the case. At this time, the pointer of the addition, subtraction, multiplication and division function is passed into the calc function as a parameter, which is the callback function.

Conclusion: in this chapter, the pointer related knowledge of c language is over

You are welcome to like the collection and pay more attention. If you have any questions, you can raise them 😁😁😁😁

Topics: C