一道关于字符串指针的趣题

     某日,有人问我一道题目,据说来自百度笔试,我也没去验证。先看如下一段代码:

void fun(void * str)
{
     char* p = *(char **)str;
     char * q = (char *)str;
}

    问:p和q有什么区别?

    这个题目蛮有趣的,主要考察c风格字符串和指针的相关知识。为了更清楚地分析问题,我们不妨写个主函数,测试一下函数fun:

int main()
{
    char str[] = "abcde";

    fun(str);

    return 0;
}

    char *q = (char *)str,相信大家对这句话都不会有疑问,如果打印q,会得到字符串"abcde"。

    问题就出在char *p = *(char**)str这句话上。str首先被转换为char**类型,即指向指针的指针,也就是二级指针。说得浅显些,(char **)str存着一个地址,按照这个地址找过去,得到的应该是一个char指针。也就是说,str处存储的内容被编译器当成了一个地址——指向一个char指针的地址!那么,str处存储的是什么?没错,是一串连续的字符“abcde”!也就是说,一串连续字符被编译器当成了一个指向char指针的地址,这就是真相!

    当然,对于32位机器来说,编译器只能将str所指的字符串的前4个字符abcd作为地址。我在linux下用g++编译这段代码,因此采用小端存储模式,即高位字节存于高地址,低位字节存于低地址。对于字符串“abcd”而言,d显然处于最高地址,而a处于最低地址,所以,如果把“abcd”作为一个整体读出来,d是最高位字节,a是最低位字节,其16进制形式应该是“0x64636261”,而非"0x61626364"。对(char**)str进行一次解引用,即*(char**)str,编译器就按照地址0x64636261去寻找,并找到一个char指针。如果幸运,这个char指针或许仍然可以作为一个字符串被读出;如果不幸运,例如,地址0x64636261本身就是一个应用程序不可达的位置,那么程序运行就会出现段错误了。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值