繁体   English   中英

理解双指针的解除引用

[英]Understanding dereferencing of double pointers

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

请通过提供双指针取消引用的示例来帮助我处理此代码片段。 有关单指针取消引用的更多信息,这里有一个非常有用的答案: 指针表达式:*ptr++、*++ptr 和 ++*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

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

  1. *c++; 应该是c++; 因为*在这里没有 anny 效果。 在此操作之后,它引用了对双指针数组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 添加到它,假设 ASCII 字符编码,你会得到'T'

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

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

所以这个声明

char ***c = b;

相当于

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

在这个表达式语句中

*c++;

不使用指针的解除引用值。 所以这个语句应该写成

c++;

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

你可以像这样重写上面的语句

c = &b[1];

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

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

取消引用指针c会得到值为a + 3左值b[1] 将一元运算符 ++ 应用于此表达式,您将获得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

就这些。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM