复杂的指针面试题

发布于:2023-01-11 ⋅ 阅读:(476) ⋅ 点赞:(0)

分享几道有大坑的指针面试题目,如果看会看懂相信对于指针会有更深的理解! 

例题1:



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

最终结果:

 例题2:部分讲解写在了注释

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] ,如下图 :

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到