当前位置:网站首页>[pointer training - eight questions]

[pointer training - eight questions]

2022-07-06 02:49:00 Fighting Yang!

`


 Insert picture description here
Every day I don't dance , It's all a betrayal of life .

subject :

Pen test 1

int main()
{
    
	int a[5] = {
     1,2,3,4,5 };
	int* ptr = (int*)(&a + 1);
	printf("%d,%d", *(a + 1), *(ptr - 1));//2 5
	return 0;
}
// What is the result of the program ?

 Insert picture description here

a Represents the first address of this array ,&a Is the address of the entire array , Therefore, it is in progress (&a+1) In the process of operation ,+1 Operation skipped a Entire array , because a It's an array ,&a Represents an array pointer , In assignment ptr The process of , On the left is the shaping pointer , On the right is the array pointer , The types on both sides are different , So use (int*) take (&a+1) Strong conversion to integer pointer type , Otherwise, a warning will be generated . So for *(a+1),a+1 by 2 The address of ,(a+1) Namely 2,ptr-1 by 5 The address of ,(ptr-1) Namely 5.

Pen test 2

struct Test
{
    
	int Num;
	char* pcName;
	short sDate;
	char cha[2];
	short sBa[4];
}*p;// namely p = (struct Test*)0x100000
// hypothesis p  The value of is 0x100000.  What are the values of the expressions in the following table ?
// It is known that , Structure Test The variable size of type is 20 Bytes 
int main()
{
    
	printf("%p\n", p + 0x1);
	printf("%p\n", (unsigned long)p + 0x1);
	printf("%p\n", (unsigned int*)p + 0x1);
	return 0;
}

0x Express 16 Base number ,0x1 representative 1, because p It's the pointer type , The pointer +1 Or minus 1 Represents the size of skipping this type , namely :
(1) A shaping pointer +1 Represents skipping an integer
(2) A structure pointer +1 Represents skipping a structure
(3) A character pointer +1 Represents skipping a character
( Company : byte )
so p+0x1 Represents skipping this structure (20 byte ), turn 16 Hexadecimal is 14, so p+0x1 by 0x100014;(unsigned int)p Represents the general shaping type , so +1 It represents this integer number +1, It's not an operation between addresses ,(unsigned int)p+0x1 by 0x100001;(unsigned int*)p Forcibly convert pointer of structure type to pointer of unsigned integer , so +1 The skipped step size is from 20 Turned into 4, namely (unsigned int*)p+0x1 by 0x100004.

Pen test 3

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


about ptr1 Operation and written test questions 1 Same operation ,ptr1[-1] Express *(ptr1-1), That is to say 4;
about ptr2 The operation of , hypothesis a The address for 0x0012ff40, When strong turns into int Type , That is, it represents an integer 0x0012ff40 so (int)a+1 It stands for numbers 0x0012ff41, And then force it to (int*) type , It becomes an address again , That is to say a The original address has been moved one byte to the right , so ptr2 The pointing position is shown in the figure , Because it is int*, Therefore, you need to start from ptr2 The position pointed to starts counting until the fourth byte 00 00 00 02,, Because it is a small end storage mode ( The last one mentioned ), Therefore, the reading should be from high address to low address ,02 00 00 00, Because the address book is 16 Base number ,%x Printing is 20000000

Pen test 4

int main()
{
    
	int a[3][2] = {
     (0, 1), (2, 3), (4, 5) };
	int* p;
	p = a[0];
	printf("%d", p[0]);
	return 0;
}

Before that , We need to note that the result of the comma expression is the last number , namely a[3][2] The internal number of is :{
1,3,
5,0,
0,0}
a[0], Represents the array name of the first row of the matrix , so p Represents the first row of array name ,p[0] = a[0][0] = 1;

Pen test 5

int main()
{
    
	int a[5][5];
	int(*p)[4];
	p = a;// There will be a warning , But it can still be implemented 
	printf("%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);
	return 0;
}

 Insert picture description here
From the above code we can see ,a by int [5[[5],p by int(*)[4], Due to type mismatch , Therefore, a warning will occur during assignment , But it can still run , By drawing , We can see that p[4][2] And a[4][2] The exact location of , Address - The address is equal to the number of elements that differ between addresses , Therefore, in order to %d The result is -4; When we use %p When printing , according to -4 The original code of :10000000000000000000000000000100,
Find the inverse code :111111111111111111111111111111111011, Then find the complement :111111111111111111111111111111111100, Can be reduced to ff ff ff fc

Pen test 6

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

 Insert picture description here
After the explanation of several questions , This problem is similar to the previous ones , The main thing is to turn the graph into a line , Instead of two lines , So the result is 10 5

Pen test 7

int main()
{
    
	char* a[] = {
     "work","at","alibaba" };
	char** pa = a;
	pa++;
	printf("%s\n", *pa);
	return 0;
}

 Insert picture description here
The array name represents the address of the first element , When put a Assign a value to pa when ,pa Yes a The address of , because pa by char** namely pa++ The size of the move is one char* size , Therefore, it is shown in the figure ,pa Point to (a+1),*pa representative :
*(a+1) namely a[1], That is to %s Print a[1], The result is at.

Pen test 8

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

 Insert picture description here
Appear as the last question , It's bound to be troublesome , therefore , We need to find out the relationship between them , That is, the association between the first three lines of code , Pictured above .
1) When we execute the first printf when ,++cpp, be cpp Yes cp[1], namely :
 Insert picture description here
so **cpp Is to dereference the connection bit by bit ,*cpp find cp[1],
**cpp find c[2], Final print POINT;
2) When we execute the second printf when , also ++cpp, Point to cp[2], And then I'll explain the quotation , That is, find the next level through the connection , That is, to arrive at cp[2],–cp[2], namely cp[2] From to c[1] To point to c[0], And then I'll explain the quotation , arrive ENTER The first address , Again +3, arrive ER, namely : Insert picture description here
3) When we execute the third printf when , Convertible :
 Insert picture description here
namely cpp-2 by cp[0] The address of , Dereference becomes cp[0], Then de quote as c[3],c[3] As array name , by FIRST First element F The address of ,+3 by S The address of , So the result is ST;
 Insert picture description here

4) When we execute the fourth printf when , Follow the above method of finding line segments , Not hard to find : Insert picture description here
The result is EW.

 Insert picture description here

summary :

Through the training of the above eight questions , It includes the operation of pointer core and the most difficult part , It's not hard to see. , Drawing and drawing well is the ultimate means to subdue all pointer relationships .

原网站

版权声明
本文为[Fighting Yang!]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/187/202207060247548991.html