接着上一篇文章,咱们在理解了数组名的含义,以及指针的运算之后,下面咱们来关注一些经典的指针面试题。下面直接代码+图解。
第一题:
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; }
第二题:
假设p 的值为0x100000。 如下表表达式的值分别为多少?
已知,结构体Test类型的变量大小是20个字节
struct Test { int Num; char* pcName; short sDate; char cha[2]; short sBa[4]; }* p = (struct Test*)0x100000; int main() { printf("%p\n", p + 0x1); //0x100000+20-->0x100014 printf("%p\n", (unsigned long)p + 0x1); //1,048,576+1 --> 1,048,577 //0x100001 printf("%p\n", (unsigned int*)p + 0x1); //0x100000+4-->0x100004 return 0; }
第三题:
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; }
注意:这里需要清楚小端存储的概念,具体内容想看前面有一篇文章的内容,里面详细讲解了大小端存储。
当要求十六进制打印时,结果为:
第四题:
int main() { int a[3][2] = { (0, 1), (2, 3), (4, 5) }; int* p; p = a[0]; printf("%d", p[0]); return 0; }
注意:这里需要注意括号问题!还有就是逗号表达式的问题!!!
第五题:
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; }
注意:这里首先需要理解:p[4][2] -> *(*(p+4)+2),而且这两个指针相减为中间的元素个数
第六题:
int main() { char* c[] = { "ENTER","NEW","POINT","FIRST" }; char** cp[] = { c + 3,c + 2,c + 1,c }; char*** cpp = cp; printf("%s\n", **++cpp);// POINT printf("%s\n", *-- * ++cpp + 3); // ER printf("%s\n", *cpp[-2] + 3); // ST printf("%s\n", cpp[-1][-1] + 1); // EW return 0; }
注意:这道题要注意-- 、++ 操作会改变cpp的位置,如果这一点get到了,再结合图解,就很简单了