In-depth understanding of pointers 3

Tip: After the article is written, the table of contents can be automatically generated. For how to generate it, please refer to the help document on the right.


Preface

世上有两种耀眼的光芒,一种是正在升起的太阳,一种是正在努力学习编程的你!一个爱学编程的人。各位看官,我衷心的希望这篇博客能对你们有所帮助,同时也希望各位看官能对我的文章给与点评,希望我们能够携手共同促进进步,在编程的道路上越走越远!

想回顾上一节的请点击这里深入理解指针2


提示:以下是本篇文章正文内容,下面案例可供参考

1. Character pointer variable

Among the types of pointers, we know that there is a pointer type called character pointer char*;

Let’s go directly to the code demonstration:

The code const char* p = "abcdefjhi"; is particularly easy for students to think that the string abcdefghi is placed in the character pointer p, but the essence is to put the string abcdefghi  The address of the first character is placed in p.

"Sword Pointer Offer" contains a written test question related to strings. Let's study it together:

Here str3 and str4 point to the same constant string. C/C++ will store constant strings in a separate memory area. When several pointers point to the same string, they will actually point to the same memory. But when using the same constant string to initialize different arrays, different memory blocks will be opened up. So str1 and str2 are different, str3 and str4 are the same.

2. Array pointer variable

2.1 What is an array pointer variable?

We learned about pointer arrays before.A pointer array is a type of array, and the array stores addresses (pointers).

Are array pointer variables pointer variables? Or an array?

Answer:Finger change amount.

Character pointer - a pointer to a character, which stores the address of the character char ch='w';char*pc=&ch
Integer pointer -A pointer to an integer type, which stores the address of the integer type int a=10;int* p=&a

Array pointer - a pointer to an array, which stores the address of the array int arr[10];int(*p)[10]=&arr
(*p) It is a pointer, which points to an array. There are 10 elements in the array. The corresponding type of each element is int

Pointer array - an array that stores pointers, int* p[10]; indicating that p[10] is an array, and the type of each element in the array is int*

We are already familiar with:

• Integer pointer variable: int * pint; stores the address of the integer variable a>, a pointer that can point to integer data.

• Floating-point pointer variable: float * pf; stores the address of the floating-point variable , a pointer that can point to floating-point data.

The array pointer variable should be:The address of the array should be stored, a pointer variable that can point to the array.

Code demo:

Explanation:p is first combined with *, indicating that p is a pointer variable, and then points to an integer of size 10 type array. So p is a pointer, pointing to an array, called an array pointer.

Note here:[] has a higher priority than *, so () must be added to ensure that p is combined with * first.

2.2 How to initialize array pointer variables

The array pointer variable is used to store the array address, so how to get the address of the array? This is the &array name we learned before.

int arr[10] = {0};

&arr;//What you get is the address of the array

If you want to store the address of an array, it must be stored inarray pointer variable, as follows:

int(*p)[10] = &arr;

We can also see during debugging that the types of &arr and p are exactly the same.

Array pointer type analysis:

int (*p) [10] = &arr;
 |    |   |
 |    |   |
 |    |   p指向数组的元素个数
 |    p是数组指针变量名
 p指向的数组的元素类型

Let's access each element of the array:

3. The essence of passing parameters through two-dimensional arrays

With the understanding of array pointers, we can talk about the essence of passing parameters in two-dimensional arrays. In the past, when we had a two-dimensional array and needed to pass parameters to a function, we wrote it like this:

The actual parameter here is a two-dimensional array, and the formal parameter is also written in the form of a two-dimensional array. Is there any other way to write it?

First of all, let’s understand the two-dimensional array again. The beginning of the two-dimensional array can be regarded as an array in which each element is a one-dimensional array, that is, Each element of the two-dimensional array The elements are a one-dimensional array. Thenthe first element of the two-dimensional array is the first row, which is a one-dimensional array.

As shown below:

arr array
0 1 2 3 4
0 1 2 3 4 5
1 2 3 4 5 6
2 3 4 5 6 7

So, according to the rule that the array name is the address of the first element of the array,The array name of the two-dimensional array represents the address of the first row, which is the address of the one-dimensional array< /span>, then the formal parameters can also be written in pointer form. As follows: is passing the first line. The address of a one-dimensional array, the two-dimensional array parameter is essentially passing the address . That means that is the first The type of the row address is the array pointer type int(*)[5], so is int [5] . According to the above example, the type of the one-dimensional array in the first row of

Summary:Two-dimensional array parameters are passed. The formal parameter part can be written as an array or in pointer form.

4. Function pointer variable

4.1 Creation of function pointer variables

What is a function pointer variable?

Based on our analogy when we studied integer pointers and array pointers earlier, it is not difficult for us to draw the conclusion: Function pointer variables should be used to store function addresses. In the future The function can be called through the address.

So does the function have an address?

Let’s do a test:

The address is indeed printed, so the function has an address.The function name is the address of the function. Of course, the address of the function can also be obtained by &function name a>.

If we want to store the address of the function, we have to create a function pointer variable. The writing method of the function pointer variable is actually very similar to the array pointer. as follows:

Function pointer type analysis:

int (*pf3) (int x, int y)
 |            ------------ 
 |    |         |
 |    |         pf3指向函数的参数类型和个数的交代
 |    函数指针变量名
 pf3指向函数的返回类型
int (*) (int x, int y) //pf3函数指针变量的类型

4.2 Use of function pointer variables

Call the function pointed to by the function pointer.

#include <stdio.h>
int Add(int x, int y)
{
 return x+y;
}
int main()
{
 int(*pf3)(int, int) = Add;
 
 printf("%d\n", (*pf3)(2, 3));
 printf("%d\n", pf3(3, 5));
 return 0;
}

Output result:

5

8

4.3 Two interesting pieces of code

Code 1

1  (*(void (*)())0)();

Code 2

1  void (*signal(int , void(*)(int)))(int);

Both pieces of code come from the book "C Pitfalls and Pitfalls"

4.3.1 typedef keyword

typedef is used to rename types, which can simplify complex types.

For example, if you think unsigned int is inconvenient to write, it would be much more convenient if it could be written as uint, then we can use:

typedef unsigned int uint;
//将unsigned int 重命名为uint

If it is a pointer type, can it be renamed? In fact, it is also possible. For example, rename int* to ptr_t and write like this:

typedef int* ptr_t;

But forarray pointer and function pointer it is a little bit Difference:

For example, we have array pointer type int(*)[5] and need to rename it to parr_t, then we can write it like this:

typedef int(*parr_t)[5]; //The new type name must be on the right side of *

The renaming of function pointer types is the same. For example, if you rename the void(*)(int) type to pf_t, you can write like this:

typedef void(*pfun_t)(int);//The new type name must be on the right side of *

Then to simplify code 2 (void (*signal(int , void(*)(int)))(int);), you can write it like this:

5. Array of function pointers

An array is a storage space that stores data of the same type. We have already learned about pointer arrays

for example:

int *arr[10]; //Each element of the array is int*

Then the address of the function must be stored in an array. Then this array is calledArray of function pointers. What about the array of function pointers? What about the definition?

Parr4 is first combined with [] to indicate that parr4 is an array. What is the content of the array? Is a function pointer of type int (*)().

6. Transfer table

Purpose of function pointer array:Transfer table

Example: General implementation of calculator:

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;
}

void menu()
{
	printf("****************************\n");
	printf("******  1.Add 2.Sub  *******\n");
	printf("******  3.mul 4.div  *******\n");
	printf("******  0.exit     *********\n");
	printf("****************************\n");

}
int main()
{
	int input = 0;
	int x = 0;
	int y = 0;
	int ret = 0;
	do
	{
		menu();
		printf("请选择:>\n");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			printf("请输入2个操作数:>");
			scanf("%d %d", &x, &y);
			ret = Add(x, y);
			printf("%d\n", ret);
			break;
		case 2:
			printf("请输入2个操作数:>");
			scanf("%d %d", &x, &y);
			ret = Sub(x, y);
			printf("%d\n", ret);
			break;
		case 3:
			printf("请输入2个操作数:>");
			scanf("%d %d", &x, &y);
			ret = Mul(x, y);
			printf("%d\n", ret);
			break;
		case 4:
			printf("请输入2个操作数:>");
			scanf("%d %d", &x, &y);
			ret = Div(x, y);
			printf("%d\n", ret);
			break;
		case 0:
			printf("退出计算器\n");
			break;
		default:
			printf("选择错误,重新选择\n");
			break;
		}
	} while (input);
	return 0;
}

Implementation using array of function pointers:

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;
}

void menu()
{
	printf("****************************\n");
	printf("******  1.Add 2.Sub  *******\n");
	printf("******  3.mul 4.div  *******\n");
	printf("******  0.exit     *********\n");
	printf("****************************\n");

}
int main()
{
	//函数指针的数组
	//通过数组下标找到对应的元素调用函数,称为转移表
	int(*pArr[])(int, int) = { 0,Add,Sub,Mul,Div };
	//因为函数的参数类型和函数的返回类型都一样,所以可以放到同一个数组中去
	int input = 0;
	int x = 0;
	int y = 0;
	int ret = 0;
	do
	{
		menu();
		printf("请选择:>\n");
		scanf("%d", &input);
		if (input <= 4 && input >= 1)
		{
			printf("请输入2个操作数:>");
			scanf("%d %d", &x, &y);
			ret = pArr[input](x, y);//通过下标找到数组对应的元素,元素是函数的地址,可以通过地址调用函数
			printf("%d\n", ret);
		}
		else if (input = 0)
		{
			printf("退出游戏\n");
		}
		else
		{
			printf("选择错误,重新选择\n");
		}
	} while (input);
	return 0;
}

Summarize

Okay, this blog ends here. If you have a better point of view, please leave a message in time. I will watch it carefully and learn from it.
If you don’t accumulate steps, you can’t reach a thousand miles; if you don’t accumulate small streams, you can’t become a river or sea.

Guess you like

Origin blog.csdn.net/2301_79585944/article/details/134101201