当前位置:网站首页>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
边栏推荐
- Service developers publish services based on EDAs
- 5g/4g wireless networking scheme for brand chain stores
- Safety reinforcement learning based on linear function approximation safe RL with linear function approximation translation 2
- Velodyne configuration command
- Qtreeview+ custom model implementation example
- 7-17 crawling worms (15 points)
- Exercise 7-3 store the numbers in the array in reverse order (20 points)
- If the uniapp is less than 1000, it will be displayed according to the original number. If the number exceeds 1000, it will be converted into 10w+ 1.3k+ display
- System. Currenttimemillis() and system Nanotime (), which is faster? Don't use it wrong!
- Ruby时间格式转换strftime毫秒匹配格式
猜你喜欢
The most detailed teaching -- realize win10 multi-user remote login to intranet machine at the same time -- win10+frp+rdpwrap+ Alibaba cloud server
Basic principle of servlet and application of common API methods
5g/4g wireless networking scheme for brand chain stores
Rhcsa - day 13
Evolution from monomer architecture to microservice architecture
Rhcsa day 10 operation
Mmclassification annotation file generation
用数据告诉你高考最难的省份是哪里!
Latex learning insertion number - list of filled dots, bars, numbers
leetcode1-3
随机推荐
MongoDB数据日期显示相差8小时 原因和解决方案
Go context basic introduction
AUTOSAR from getting started to mastering 100 lectures (106) - SOA in domain controllers
对于程序员来说,伤害力度最大的话。。。
MPLS: multi protocol label switching
Hands on deep learning (42) -- bi-directional recurrent neural network (BI RNN)
The time difference between the past time and the present time of uniapp processing, such as just, a few minutes ago, a few hours ago, a few months ago
Work order management system OTRs
System. Currenttimemillis() and system Nanotime (), which is faster? Don't use it wrong!
用数据告诉你高考最难的省份是哪里!
Devop basic command
Es advanced series - 1 JVM memory allocation
system design
Basic data types of MySQL
On Multus CNI
Hlk-w801wifi connection
Exercise 7-4 find out the elements that are not common to two arrays (20 points)
Batch distribution of SSH keys and batch execution of ansible
Dos:disk operating system, including core startup program and command program
Idea SSH channel configuration