一个面试题,很基础,却有很多东西可以挖掘+char*+char[]+与char*[]++char(*[])


先给出题目,问输出多少:

#include <iostream>
using namespace std;

int main()
{
    char* str[]={"Welcome","to",Fortemedia", "Nanjing"};
    char **p=str+1;
    str[0]=(*p++)+2;
    str[1]=*(p+1);
    str[2]=p[1]+3;
    str[3]=p[0]+(str[2]-str[1]);
    cout<<str[0]<<str[1]<<str[2]<<str[3]<<endl;
}

1、先纠正自己几个语法上的错误思想
       看下面这个测试程序:

#include <iostream>
using namespace std;

int main()
{
    char str[]="Welcome";
    char* p = str;
    cout<<++str<<endl;
    cout<<++str<<endl;
    cout<<++str<<endl;
    cout<<++p<<endl;
    cout<<++p<<endl;
    cout<<++p<<endl;
}

        这个程序编译是通不过的,问题出在

    cout<<++str<<endl;
    cout<<++str<<endl;
    cout<<++str<<endl;

        问题出在这几行,str是char[]类型的,不是指针类型,不支持自增自减。但是str存的是字符串首地址,赋给p指针之后,可以通过p自增自减截取子串。

        再看这个测试程序:

    int main()
    {
       char str[]="Welcome";
       char* p = str + 1;
       str = str + 1; //出错提示为:“=”: 无法从“char *”转换为“char [8]”
        cout<<++p<<endl;
       cout<<++p<<endl;
       cout<<++p<<endl;
    }

         原来,str被隐式转换为char*类型,但是相反的过程不支持,这点保证了str的内容始终指向字符串在常量区中的首地址。

2、char*与char[]的区别

       摘自网上一段话,自己做了修改

       char *Str;Str="abcdef";       Str指向常量区,不能更改字符串的值       char Str[]="abcdef";       在栈区,可以改变

       首先第一个指针形式的str指向一个字符串,这样指向以后就不能通过str对abcdef这个字符串修改了,但是你可以给str用别的字符串再赋值,这样他就指向了别的字符串,

       如: char *Str = "abc";

                 Str = "def";

       但是一旦指向某个字符串,就不能通过这个指针对字符串修改了。

       第二种数组形式的str,其实数组名就是指针常量,也就是说一旦他初始化了,它指向的地址就固定了,就不能再用别的字符串赋值了(这就不同于指针形式的str),但是  这个地址里放什么是可以改变的(指针形式的就不能改变了),比如说初始化之后在通过cin>>str改变数组的内容还是没有问题的。

3、char *str[]的类型问题

        str是一个char*[]类型,与char[]一样,同样指向常量区中的首地址,该块内存中顺序存放了n的char*类型的指针,如上题就是4个地址,第一个地址指向"Welcome"字符串的首地址、依次类推。所以:

    char* str[]={"Welcome","to","Fortemedia", "Nanjing"};
    char *a="Welcome";
    char *b="to";
    char *c="Fortemedia";
    char *d="Nanjing";
    char* str[]={a,b,c,d};

         这两端是等效的。

         可以这么看 char* str[] ,即str是一个数组,数组内的元素类型是char*

4、回到面试题也就不难理解了

        char **p=str+1;是取到了指向str[1]的指针

        str[0]=(*p++)+2;是先取p的内容,内容即是"to"字符串首字母的地址,然后+2,指向了第三个字符,即'\0',在p++,此时p为指向str[2]的指针

        str[1]=*(p+1);    p先加1,指向了str[3]再取内容,返回的是"Nanjing"的首字母地址

        str[2]=p[1]+3;  等效于 str[2] = *(p+1) + 3;  p为指向str[2]的指针  +1之后为指向str[3]的指针,取内容返回"Nanjing"首字母地址,+3之后指向"Nanjing"字符串中j的地址

        str[3]=p[0]+(str[2]-str[1]); str[2]为指向"Nanjing"字符串中j的地址,str[1]为"Nanjing"首字母地址,相减返回3,p[0]指向了str[2],str[]此时为指向"Nanjing"字符串中j的

                                                     指针,+3之后指向了'g'

        输出结果为:Nanjingjingg

        输出str[0]为空

        输出str[1]为Nanjing

        输出str[2]为jing

        输出str[3]为g

 

5、char*str[]与char(*str[])等效

                
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值