百炼成钢(LeetCode)|图解八道经典指针笔试题


题目目录

  • 第一题
  • 第二题
  • 第三题
  • 第四题
  • 第五题
  • 第六题
  • 第七题
  • 第八题

第一题
int main() { int a[5] = { 1, 2, 3, 4, 5 }; int *ptr = (int *)(&a + 1); printf( "%d,%d", *(a + 1), *(ptr - 1)); return 0; } //程序的结果是什么?

a与ptr的内存图:
【百炼成钢(LeetCode)|图解八道经典指针笔试题】百炼成钢(LeetCode)|图解八道经典指针笔试题
文章图片

a + 1和 ptr - 1:

百炼成钢(LeetCode)|图解八道经典指针笔试题
文章图片

解引用后答案为:
2,5
第二题
struct Test { int Num; char* pcName; short sDate; char cha[2]; short sBa[4]; }*p = 0x100000; //假设p 的值为0x100000。 如下表表达式的值分别为多少? int main() { printf("%p\n", p + 0x1); printf("%p\n", (unsigned long)p + 0x1); printf("%p\n", (unsigned int*)p + 0x1); return 0; }

本题涉及结构体大小的计算,有遗忘的小伙伴可以看一看:结构体/联合体大小的计算
此结构体的大小为20字节
这道题首先要知道指针加整数要看指针类型,而整数加整数就可以直接加
p+0x1 就是跳过一个p类型大小,就相当于+20
(unsigned long)p + 0x1 俩整数相加,直接加
(unsigned int*)p + 0x1 跳过p类型大小,相当于+4

最后答案为:
0x100020
0x100001
0x100004

第三题
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; }

ptr1跟第一题一样,要注意的是ptr2,(int)a + 1中的+1是加一个字节,而一个整形有四个字节,a是首元素地址,(int)a + 1后:
百炼成钢(LeetCode)|图解八道经典指针笔试题
文章图片

而因为ptr2是int* 类型,所以解引用时要向后看四个字节:
百炼成钢(LeetCode)|图解八道经典指针笔试题
文章图片

小端存储取出来后就为02 00 00 00
最后的答案为:

4, 2000000(16进制不打印前面的0)
第四题
int main() { int a[3][2] = { (0, 1), (2, 3), (4, 5) }; int *p; p = a[0]; printf( "%d", p[0]); return 0; }

这里有个陷阱:逗号表达式
真正的内存图:
百炼成钢(LeetCode)|图解八道经典指针笔试题
文章图片

最后的答案为:
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; }

a[4][2]很好找,但是p[4][2]不好找,p指针的类型是int(*)[4]p[4][2]可以看做:
百炼成钢(LeetCode)|图解八道经典指针笔试题
文章图片

&p[4][2] - &a[4][2]结果是-4
百炼成钢(LeetCode)|图解八道经典指针笔试题
文章图片

所以答案为:
FF FF FF FC , -4
第六题
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; }

百炼成钢(LeetCode)|图解八道经典指针笔试题
文章图片

答案:
10, 5
第七题
int main() { char* a[] = { "work","at","alibaba" }; char** pa = a; pa++; printf("%s\n", *pa); return 0; }

百炼成钢(LeetCode)|图解八道经典指针笔试题
文章图片

pa++后指向的a指向"at"
答案为:
“at”
第八题
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; }

先把图画出来
百炼成钢(LeetCode)|图解八道经典指针笔试题
文章图片

因为打印函数中存在++和- -,会改变下一步的结果,所以要一步步分析
1??**++cpp
百炼成钢(LeetCode)|图解八道经典指针笔试题
文章图片

指向的是"POINT"
2??*-- * ++cpp + 3
①++cpp
百炼成钢(LeetCode)|图解八道经典指针笔试题
文章图片

②-- * ++cpp
百炼成钢(LeetCode)|图解八道经典指针笔试题
文章图片

③*-- * ++cpp + 3
百炼成钢(LeetCode)|图解八道经典指针笔试题
文章图片

指向的为"ER"
3??*cpp[-2] + 3
百炼成钢(LeetCode)|图解八道经典指针笔试题
文章图片

百炼成钢(LeetCode)|图解八道经典指针笔试题
文章图片
指向的为"ST"
4??cpp[-1][-1] + 1
①cpp[-1]
百炼成钢(LeetCode)|图解八道经典指针笔试题
文章图片

②cpp[-1][-1]
百炼成钢(LeetCode)|图解八道经典指针笔试题
文章图片

③cpp[-1][-1] + 1
百炼成钢(LeetCode)|图解八道经典指针笔试题
文章图片

指向的为"EW"
所以答案为:
POINT
ER
ST
EW

    推荐阅读