C language--Advanced pointers

We have already touched on the topic of pointers in the "Pointers" chapter at the primary stage. We know the concept of pointers:
1. A pointer is a variable, used to store addresses. The address uniquely identifies a memory space.
2. The size of the finger is fixed 4/8 Special value ( Iheidai). /64Iheidai 32
3. Pointers have types, and the type of the pointer determines the pointer's +- integer Step size, permission during pointer dereference operation.
4. Pointer operations.
5. Memory units are numbered, number == address == pointer

Next we will learn more advanced content about pointers.

Table of contents

 1. Character pointer

2. Pointer array  

 3. Array pointer

3.1 Definition of array pointer

3.2 &Array name VS array name

 3.3 Use of array pointers

 4. Array parameters, pointer parameters

 4.1 One-dimensional array parameter transfer

4.3 First-level pointer parameter passing

 4.4 Second-level pointer parameter passing

5. Function pointer

Read two interesting pieces of code:


 1. character fingertip

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

General use :
int main()
{
    char ch = 'w';
    char *pc = &ch;
    *pc = 'w';
    return 0;
}
Another way to use it is as follows:
int main()
{
    const char* pstr = "abcdef";//这里是把一个字符串放到pstr指针变量里了吗?
    printf("%s\n", pstr);
    return 0;
}
代码 const char* pstr = "abcdef" ;
is particularly easy for us to think that the string abcdef is placed in the character pointer pstr , but / The essence is to put the address of the first character of the string abcdef into pstr.  
The above code means to store the address of the first character of a constant string h into the pointer variable pstr .
Then there are interview questions like this:

#include <stdio.h>
int main()
{
	char str1[] = "hello bit.";
	char str2[] = "hello bit.";
	const char* str3 = "hello bit.";
	const char* str4 = "hello bit.";
	if (str1 == str2)
		printf("str1 and str2 are same\n");
	else
		printf("str1 and str2 are not same\n");

	if (str3 == str4)
		printf("str3 and str4 are same\n");
	else
		printf("str3 and str4 are not same\n");

	return 0;
}
The final output here is:

Here str3 and str4 point to a < /span> are different. str4 andstr3 are different, str2 and So str1 initialize different arrays, different memory blocks will be allocated. But when you use the same constant string to When several pointers point to the same When they are a string, they will actually point to the same memory. will store the constant string in a separate memory area. C/C++. The same constant string
As shown in the picture:

2. Finger combination  

An array of pointers is an array in which each element is a pointer. Each pointer can point to different types of data or objects.

Like the following form:

int* arr1[10]; //整形指针的数组
char *arr2[4]; //一级字符指针的数组
char **arr3[5];//二级字符指针的数组

 You can use an array of pointers to simulate a two-dimensional array:

int main()
{
	int arr1[] = { 1,2,3,4,5 };
	int arr2[] = { 2,3,4,5,6 };
	int arr3[] = { 3,4,5,6,7 };
	        //int*  int*  int*
	//指针数组
	int* arr[] = { arr1, arr2, arr3 };
	int i = 0;

	return 0;
}

Int* arr[] stores three elements arr1, arr2, and arr3, and the type of each element is int*.

Of course, this way of writing can be accessed like a two-dimensional array:

 You can also maintain multiple strings this way:

int main()
{
	//指针数组
	char* arr[5] = {"hello", "hehe", "haha", "heihei", "C"};

	int i = 0;
	for (i = 0; i < 5; i++)
	{
		printf("%s\n", arr[i]);
	}

	return 0;
}

Running results and illustrations:

 3. Number of fingers

3.1 Definition of array pointer

Are array pointers pointers? Or an array?
The answer is: pointers.
We are already familiar with:
Integer pointer: int * pint ; A pointer that can point to integer data.
Floating point pointer: float * pf ; A pointer that can point to floating point data.
The array pointer should be: a pointer that can point to the array.

 Which of the following codes is an array pointer?

int *p1[10];
int (*p2)[10];
//p1, p2分别是什么?
explain:
int ( * p )[ 10 ];
Explanation: p is first combined with *, indicating that p is a pointer variable, and then points to an array of 10 integers. 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.

3.2 &number group nameVSnumber group name

For the following array:
int arr[10];
arr sum &arr separation is it?
We know that arr is the array name, and the array name represents the address of the first element of the array.
Then &arr What is the name of the array?

 Let's look at a piece of code:

#include <stdio.h>
int main()
{
    int arr[10] = {0};
    printf("%p\n", arr);
    printf("%p\n", &arr);
    return 0;
}
The running results are as follows:

The visible array name and the address printed by the & array name are the same.
Are the two the same?
Let’s look at another piece of code:
#include <stdio.h>
int main()
{
 int arr[10] = { 0 };
 printf("arr = %p\n", arr);
 printf("&arr= %p\n", &arr);
 printf("arr+1 = %p\n", arr+1);
 printf("&arr+1= %p\n", &arr+1);
 return 0;
}

According to the above code, we found that, in fact, &arr and arr< a i=4>, although the value is the same, the meaning should be different.
Actually: &arr represents the address of the array , rather than the address of the first element of the array. (Experience it carefully)
In this example &arr the type is: int(*)[10] < /span> , is an array pointer type
The address of the array +1 , skipping the entire array size, so &arr+ The difference between 1 and &arr is 40. a>

 3.3 ​​Use of array pointers

How are array pointers used?
Since the array pointer points to an array, the address of the array should be stored in the array pointer.
Look at the code:
int main()
{

	int arr[10] = { 0 };
	int (*p)[10] = &arr; //p是用来存放数组的地址的,p就是数组指针
	
	char* arr2[5];
	char* (*pc)[5] = &arr2;//pc是用来存放数组的地址的,每个数组的类型为char*
	int (*p)[10] = &arr;

	int arr3[] = { 1,2,3 };
	int (*p3)[3] = &arr3;

	return 0;
}

In the above code, why not just use int (*p)[10] =arr;?
This is because although the values ​​​​of arr and &arr are the same, their meanings are different:
*** arr refers to It is the first address of the  first element of this array.
*** &arr refers to the first address of this entire array .

Array pointers are used in two-dimensional arrays:
void print(int (*p)[5], int r, int c)
{
	int i = 0;
	for (i = 0; i < 3; i++)
	{
		int j = 0;
		for (j = 0; j < 5; j++)
		{
			printf("%d ", p[i][j]);
		}
		printf("\n");
	}
}

int main()
{
	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;
}
The array name arr represents the address of the first element
But the first element of the two-dimensional array is the first row of the two-dimensional array
So the arr passed here is actually equivalent to the address of the first line, which is the address of the one-dimensional array
can array pointer be received
After learning about pointer arrays and array pointers, let’s review them together and see what the following code means:
int arr[5];
int *parr1[10];
int (*parr2)[10];
int (*parr3[10])[5];

explain:

 

 4. Array parameters, pointer parameters

When writing code, it is inevitable to pass [array] or [pointer] to a function. How should the parameters of the function be designed?

 4.1 One-dimensional array parameter passing

#include <stdio.h>
void test(int arr[])//ok?
{}
void test(int arr[10])//ok?
{}
void test(int* arr)//ok?
{}
void test2(int* arr[20])//ok?
{}
void test2(int** arr)//ok?
{}

int main()
{
 int arr[10] = {0};
 int* arr2[20] = { 0 };
 test(arr);
 test2(arr2);
}

The above writing methods are all OK.

Numeric parameters and formal parameters can be written in array form.

The essence of array parameter passing is to pass the address of the first element of the array.

Array parameters can also be passed in the form of pointers

 4.2 Two-dimensional number combination

void test(int arr[3][5])//ok?
{}
void test(int arr[][])//ok?
{}
void test(int arr[][5])//ok?
{}
//总结:二维数组传参,函数形参的设计只能省略第一个[]的数字。
//因为对一个二维数组,可以不知道有多少行,但是必须知道一行多少元素。
//这样才方便运算。
void test(int *arr)//ok?  这是接收一维数组的写法
{}
void test(int* arr[5])//ok?这是指针数组,也不行
{}
void test(int (*arr)[5])//ok?这才是对的,用数组指针
{}
void test(int **arr)//ok?二级指针是用来接收一级指针的,所以也不行
{}
int main()
{
 int arr[3][5] = {0};
 test(arr);
}

4.3 First-level pointer parameter passing

#include <stdio.h>
void print(int* p, int sz)
{
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%d\n", *(p + i));
	}
}
int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9 };
	int* p = arr;
	int sz = sizeof(arr) / sizeof(arr[0]);
	//一级指针p,传给函数
	print(p, sz);
	return 0;
}

Use a first-level pointer to pass parameters, and use a first-level pointer to receive formal parameters.

think:
When the parameter part of a function is a first-level pointer, what parameters can the function receive?

 4.4 Second-level pointer parameter passing

#include <stdio.h>
void test(int** ptr)
{
	printf("num = %d\n", **ptr);
}
int main()
{
	int n = 10;
	int* p = &n;
	int** pp = &p;
	test(pp);
	test(&p);
	return 0;
}

Secondary pointers are used to pass parameters, and formal parameters can be received using secondary pointers.

think:
When the parameter of a function is a secondary pointer, what parameters can it receive?

5. Function indicator

 First of all, it is a pointer, a pointer to a function, and the address of the function is stored in the memory space;

 Let’s look at the code first:

#include <stdio.h>
void test()
{
	printf("hehe\n");
}
int main()
{
	printf("%p\n", test);
	printf("%p\n", &test);
	return 0;
}
Output result:

Here we know,&The function name is the address of the function, and the function name is also the address of the function.  

 The output is two addresses, which are the addresses of the test function.

So if we want to save the address of our function, how do we save it?
Let's look at the code below:
void test()
{
    printf("hehe\n");
}
//下面pfun1和pfun2哪个有能力存放test函数的地址?
void (*pfun1)();
void *pfun2();
First of all, if you can give the storage address, you need pfun1 or pfun2 is a pointer, so which one is the pointer?
the answer is:
  pfun1 can be stored. pfun1 is first combined with *, indicating that pfun1 is a pointer. The pointer points to a function. The pointed function has no parameters and the return value type is void. 

 Let’s set up an example: simple summation

int Add(int x, int y)
{
	return x + y;
}
int main()
{
	int (* pf2)(int, int) = &Add;
	int ret = (* pf2)(2, 3);
	printf("%d\n", ret);

	return 0;
}

 operation result:

 As a function pointer, pf2 is also an address, and the function itself is also an address, so the * in (* pf2) in int ret = (* pf2)(2, 3) can naturally be omitted. int ret = pf2(2, 3) is also possible.

Read two interesting pieces of code:

//代码1
(*(void (*)())0)();
//代码2
void (*signal(int , void(*)(int)))(int);

Code 1: void(*)() is a function pointer type, *(void (*)())0 is forced type conversion 0, and 0 is regarded as the function address, then there is void(*)() at the 0 address Such a function, so the meaning of this code is: call the function at address 0. This function has no parameters and the return type is void.

Code 2:

 Code2 is too complex, how to simplify it:

typedef void(*pfun_t)(int);
pfun_t signal(int, pfun_t);

Typedef it.

Guess you like

Origin blog.csdn.net/2301_76618602/article/details/132207177