分享几道有大坑的指针面试题目,如果看会看懂相信对于指针会有更深的理解!
-
-
- const char* c[] = { "ENTER", "NEW", "POINT", "FIRST" };
- const char** cp[] = { c + 3, c + 2, c + 1, c };
- const char*** cpp = cp;
-
-
- int main(void)
- {
- printf("%s\n", **++cpp);
- printf("%s\n", *-- * ++cpp + 3);
- printf("%s\n", *cpp[-2] + 3);
- printf("%s\n", cpp[-1][-1] + 1);
- return 0;
- }
首先对于【**++cpp】:cpp指向cp数组的首地址,++cpp,向后移动,指向cp的第二个元素地址,取*号解引用*++cpp,指向第二个元素的内容c+2,它指向POINT的首元素地址&P,最后一次解引用**++cpp,找到里面的内容POINT
对于【*-- * ++cpp + 3】:首先清楚*,++,+,的运算符优先级,对于*和++二者优先级相同,计算顺序是从右到左,对于*和++或--都比+或-的优先级高,对于+或-运算顺序为从左向右
明白这个我们开始看这条语句,因为上一步cpp已经指向了c+2的位置,因此++cpp指向c+1的位置,*++cpp就是c+1指向&N,而接下来--*++cpp指向c,再次解引用*--*++cpp也就是指向其即它的首元素地址&E,而最后+3即从&E向后移动三个单位指向(&E为+0),即指向了下一个&E,打印输出后面字符ER
对于【*cpp[-2] + 3】:cpp[ -2]转换成指针即*(cpp-2),即等价于**(cpp-2)+3,首先cpp-2在上一步基础上指向了cp的第一个元素地址c+3处,解引用*(cpp-2)指向了c+3,再次解引用**(cpp-2)指向c数组最后一个元素地址&F,最终**(cpp-2)+3,指向FIRST的S地址,打印输出ST
对于【cpp[-1][-1] + 1】 :等价于*(*(cpp-1)-1)+1,首先cpp-1指向c+2处地址,解引用*(cpp-1)为c+2,指向&P处,*cpp(-1)-1指向了c数组的c+1处,解引用*(*(cpp-1)-1)指向N,最后+1取到了E,最终打印EW
最终结果:
- int main()
- {
- const char* str[] = { "welcome","to","Fortemedia","Nanjing" };
- const char** p = str + 1;//p存储 "to"字符串地址的地址,即&str[1]
- str[0] = (*p++) + 2;//str[0]指向'\0';因为是后置++,p++后还是指向to首地址
- // 整个(*p++) + 2结束后p才后移一位,指向了下一个字符串Fortemedia
- //存储"Fortemedia"字符串地址的地址, 即p=&str[2]
-
- str[1] = *(p + 1);//p+1后 p+1 = &str[3]; 则 str[1] = str[3] ,
- //即现在str[1]和str[3]都指向了同一地址
-
- str[2] = p[1] + 3;//p[1]存储"Nanjing"字符串的地址,为(char *)型,加三的效果为:
- //+sizeof(char)*3,
- //故str[2]存储了"Nanjing"字符串中的"jing"地址
-
- str[3] = p[0] + (str[2] - str[1]);//str[3]指向从p[0]开始(也就是*p,也就是str[2])的偏移量
- //为(str[2]-str[1])的地址~ str[2]指向"jing",str[1]指向str[3],
- //也就是"Nanjing",所以str[3]指向"jing"的"g"地址
- printf("%s\n", str[0]);
- printf("%s\n", str[1]);
- printf("%s\n", str[2]);
- printf("%s\n", str[3]);
- return 0;
- }
- char* str[] = { "welcome","to","Fortemedia","Nanjing" };
- char** p = str + 1;
得到:
执行下一句,画出(*p++) + 2
将其赋值给str[0]
- str[0] = (*p++) + 2;
- 画出*(p+1)
- str[1] = *(p + 1);赋值
- 画出p[1] + 3
- str[2] = p[1] + 3;赋值
- 画出 p[0] + (str[2] - str[1])
我们可以得到str[2] -str[1] = 3 , 在两个指针指向同一片连续的存储空间时 , 是可以相减的 , 相减为两指针间差了几个元素 ,很明显差了三个 , 再将p[0]+str[2] -str[1]的值赋给str[3] ,如下图 :