当前位置:网站首页>The bamboo shadow sweeps the steps, the dust does not move, and the moon passes through the marsh without trace -- in-depth understanding of the pointer
The bamboo shadow sweeps the steps, the dust does not move, and the moon passes through the marsh without trace -- in-depth understanding of the pointer
2022-07-04 10:25:00 【sqjddb】
Understand pointer from many aspects
- >> Explain the size of pointer variables
- >> Wild pointer problem
- >> The relational operation of pointers
- >> Pointer arrays and array pointers
- >> Explanation of array pointer usage
- >> Array parameter passing and pointer parameter passing
- >> A function pointer
- >> Callback function
- >> Pointer related classic topics
>> Explain the size of pointer variables
A pointer is a variable , The address where the memory unit is stored ( Number ), The size of a pointer variable can be understood in this way
Here you are 2 Of 32 The next address
stay 32 On the machine , The address is 32 individual 0 perhaps 1 Make up a binary sequence , Then the address has to be 4 Bytes of space to store , the
With a pointer, the size of the variable should be 4 Bytes .
Well, if it's in 64 On the bit machine , If there is 64 Root address line , The size of that pointer variable is 8 Bytes
>> Wild pointer problem
The position of the pointer is unknown ( Random 、 incorrect 、 There is no definite limit to )
To dereference is to access an uncertain address , So the result is unknowable .
origin :
① Pointer variable not initialized
② Pointer operation goes beyond variable scope
③ After the space pointed to by the pointer is released , The pointer is not null , This involves Dynamic memory development
Ways to avoid wild pointer problems :
① Pointer initialization
② Watch out for cross-border visits
③ After the space pointed to by the pointer is released , Null pointer
④ Check the validity before using the pointer
>> The relational operation of pointers
Can pointers compare sizes ?
The standard stipulates :
Allow pointers to array elements and Pointer to the memory location after the last element of the array Compare , But... Is not allowed
And Pointer to the memory location before the first element Compare .
>> Pointer arrays and array pointers
Pointer array is an array of pointers
int* arr3[5];
arr3 Is an array , There are five elements , Each element is an integer pointer
Array pointer is a pointer to an array
int (*p)[10];
p The first and * combination , explain p Is a pointer variable , It points to a size of 10 An array of integers
p It's a pointer , Point to an array , It's called array pointer
[ ] Priority is higher than * The no. , So we have to add () To guarantee p The first and * combination .
int (*parr[10])[5];
Is the above code an array or a pointer ? It's an array
paar The first and [ ] combination , Is an array of ten elements , What types of elements are stored in the array ?
Define an array , Removing the array name is the element type it stores , Such as int a[9], Get rid of a[9], be left over int
Remove the above example parr[10], be left over int (*) [5], The type represented is array pointer . To sum up, this is an array storing array pointers
>> Explanation of array pointer usage
The array pointer points to the entire array , The array name can represent the address of the first element of the array , The address of the whole array can be & The array name indicates
int arr[10] = { 0 };
&arr and arr, Although the values are the same , But the meaning is different
actually &arr Represents the address of the array , Instead of the address of the first element of the array
Address of array +1, Skip the size of the entire array
For example, you can use array pointers as function parameters :
Print a two-dimensional array :
void print_arr(int (*arr)[5], int row, int col) {
int i = 0;
for(i=0; i<row; i++)
{
for(j=0; j<col; j++)
{
printf("%d ", arr[i][j]);
}
printf("\n");
}
}
int main()
{
int arr[3][5] = {
1,2,3,4,5,6,7,8,9,10};
print_arr(arr, 3, 5);
return 0;
}
Array name arr, Represents the address of the first element
however The first element of a two-dimensional array is the first row of the two-dimensional array
So the message here is arr, It's actually equivalent to the address on the first line , Is the address of a one-dimensional array
You can use an array pointer to receive
>> Array parameter passing and pointer parameter passing
We often pass arrays and pointers to functions , How to design the parameters of the function ?
① One dimensional array parameters
int main()
{
int arr[10] = {
0};
int *arr2[20] = {
0};
test1(arr);
test2(arr2);
}
tset1 The address of the first element of a one-dimensional array is received , The parameters can be designed like this
void test(int arr[10]) //10 not essential
void test(int *arr)
test2 The address of the first element of the pointer array is received , It's the address of a pointer ( The secondary pointer ), The parameters can be designed like this
void test2(int *arr[20]) //20 not essential
void test2(int **arr)
② Two dimensional array parameters
int main()
{
int arr[3][5] = {
0};
test(arr);
}
test The address of the first element of the two-dimensional array is received , As mentioned earlier, the address of the first element of the two-dimensional array is the address of the first row of the two-dimensional array
So the parameters can be designed like this
void test(int arr[3][5]) //3 It can be omitted , And the number of columns 5 Don't omit
void test(int (*arr)[5]) // Array pointer to the first row of the two-dimensional array
③ First level pointer parameter transfer
Very often , Let's take a simple example :
#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]);
// First level pointer p, Pass to function
print(p, sz);
return 0;
}
④ The secondary pointer transmits parameters
#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;
}
The secondary pointer is the pointer to the primary pointer ( The address of the first level pointer ), So the parameters are transferred to pp and &p Fine
>> A function pointer
① On function pointer
seeing the name of a thing one thinks of its function , A function pointer is a pointer to a function , Save the address of the function
Illustrate with examples :
void test()
{
printf("hehe\n");
}
test Address of function , It can be used &test Express , It can also be used. test Express , The two have the same meaning
printf("%p\n", test);
printf("%p\n", &test);
These two lines of code can be printed test Address of function
Representation of function pointer :
int Add(int x,int y)
{
return x+y;
}
Point to Add The pointer of the function is expressed in this way :
int (*p)(int,int)=Add;
int (*p)(int,int)=&Add;
Call... With a function pointer Add function :
p(3,5);
(*p)(3,5);
The above parameters are transmitted (3,5) to Add function , but * No practical significance , Plus easy to understand
② Deep understanding of function pointers
《C Traps and defects 》 There are two interesting examples of function pointers in
// Code 1
(*(void (*)())0)();
Code 1 The function of is to call 0 The function at the address
// Code 2
void (*signal(int , void(*)(int)))(int);
Code 2 The function of is a function declaration
We know , Remove the function name and parameter type to get the function return value type
Code 2 Twice void (*)(int) type , It can be used typedef Rewrite it to increase readability , Note here that the new name should follow * after
typedef void(*pfun_t)(int);
pfun_t signal(int, pfun_t);
If readers can quickly identify the code related to function pointers , I believe I have a certain understanding of function pointers .
③ Function pointer array
Define an array of function pointers
int (*parr1[10])();
Array name parr1[10]
Removing the array name is the type of array element :int (*)()
Application instance of function pointer array :
Write a simple calculator , Store the address of the function that implements each operation function in a function pointer array , Call various functions by accessing array elements , The code is as follows
#include <stdio.h>
int add(int a, int b)
{
return a + b;
}
int sub(int a, int b)
{
return a - b;
}
int mul(int a, int b)
{
return a*b;
}
int div(int a, int b)
{
return a / b;
}
int main()
{
int x, y;
int input = 1;
int ret = 0;
int(*p[5])(int x, int y) = {
0, add, sub, mul, div }; // Transfer table
while (input)
{
printf( "*************************\n" );
printf( " 1:add 2:sub \n" );
printf( " 3:mul 4:div \n" );
printf( "*************************\n" );
printf( " Please select :" );
scanf( "%d", &input);
if ((input <= 4 && input >= 1))
{
printf( " Enter the operands :" );
scanf( "%d %d", &x, &y);
ret = (*p[input])(x, y);
}
else
printf( " Incorrect input \n" );
printf( "ret = %d\n", ret);
}
return 0;
}
④ A pointer to an array of function pointers
It's not complicated , It is essentially an array pointer , The type is function pointer
// A function pointer pfun
void (*pfun)(const char*) = test;
// An array of function pointers pfunArr
void (*pfunArr[5])(const char* str);
// Pointer to function array pfunArr The pointer to ppfunArr
void (*(*ppfunArr)[5])(const char*) = &pfunArr;
>> Callback function
Functions called through function pointers , Put the pointer of the function ( Address ) Pass as argument to another function , When this pointer is used to call the function it points to , Let's just say this is a callback function
qsort The callback function is applied ,qsort yes C Sorting function of language compiler function library , The prototype is as follows
The meaning of each parameter :
The following code uses qsort Function on array { 1, 3, 5, 7, 9, 2, 4, 6, 8, 0 } Sort , Comparison function int_cmp It's self actualization , hold int_cmp Address of function ( The pointer ) Passed on to qsort function , Call the... It points to through the pointer when necessary int_cmp function , This is a clear example of a callback function
#include <stdio.h>
//qosrt The user of the function needs to implement a comparison function
int int_cmp(const void * p1, const void * p2)
{
return (*( int *)p1 - *(int *) p2);
}
int main()
{
int arr[] = {
1, 3, 5, 7, 9, 2, 4, 6, 8, 0 };
int i = 0;
qsort(arr, sizeof(arr) / sizeof(arr[0]), sizeof (int), int_cmp);
return 0;
}
>> Pointer related classic topics
Keep in mind : The pointer +1, The number of bytes offset is the number of bytes pointed to by the pointer
①
int main()
{
int a[5] = {
1, 2, 3, 4, 5 };
int *ptr = (int *)(&a + 1);
printf( "%d,%d", *(a + 1), *(ptr - 1));
return 0;
}
// What is the result of the program ?
Running results :
analysis :
②
struct Test
{
int Num;
char *pcName;
short sDate;
char cha[2];
short sBa[4];
}*p;
// Tell the size of the structure is 20 Bytes assume p The value of is 0x100000. What are the values of the expressions in the following table ?
int main()
{
printf("%p\n", p + 0x1);
printf("%p\n", (unsigned long)p + 0x1);
printf("%p\n", (unsigned int*)p + 0x1);
return 0;
}
Running results :
analysis :
p Is a structure pointer ,+1 The time offset is the size of this structure 20
convert to unsigned long A type is an integer data ,+1 It's a number +1
convert to unsigned int* A type is an integer pointer ,+1 The offset is 4
According to the requirements in the question 16 Binary calculation is enough
③
int main()
{
int a[4] = {
1, 2, 3, 4 };
int *ptr1 = (int *)(&a + 1);
int *ptr2 = (int *)((int)a + 1);
printf( "%x,%x", ptr1[-1], *ptr2);
return 0;
}
Running results :
analysis :
Array elements 1 2 3 4 Store in small end mode ( What is the big and small end ) In memory, see the following figure :
④
#include <stdio.h>
int main()
{
int a[3][2] = {
(0, 1), (2, 3), (4, 5) };
int *p;
p = a[0];
printf( "%d", p[0]);
return 0;
}
Running results :
analysis :
You're not mistaken , The answer is 1
int a[3][2] = { (0, 1), (2, 3), (4, 5) }; Notice the parentheses
Parenthesis expression (0,1) The value of is 1, So it's equivalent to int a[3][2] = { 1,3,5 };
p = a[0]; It means p Point to the first row of the array
p[0] Obviously 1
⑤
int main()
{
int a[5][5];
int(*p)[4];
p = a;
printf( "%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);
return 0;
}
Running results
analysis :
The pointer p Is an integer array pointer ,+1 The offset of is 4 An integer
We know , The number of elements is obtained by subtracting the pointer , therefore &p[4][2] - &a[4][2] The value of is -4, Store in memory with complement , When printing as an address , It's called an unsigned number , That is to say FFFFFFFC
⑥
int main()
{
int aa[2][5] = {
1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int *ptr1 = (int *)(&aa + 1);
int *ptr2 = (int *)(*(aa + 1));
printf( "%d,%d", *(ptr1 - 1), *(ptr2 - 1));
return 0;
}
Running results :
analysis :
⑦
int main()
{
char *a[] = {
"work", "at", "alibaba" };
char**pa = a;
pa++;
printf("%s\n", *pa);
return 0;
}
Running results :
analysis : Array elements are char* type , The address of the first element should be received with a secondary pointer
⑧
int main()
{
char *c[] = {
"ENTER","NEW","POINT","FIRST"};
char**cp[] = {
c+3,c+2,c+1,c};
char***cpp = cp;
printf("%s\n", **++cpp);
printf("%s\n", *--*++cpp+3);
printf("%s\n", *cpp[-2]+3);
printf("%s\n", cpp[-1][-1]+1);
return 0;
}
Running results :
analysis :
Use a graph to show the pointing relationship of the three-level pointer :
printf("%s\n", **++cpp);
++cpp ------------ cpp Point to c+2
*++cpp------------c+2
**++cpp-----------*(c+2)----------------&POINT
here cpp The point is like this
Look at this line of code
printf("%s\n", *--*++cpp+3);
++cpp--------------cpp Point to c+1
++cpp-------------c+1
–++cpp-----------c
–++cpp----------*c-----------&ENTER
–++cpp+3------------&ER
here cpp Point to c+1
Look at this line of code
printf("%s\n", *cpp[-2]+3);
cpp[-2] amount to *(cpp-2)-----------c+3
cpp[-2]-----------------------------(c+3) ----------------------&FIRST
*cpp[-2]+3----------------&ST
here cpp Still point to c+1
Look at this line of code
printf("%s\n", cpp[-1][-1]+1);
cpp[-1] amount to *(cpp-1)--------c+2
cpp[-1][-1] amount to *(c+2-1)--------&NEW
cpp[-1][-1]+1 amount to *(c+1)+1-----&EW
边栏推荐
- DDL statement of MySQL Foundation
- Idea SSH channel configuration
- Rhcsa12
- Whether a person is reliable or not, closed loop is very important
- System. Currenttimemillis() and system Nanotime (), which is faster? Don't use it wrong!
- 2021-08-11 function pointer
- Pcl:: fromrosmsg alarm failed to find match for field 'intensity'
- Development guidance document of CMDB
- 原生div具有编辑能力
- 【OpenCV 例程200篇】218. 多行倾斜文字水印
猜你喜欢
【OpenCV 例程200篇】218. 多行倾斜文字水印
A little feeling
六月份阶段性大总结之Doris/Clickhouse/Hudi一网打尽
Rhcsa day 9
Dynamic address book
Three schemes of ZK double machine room
Latex learning insertion number - list of filled dots, bars, numbers
What are the advantages of automation?
Online troubleshooting
Advanced technology management - how to design and follow up the performance of students at different levels
随机推荐
2021-08-10 character pointer
Lavel document reading notes -how to use @auth and @guest directives in lavel
Evolution from monomer architecture to microservice architecture
Four characteristics and isolation levels of database transactions
Network disk installation
Exercise 9-1 time conversion (15 points)
Mmclassification annotation file generation
Golang defer
DCL statement of MySQL Foundation
Safety reinforcement learning based on linear function approximation safe RL with linear function approximation translation 1
Rhcsa day 10 operation
Kotlin set operation summary
Hands on deep learning (III) -- Torch Operation (sorting out documents in detail)
Si vous ne connaissez pas ces quatre modes de mise en cache, vous osez dire que vous connaissez la mise en cache?
Ruby time format conversion strftime MS matching format
MongoDB数据日期显示相差8小时 原因和解决方案
MySQL case
Advanced technology management - how to design and follow up the performance of students at different levels
Go context basic introduction
六月份阶段性大总结之Doris/Clickhouse/Hudi一网打尽