zoukankan      html  css  js  c++  java
  • 指针的一道题

    #include <stdio.h>
    
    char *c[] = {"HELLO","NEW","WORLD","SAYHI"};
    char **cp[]={c+3,c+2,c+1,c};
    char ***cpp=cp;
    
    int main(void)
    {
        printf("%s
    ",*cpp[2]);
        printf("%s
    ",**++cpp);
        printf("%s
    ",*--*++cpp+3);
        printf("%s
    ",**cpp);
        printf("%s
    ",*cpp[-2]+3);
    
        printf("%s
    ",cpp[-1][-1]+1);
        printf("%s
    ",cpp[-1]);
    }
    

    #include <iostream>
    #include <string>
    using namespace std;
    
    int main()
    {
        char *c[] = {"HELLO","NEW","WORLD","SAYHI"};
        char **cp[]={c+3,c+2,c+1,c};
        char ***cpp=cp;
        cout<< sizeof(char*) <<endl;
        cout<< sizeof(char**) <<endl;
        cout<< sizeof(char***) <<endl;
        cout<< "c:			"             << c <<endl;
        cout<< "c[0]:			"          << c[0] <<endl;
        cout<< "c[1]:			"          << c[1] <<endl;
        cout<< "&c[0]:			"         << &c[0] <<endl;
        cout<< "&c[1]:			"         << &c[1] <<endl;
        cout<< "&c[2]:			"         << &c[2] <<endl;
        cout<< "&c[3]:			"         << &c[3] <<endl;
    
        cout<< "*c:			"            << *c <<endl;
        cout<< "*(c+1):			"        << *(c+1)<<endl;
        cout<< "&c:			"            << &c<<endl;
    
        cout<< "c[0]:			"          << c[0]<<endl;
        cout<< "&c[0]:			"         << &c[0]<<endl;
        cout<< "*c[0]:			"         << *c[0]<<endl;
        cout<< "*(c[0]+1):		"       << *(c[0]+1)<<endl;
        cout<< "*(&c+1):		"         << *(&c+1) <<endl;
        cout<< "*(&c[0]+1):		"      << *(&c[0]+1)<<endl;
        cout<< "cp			"             << cp <<endl;
        cout<< "*cp			"            << *cp<<endl;
        cout<< "*(cp+1)			"        << *(cp+1)<<endl;
        cout<< "cp[0]			"          << cp[0]<<endl;
        cout<< "&cp[0]			"         << &cp[0]<<endl;
        cout<< "**cp			"           << **cp<<endl;
        cout<< "&cp			"            << &cp<<endl;
        cout<< "&cp[0]			"         << &cp[0]<<endl;
        cout<< "*(*cp+1)		"         << **(cp+1)<<endl;
        cout<< "cpp			"            << cpp<<endl;
        cout<< "&cpp			"           << &cpp<<endl;
        cout<< "*cpp			"           << *cpp<<endl;
        cout<< "*(cpp+1)		"         << *(cpp+1)<<endl;
        cout<< "*(&cpp)			"        << *(&cpp)<<endl;
        cout<< "*(&cpp+1)		"        << *(&cpp+1)<<endl;
        cout<< "**cpp			"          << **cpp<<endl;
        cout<< "***cpp			"         << ***cpp<<endl;
    
    
    
    
    //    cout<< <<endl;
    //    cout<< <<endl;
    //    cout<< <<endl;
    //    cout<< <<endl;
    //    cout<< <<endl;
    //    cout<< <<endl;
    }
    
    8
    8
    8
    c:                   0x61fe00
    c[0]:                   HELLO
    c[1]:                   NEW
    &c[0]:                  0x61fe00
    &c[1]:                  0x61fe08
    &c[2]:                  0x61fe10
    &c[3]:                  0x61fe18
    *c:                     HELLO
    *(c+1):                 NEW
    &c:                     0x61fe00
    c[0]:                   HELLO
    &c[0]:                  0x61fe00
    *c[0]:                  H
    *(c[0]+1):              E
    *(&c+1):                0x61fe20
    *(&c[0]+1):             NEW
    cp                      0x61fde0
    *cp                     0x61fe18
    *(cp+1)                 0x61fe10
    cp[0]                   0x61fe18
    &cp[0]                  0x61fde0
    **cp                    SAYHI
    &cp                     0x61fde0
    &cp[0]                  0x61fde0
    *(*cp+1)                WORLD
    cpp                     0x61fde0
    &cpp                    0x61fdd8
    *cpp                    0x61fe18
    *(cpp+1)                0x61fe10
    *(&cpp)                 0x61fde0
    *(&cpp+1)               0x61fe18
    **cpp                   SAYHI
    ***cpp                  S
    

    **解题过程
    题解1
    题解2
    图示解析

    解题过程
    c 是一个数组,数组里面存的东西是 char *, 类型 cp 也是一个数组,数组里面存的东西是 char **, 类型 cpp 是一个指针,cpp 是一个三级指针,三级指针只能存二级指针地址
    我用 gdb 调试如下

    从 gdb 调试可以看到 cpp 存的是一个地址,这个地址就是 &cp 也就是 0x601060
    cp 是数组,里面的数组存的是 char ** ,如果我们想拿到 char * 的字符串,就需要使用 *p[x] 来获取里面的字符串
    比如

    几个printf 的输出结果
    1、printf("%s ",*cpp[2]);
    实际上获取的就是 c+2 也就是 NEW 字符串
    2、printf("%s ",**++cpp);
    ** ++cpp 是先取cpp 移动到下一个位置,然后再取值,cpp移动多少位置呢?是sizeof(char ***)的大小

    cpp 移动 到下一个就是 c+2 所以 ++cpp 就是 "WORLD"
    3、printf("%s ",
    --*++cpp+3);
    这个就慢慢的显得难度上来了,看这个东西总觉得怪怪的,我们还是分解一下, 首先 ++cpp, cpp 是三级指针, 所以 cpp 就是获取二级指针的值

    因为之前已经对 cpp做了 ++运算,所以现在cpp 指向的是 cp[1],现在又对cpp 做++运算,所以 cpp就指向了 cp[2]了,--cpp 可以理解是对指针做运算,移动的值就是 sizeof (char *** ) 。
    -- * ++cpp 就是
    ++cpp - sizeof(char ***) 也就是 &cp[2] - 8,这个操作之后,实际上就是 &cp[3]了,前面再加上一个 ,就是cp[3]了,cp[3] +3 就是便宜3个值,也就是 "LO" 字符串了。

    4、printf("%s ",**cpp);
    这个输出 HELLO 应该没有任何问题吧,原来题目没有这个打印的,我是为了调试而已。
    5、printf("%s ",cpp[-2]+3);
    这个也是一个超级让我们奇怪的表达式,我们可以主要看这个cpp[-2] ,cpp[-2] 可以这样理解 cpp - 2
    sizeof(char **) = cpp - 28 = cpp -16

    我们先理一下前面的运算,现在cpp在哪个位置?
    这个很关键
    我们之前对cpp 进行了两次 ++ 次操作,现在cpp 应该指向 cp[2]才对,使用gdb验证试一下。

    cpp[-2] 理论上应该是 cp[0] 的值,cpp[2] +3 的输出那应该很容易可以得出来了。就是 "HI"了。
    6、printf("%s ",cpp[-1][-1]+1);
    我们知道,cpp[-1],就是当前的值往前偏移一个位置,跟上面的推断一样,当前cpp还是在cp[2]这个位置,所以cpp[-1]实际上就是cp[1]的位置,然后cpp[-1][0]就是 "WORLD"的位置,cpp[-1][-1]就是"WORLD"再往前偏移一个位置,就是"NEW"了。
    后面再来一个+1 那输出结果应该就是 "EW"了

    至于最后的那个print("%s ",*cpp),因为cpp是三级指针,这样只取到二级指针,最终输出的结果应该是不确定的。













    种一棵树最好的时间是十年前,其次是现在。
  • 相关阅读:
    Java实现 蓝桥杯VIP 算法提高 选择排序
    Java实现 蓝桥杯VIP 算法提高 选择排序
    Java实现 蓝桥杯VIP 算法提高 选择排序
    QT中的SOCKET编程
    代理Delegate的小应用(使用setModelData设置下拉日期对话框)
    360企业云盘需求调研,包括定价
    大神为你分析 Go、Java、C 等主流编程语言(Go可以替代Java,而且最小化程序员的工作量,学习比较容易)
    VS 查看是否有内存泄露的方法
    SpringMVC之 数据绑定-1
    动画操作 (Applying Animations) ngAnimate12
  • 原文地址:https://www.cnblogs.com/islch/p/15109641.html
Copyright © 2011-2022 走看看