<Written exam questions> Pointer

content

1. Question 1 of the written test:

2. Question 2 of the written test:

3. Question 3 of the written test:

4. Question 4 of the written test:

5. Question 5 of the written test:

6. Question 6 of the written test:

7. Question 7 of the written test:

8. Question 8 of the written test:


1. Question 1 of the written test:

#include<stdio.h>
int main()
{
	int a[5] = { 1, 2, 3, 4, 5 };
	int* ptr = (int*)(&a + 1);
	printf("%d,%d", *(a + 1), *(ptr - 1));
	return 0;
}
//程序的结果是什么?

  •  Parse:

  • * (ptr - 1)

&a means to take out the address of the entire array, &a+1 skips the entire array, the type of &a: int(*)[5], the type of &a+1 is still int(*)[5], cast &a+1 For int*, assign it to ptr, then ptr points to the address of &a+1, ptr-1 is the address of the previous element, and then dereference *(ptr-1) to get 5.

  • *(a + 1):

a represents the address of the first element 1 of the array name, +1 represents the address of element 2, and dereference *(a+1) is 2.

2. Question 2 of the written test:

#include<stdio.h>
struct Test
{
	int Num;
	char* pcName;
	short sDate;
	char cha[2];
	short sBa[4];
}*p;
//假设p 的值为0x100000。 如下表表达式的值分别为多少?
//已知,结构体Test类型的变量大小是20个字节
int main()
{
	printf("%p\n", p + 0x1);
	printf("%p\n", (unsigned long)p + 0x1);
	printf("%p\n", (unsigned int*)p + 0x1);

	printf("%x\n", p + 0x1);
	printf("%x\n", (unsigned long)p + 0x1);
	printf("%x\n", (unsigned int*)p + 0x1);

    //%p以地址的形式打印,不省略0
    //%x就是打印16进制,省略0
	return 0;
}

  • Parse:
  • p+0x1:

The integer pointer (int*)+1 skips 4 bytes, the character pointer (char*)+1 skips 1 byte, and the structure pointer p+1 should skip a structure size, which is 20 bytes, The hexadecimal of 20 is 0x000014, and after adding it is 0x100014.

  • (unsigned long)p + 0x1:

p was originally a pointer to a structure. If p is forced to be converted to an unsigned long type, it will become an unsigned integer type, and it is no longer a pointer. Since it is an unsigned integer type, it is treated as a number, and after adding 1, it is directly Just add it, ie 0x100001

  • (unsigned int*)p + 0x1:

p is coerced into an integer pointer, the integer pointer +1 skips 4 bytes, and adding 4 is 0x100004

3. Question 3 of the written test:

#include<stdio.h>
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;
}

  • Parse:
  •  ptr1[-1]:

&a takes out the address of the array, &a+1 skips the entire array, casts it to int* and assigns it to ptr1. At this time, the address of ptr1 is &a+1, and ptr[-1] is equivalent to *(ptr1- 1) , the address of ptr1-1 is as shown in the figure, and the dereferenced result is 4.

  • *ptr2:

The array name a represents the address of the first element, and the forced type is converted to an integer, which is a value. Adding 1 means adding 1 byte. The memory needs to be converted into data in bytes, and element 1 is 4 words. Section, if it is little endian, assuming that the address of a is 0x10, converted to decimal is 16, plus 1 is 17, hexadecimal is 0x11, find the address of ptr2, and then dereference only need to access 4 more Bytes can be printed out as 2000000. The process is shown in the figure

4. Question 4 of the written test:

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

  •  Parse:

There is a pit in this question, and the comma expression is tested, int a[3][2] = { (0, 1), (2, 3), (4, 5) }; This code can be converted into int a[3 ][2] = { 1, 2, 5 }; This array is 3 rows and 2 columns, a[0] is the array name of the first row, the array name represents the address of the first element, and a[0] represents the first row of the first row The address of an element, that is, the position pointed to by p, p[0] = *(p+0) = *p , and p dereferences to get 1.

5. Question 5 of the written test:

#include<stdio.h>
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;
}

  • Parse:

  •  &a[4][2]:

&a[4][2] represents the address of row 5 and column 3, as shown in the figure.

  • &p[4][2]:

 p is an array pointer, the array that p can point to is 4 elements, p+1 skips 4 integers, which is 16 bytes, p[4][2] --->*(*(p+4 )+2), a is the array name of the array, that is, the address of the first element, assign a to p, and p also points to the address, as shown in the figure. p+1 skips an array of 4 elements, the position of +4 is as shown in the figure, *(p+4) finds 4 elements backward, as shown in the yellow box *(p+4), *(p+4 )+2 skips the position pointed to by 2 elements as shown in the figure, and then dereferences it, and the element is obtained.

  • &p[4][2] - &a[4][2] The number of elements in the middle is 4 by subtracting the addresses of the two integer types. Because the small address reduces the large address, the printing in the form of %d is - 4
  • And printing in the form of %p is to print the address, just print the complement.

-4's complement: 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1100

Converted to hexadecimal printing is FFFF FFFF FFFF FFFC

6. Question 6 of the written test:

#include<stdio.h>
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;
}

  • Parse:
  • *(ptr1 - 1):

&aa means the address of the two-dimensional array, &aa+1 means to skip the entire two-dimensional array to the position shown in the figure, and force it into an integer pointer and assign it to ptr1. The address of ptr1-1 is as shown in the figure, and then dereference it It's the number 10.

  • *(ptr2 - 1):

aa is the array name indicating the address of the first line of the first element of the two-dimensional array, aa+1 skips the first line to the second line as shown in the figure, and then dereferences *(aa+1) to get the second line of the array name The address of the first element, that is, the address of element 6, is assigned to ptr2 forcibly, and ptr2-1 moves forward and dereferences it to get 5.

7. Question 7 of the written test:

#include <stdio.h>
int main()
{
	char* a[] = { "work","at","alibaba" };
	char** pa = a;
	pa++;
	printf("%s\n", *pa);
	return 0;
}

  • Parse:

 The type of pa is char*, adding 1 means skipping an element of char*, pointing to the position as shown in the figure, then dereferencing *pa to get the address of a, and then %s accesses backward to \0 to stop. That is at.

8. Question 8 of the written test:

#include<stdio.h>
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;
}

  • Parse:
  • ** ++ cpp :

 ++cpp skips the address of a char** element to the position shown in the figure, dereferences *++cpp to get the element c+2, c+2 is the address of the third element in c, and then solve The reference gets the address of p, and prints it in the form of %s until \0, that is, POINT.

  • * - * ++ cpp + 3 :

++cpp skips another char* element to the icon position, and then dereferences * ++cpp to get c+1, -- * ++cpp makes c+1-1=c, at this time c is the c array Name the address of the first element, then dereference *-- * ++cpp to get the address of E, then +3 to point to the second E, and then print ER at %s.

  •  * cpp [-2] + 3 :

  *cpp[-2] is **(cpp-2)+3. The location pointed to by cpp-2 is shown in the figure, dereference *(cpp-2) to get c+3, then dereference **(cpp-2) to get the address of F, then +3 points to S, and then %s Print out ST.

  • cpp [-1] [- 1] + 1 :

 cpp[-1][-1] + 1 is *(*(cpp-1)-1)+1, the position of cpp-1 is as shown in the figure, dereferencing gets c+2, minus 1 is c+1, and then Dereference *(*(cpp-1)-1) to get the address of N, plus 1 to point to E, %s prints out EW.

Guess you like

Origin blog.csdn.net/bit_zyx/article/details/122590914
Recommended