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.