关于C中指针递减的困惑

Des*_*tor 3 c pointers pointer-arithmetic

考虑以下程序:(参见此处的现场演示)

#include <stdio.h>
int main(void)
{
    char c[]={'s','h','r','e','y','a','\0'};
    char *ptr=c;
    for(int i=0;i<6;i++)
        printf("%c",ptr[i]);
    printf("\n");

    char (*s)[7];
    s=&c;
    for(int i=0;i<6;i++)
        printf("%c",(*s)[i]);
    printf("\n");

    ptr=&c[5];       // ptr points to 6th char of string
    for(int i=5;i>=0;i--)
        printf("%c",ptr[i]);
}
Run Code Online (Sandbox Code Playgroud)

该计划没有给出预期的结果.我得到的结果是:

SHREYA

SHREYA

一个

但如果我写下最后一个循环如下,它工作正常.

for(int i=5;i>=0;i--)
     printf("%c",c[i]);
Run Code Online (Sandbox Code Playgroud)

关于指针我在这里理解错了什么?为什么我printf("%c",ptr[i]);在last for循环中写入时只有最后一个char作为输出.

Har*_*ris 6

当你完成任务

ptr=&c[5];
Run Code Online (Sandbox Code Playgroud)

ptr指出fifth了数组的元素,即a.现在你正在循环中打印ptr[i].

让我们从循环的开始开始,看看它打印的内容.

*(ptr+5),这是超出阵列的方式c[].

{'s','h','r','e','y','a','\0'};
  ^   ^   ^   ^   ^   ^    ^    ^  ^  ^  ^
  0   1   2   3   4   5    6    G  G  G  G   //G -> Garbage
                      ^                  ^
                     ptr              (ptr+5)
Run Code Online (Sandbox Code Playgroud)

与之相似,这种情况持续下去,直到i0,最后一次迭代,即*(ptr+0).在它打印a


Fra*_*e_C 5

分配ptr=&c[5];你使得它ptr保存字符串的第5个元素的地址.

如果要访问前面的元素,则需要使用负索引来回退字符串.

ptr=&c[5];       // ptr points to 6th char of string
for(int i=4;i>=0;i--)
    printf("%c",ptr[-i]);
Run Code Online (Sandbox Code Playgroud)

要么

ptr=&c[5];       // ptr points to 6th char of string
for(int i=-4;i<=0;i++)
    printf("%c",ptr[i]);
Run Code Online (Sandbox Code Playgroud)

还请考虑第5个元素被移位4个位置(因为第一个元素位于偏移0处,从0到4计数有5个符号).

另一个是有效的,因为数组c总是指向元素0的地址.