【问题标题】:Understanding dereferencing of double pointers理解双指针的解引用
【发布时间】:2021-01-06 01:37:42
【问题描述】:

这是我最近在线测试中要求的预测输出程序。我无法获得准确的输出,因为我不熟悉双指针解引用。我知道后缀操作的优先顺序和副作用,这对于理解指针问题至关重要。

请通过给出双指针取消引用的示例来帮助我处理此代码 sn-p。 有关单指针取消引用的更多信息,这是一个非常有用的答案: Pointer expressions: *ptr++, *++ptr and ++*ptr

    #include <stdio.h>
    int main()

    {
        char *a[] = {"NITK", "SURATH", "KALMAN", "GALO", "BREAK", "REJOIN"};
        char **b[] = {a + 2, a + 3, a, a + 1, a + 5, a + 4};
        char ***c = b;
        *c++;
        printf("%s\t", *++*c);
        printf("%s\t", **c + 2);
        printf("%c", (*(**(c + 2) + 2) + 2));
        return 0;
    }

预期输出:

BREAK EAK T

P.s这个问题可能没有实际用处,但对理解双指针的概念会有所帮助。

【问题讨论】:

  • 避免这种表达方式。它们没有任何实际用途。实际上,如果我在进行代码审查时看到这样的事情 - 我要求重写整个事情。
  • 同意@P__J__,但这个问题来自测试。
  • 我同意@P__J__。正如我提到的这个问题来自一个测试,我只是想澄清我对双指针取消引用的概念。
  • 关于:char ***c = b;three star programmer
  • 从右到左读取表达式是最容易的,例如:*++*c。这导致:变量 c 是一个指针,该指针预递增,该指针取消引用。但是,必须注意运算符的优先级,因此 ++ 将首先完成,然后是两个取消引用。建议阅读C precedence

标签: c string pointers double-pointer


【解决方案1】:
  1. *c++; 应该是c++; 因为* 在这里没有任何作用。在此操作之后,它引用了对双指针数组 b (a + 3) 的第二个值的引用

  2. 取消引用后,它指向指向a+3的指针,它增加了(因此它引用了指向a + 4的指针。另一个取消引用指向a + 4的指针

  3. 由于前面的操作使c 引用指向a + 4 的指针,**c 引用a + 4,所以**c + 2 引用a + 4 的第三个字符。

  4. c + 2 是指向a + 1 的指针。然后**引用a + 1。添加 2 引用 a + 1 的第三个字符,即 R。取消引用此指针会给出 char 'R'。将 2 添加到它,你会得到 'T' 假设 ASCII 字符编码。

【讨论】:

    【解决方案2】:

    对于初学者来说,这是一个非常愚蠢的测试。忽略使用混淆代码进行此类测试的公司。不要和白痴打交道。通常这样的测试是由低素质的程序员进行的。

    考虑到在表达式中使用的数组指示符(具有罕见的例外)被隐式转换为指向其第一个元素的指针。

    所以这个声明

    char ***c = b;
    

    等价于

    char ***c = &b[0];
    

    在这个表达式语句中

    *c++;
    

    不使用指针的取消引用值。所以这个语句应该写成这样

    c++;
    

    在此语句之后,指针c 指向数组b 的第二个元素。

    你可以重写上面的语句

    c = &b[1];
    

    现在让我们考虑 printf 调用中的表达式

    printf("%s\t", *++*c)
    

    解引用指针c,你会得到左值b[1],它的值是a + 3。将一元运算符 ++ 应用于此表达式,您将得到 a + 4。最后取消引用这个表达式你会得到左值a[4] 即输出。

    BREAK
    

    现在考虑第二次调用 printf 中的表达式。

    printf("%s\t", **c + 2);
    

    第一次解引用指针c,您将获得左值b[1]。在第一次调用 printf 之后,它包含值 a + 4。取消引用此表达式,您将获得指向字符串文字“BREAK”的左值 a[4]。指针表达式加 2 将指向字符串文字的第三个字符。所以会有输出

    EAK
    

    最后让我们考虑一下 printf 的第三次调用中的表达式。

    printf("%c", (*(**(c + 2) + 2) + 2));
    

    由于 c 指向 b[1],然后使用指针算术 c + 2 表达式将指向 b[3] 取消引用指针,您将获得包含值 a + 1 的左值 b[3]。取消引用此表达式,您将获得指向字符串文字 "SURATH" 的左值 a[1]。再次应用指针算法,您将得到一个指针,该指针指向字符串文字的第三个元素,即子字符串"RATH"。取消引用指针表达式,您将获得字符'R'。将值添加到字符 2,您将得到输出的字符 'T'

    T
    

    就是这样。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-11-10
      • 1970-01-01
      • 1970-01-01
      • 2014-10-15
      • 1970-01-01
      • 2023-04-10
      • 1970-01-01
      相关资源
      最近更新 更多