一面微创题--字符串逆序输出

时间:2021-07-04 11:10:47

     最近一直在等面试消息,都有点着急了,的确,还有太多不足,笔面之后的一面技术面,幸运地是在三个面试者中面试官留下了我,可是一句话又搞的我一点底都没了:“你别以为你通过了就怎么着,其实你也很菜,你写的程序不过就是让我大概看懂了罢了。”可不,趁现在等消息好好想想写的那程序得了。当时一看题目感觉挺简单的,字符串逆序很容易实现呐。

      实现要求是至多只能申请一个空间,不能用库函数。当时面试的时候是这样考虑的,字符数组做函数参数传递,此时如果直接传递的话就成值传参了,所以立马就考虑到用二级指针。面试时写的程序大概如下:

[c-sharp] view plaincopy
  1. #include <iostream>  
  2. using namespace std;  
  3.   
  4. void reverse(char **src,int n);  
  5. int main(int argc,char **argv)  
  6. {  
  7.     char test[] = "I love you!";  
  8.     cout<<test<<endl;  
  9.     reverse(&test,sizeof(test));  
  10.     cout<<test<<endl;  
  11. }  
  12.   
  13. void reverse(char **src,int n)  
  14. {  
  15.     char temp = '/0';  
  16.     for(int i=0;i<n/2;i++)  
  17.     {  
  18.         temp = (*src)[i];  
  19.         *src[i] = *src[n-i-2];  
  20.         *src[n-i-2] = temp;  
  21.     }  
  22.     *src[n-1] = '/0';  
  23.     return ;  
  24. }  

 

可是此时编译运行却出错:“reverse”: 不能将参数 1 从“char (*)[12]”转换为“char **”;

之后在main函数中加入:cout<<typeid(test).name()<<endl;cout<<typeid(&test).name()<<endl;发现,test为char *类型指针,而&test为char (*)[12]类型数组指针。所以参数传递时明显不匹配,数组指针不能传向二级指针形参。修改代码后:

[c-sharp] view plaincopy
  1. #include <iostream>  
  2. using namespace std;  
  3.   
  4. void reverse(char **src,int n);  
  5. int main(int argc,char **argv)  
  6. {  
  7.     char test[] = "I love you!";  
  8.         cout<<typeid(test).name()<<endl;  
  9.         cout<<typeid(&test).name()<<endl;  
  10.     cout<<test<<endl;  
  11.         char *p = test;  
  12.     reverse(&p,sizeof(test));  
  13.         //reverse(&test,sizeof(test));  
  14.     cout<<test<<endl;  
  15. }  
  16.   
  17. void reverse(char **src,int n)  
  18. {  
  19.     char temp = '/0';  
  20.     for(int i=0;i<n/2;i++)  
  21.     {  
  22.         temp = *src[i];  
  23.         *src[i] = *src[n-i-2];  
  24.         *src[n-i-2] = temp;  
  25.     }  
  26.     *src[n-1] = '/0';  
  27.     return ;  
  28. }  

通过编译运行后却又出现内存错误,为什么呢?

再看看reverse函数,优先级又出错了,*src[i];....?这个算什么呢?[]的优先级比*高,所以首先src是与[]结合的,那再通过解引用获得的会是什么元素,此处已经明显内存溢出了。所以继续修改:

[c-sharp] view plaincopy
  1. void reverse(char **src,int n)  
  2. {  
  3.     char temp = '/0';  
  4.     for(int i=0;i<n/2;i++)  
  5.     {  
  6.         temp = (*src)[i];  
  7.         (*src)[i] = (*src)[n-i-2];  
  8.         (*src)[n-i-2] = temp;  
  9.     }  
  10.     (*src)[n-1] = '/0';  
  11.     return ;  
  12. }  

再继续编译运行,总算可以将"I love you!"逆序成"!uoy evol I"了。可是下面这个程序却让我彻彻底底挂掉了。

[cpp] view plaincopy
  1. #include <iostream>  
  2. using namespace std;  
  3.   
  4. void reverse(char *src,int n);  
  5. int main(int argc,char **argv)  
  6. {  
  7.     char test[] = "I love you!";  
  8.     cout<<test<<endl;  
  9.     reverse(test,sizeof(test));  
  10.     cout<<test<<endl;  
  11. }  
  12.   
  13. void reverse(char *src,int n)  
  14. {  
  15.     char temp = '/0';  
  16.     for(int i = 0;i<n/2;i++)  
  17.     {  
  18.         temp = src[i];  
  19.         src[i] = src[n-i-2];  
  20.         src[n-i-2] = temp;  
  21.     }  
  22.     return ;  
  23. }  

同样达到了字符串逆序输出的效果。怎么感觉有点画蛇添足的效果呢,函数是传入的是值形参,尽管这个值的类型是个指针类型,但是对于这个形参和实参来说,所指向的位置是一样的,即所操作的地址是一样的,所以直接用数组名操作即可。哎,果然还太菜呐。