我正在尝试学习C语言中的指针,并且为此目的参加了一次测试。以下是问题:
#include <stdio.h>
char *c[] = {"GeksQuiz", "MCQ", "TEST", "QUIZ"};
char **cp[] = {c+3, c+2, c+1, c};
char ***cpp = cp;
int main()
{
printf("%s ", **++cpp);
printf("%s ", *--*++cpp+3);
printf("%s ", *cpp[-2]+3);
printf("%s ", cpp[-1][-1]+1);
return 0;
}
这行代码的结果:
printf("%s ", *cpp[-2]+3);
这段内容有些让人困惑,但是让我逐步解释一下我所理解的。
char *c[]
- 是一个指向char的指针数组。char **cp[]
- 是一个指向指向char的指针的指针数组(我认为这是*c[]
的反向包装)。char ***cpp
- 是一个指向指向char的指针的指针的指针(我认为这是**cp[]
的包装,可用于就地修改)。
**++cpp
- 由于cpp
指向cp
,那么++cpp
将指向cp+1
,即c+2
,因此双重引用将打印出TEST
。
*--*++cpp+3
- 由于现在cpp
指向cp+1
,那么++cpp
将指向cp+2
,即c+1
,接下来的操作--
将给我们c
的指针,因此最后的引用将打印出sQuiz
。
这里有些困惑:
cpp[-2]
- 由于现在cpp
指向cp+2
,我可以确认这一点。
printf("%p\n", cpp); // 0x601090
printf("%p\n", cp+2); // 0x601090
这里我打印了指向 c
的指针的地址。
printf("c - %p\n", c); // c - 0x601060
printf("c+1 - %p\n", c+1); // c+1 - 0x601068
printf("c+2 - %p\n", c+2); // c+2 - 0x601070
printf("c+3 - %p\n", c+3); // c+3 - 0x601078
所以,当我像这样去解引用 *(cpp[0])
或者 **cpp
时,我期望得到的值是 c+1
中的 MCQ
printf("%p\n", &*(cpp[0])); // 0x601068
但是当我说*(cpp[-2])
时,我得到了QUIZ
,但我更期望得到一些垃圾值。
所以我的问题是:
How the magic with
*--*++cpp+3
works, I mean what is modified by the--
part that allows me to getMCQ
instead ofTEST
when I dereference like this**cpp
, I assume that this pointer*++cpp+3
preserves the state after the--
is applied, but cannot imagine yet how it works.Why the following works the way it works (the
cpp[-2]
part):printf("%p\n", &*cpp[1]); // 0x601060 -> c printf("%p\n", &*(cpp[0])); // 0x601068 -> c+1 printf("%p\n", &*(cpp[-1])); // 0x601070 -> c+2 printf("%p", &*(cpp[-2])); // 0x601078 -> c+3
看起来顺序相反了,我可以接受&*(cpp[0])
指向c+1
,但我希望&*cpp[1]
指向c+2
,&*(cpp[-1])
指向c
。 我在这个问题中找到了答案:Are negative array indexes allowed in C?
- 显然我混淆了很多东西,并且可能称某些不是指针的东西为指针,我想掌握指针的概念,所以如果有人能告诉我哪里错了,我会很高兴。
cpp[n]
这个术语实际上与*(cpp + n)
相同。 因此,使用负值作为n是可以接受的,但在实践中很少使用。 因此,负下标只是从指针cpp向后移动。 - bruceg*--*++cpp+3
不是正确的写法,但那些棘手的测验问题仍然帮助我提高了对指针的理解。别担心,你不会看到我的 C 代码,我只是学习指针并离开。 - MisterAlejandro*--*++cpp+3
不重要,因为它从未被使用过。我不知道它是做什么的,但我并不在意(查看我的灰色胡须可以看出我已经工作很长时间了,而没有需要这个)。你应该把学习重点放在你实际可以使用的东西上。 - Bo Persson