问题描述
这是我最近的在线测试中要求的预测输出程序。我无法获得准确的输出,因为我对双指针解引用不熟悉。我知道后缀操作的优先顺序和副作用,这对于理解指针问题至关重要。
通过提供双指针解引用示例,请帮助我使用此代码段。 有关单指针取消引用的更多信息,这里提供了一个非常有用的答案: 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这个问题可能没有实际用途,但有助于理解双指针的概念。
解决方法
-
*c++;
应该是c++;
,因为*
在这里没有任何保姆效果。在此操作之后,它引用对双指针数组b
(a + 3
)的第二个值的引用 -
取消引用后,它指向指向
a+3
的指针的指针(因此它引用了指向a + 4
的指针。另一个取消引用给出了指向a + 4
的指针 -
当先前的操作使
c
引用指向指向a + 4
的指针时,**c
引用了a + 4
,因此** c + 2引用了第三个a + 4
的字符。 -
c + 2
是指向a + 1
的指针。然后**引用a + 1
。向其添加2将引用a + 1
的第三个字符R
。取消引用此指针可得出char'R'
。向其添加2,您将得到'T'
,并假设使用ASCII字符编码。
对于初学者来说,这是一个非常愚蠢的测试。忽略使用混淆代码进行此类测试的公司。不要与白痴打交道。通常,此类测试是由不合格的程序员进行的。
请注意,在表达式中使用的具有罕见异常的数组指示符会隐式转换为指向其第一个元素的指针。
所以这个声明
def buttonPressed(self,event):
self.richTextCtrl.Clear()
self.richTextCtrl.SetDefaultStyle(wx.TextAttr()) # add this line
等同于
char ***c = b;
在此表达式语句中
char ***c = &b[0];
不使用指针的解引用值。因此,该语句应写为
*c++;
此语句之后,指针c++;
指向数组c
的第二个元素。
您可以像上面这样重写语句
b
现在让我们考虑一下printf调用中的表达式
c = &b[1];
解引用指针printf("%s\t",*++*c)
会得到具有值c
的左值b[1]
。将一元运算符++应用于此表达式,您将得到a + 3
。最后,取消引用此表达式,您将获得左值a + 4
输出。
a[4]
现在在第二个printf调用中考虑表达式。
BREAK
第一次解引用指针printf("%s\t",**c + 2);
时,您将获得左值c
。在第一次调用printf之后,它包含值b[1]
。取消引用此表达式,您将获得左值a [4],该值指向字符串文字“ BREAK”。指针表达式加2将指向字符串文字的第三个字符。这样就会输出
a + 4
最后,让我们考虑一下printf的第三次调用中的表达式。
EAK
随着c指向b [1],然后使用指针算术printf("%c",(*(**(c + 2) + 2) + 2));
,该表达式将指向c + 2
。对指针进行解引用,您将得到包含值{{ 1}}。取消引用此表达式,您将获得指向字符串文字b[3]
的左值b[3]
。再次应用指针算法,您将获得一个指针,该指针指向字符串文字的第三个元素,即子字符串a + 1
。取消引用指针表达式,您将获得字符a[1]
。将字符添加到值2中,您将获得输出的字符“ T”
"SURATH"
仅此而已。