谁能告诉我这段代码是如何工作的?

时间:2019-02-18 23:10:36

标签: c

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void print_reverse(char *s)
{
    size_t len=strlen(s);
    char *t=s+len-1;
    printf("%s %s\n",t,s);
    while(t>=s){
        printf("%c",*t);
        t=t-1;
    }
    puts("");
}
int main(){
    print_reverse("Hello");

}

谁能告诉char *t=s+len-1;while(t>=s)的工作方式。我无法理解如何将数字添加到指针,以及如何在while循环中比较指针。该程序用于反转c中的字符串。

2 个答案:

答案 0 :(得分:0)

让我们逐行执行此操作:

print_reverse("Hello");
void print_reverse(char *s)

现在s指向包含以下内容的字符串:

- - ----+----+----+----+----+----+----+---- - -
        |  H |  e |  l |  l |  o | \0 |
- - ----+----+----+----+----+----+----+---- - -
           ^
           s

最后一个字符称为字符串“ NUL”终止符,因为“ NUL”是ASCII值为零(所有不可打印的ASCII值都有三个字母名称)的字符的名称。

    size_t len=strlen(s);

现在len的值为5。请注意,它不包含“ NUL”终止符,因此即使字符串占用6个字节,长度也为5。

    char *t=s+len-1;

现在t的值为s + 4。如果您算一下内存位置,这就是您得到的:

- - ----+----+----+----+----+----+----+---- - -
        |  H |  e |  l |  l |  o | \0 |
- - ----+----+----+----+----+----+----+---- - -
           ^                   ^
           s                   t

请注意,s+strlen(s)将指向“ NUL”终止符。

    printf("%s %s\n",t,s);

该printf应该打印Hello o

    while(t>=s)

此while循环将一直持续到t>=s,这意味着它将为每个字符(包括s所指向的字符)执行循环的正文。

        printf("%c",*t);

这将打印t指向的存储器的内容。它从o开始,然后向H的方向继续前进。

        t=t-1;

向后移动t的部分。最终,t将超过s,然后循环将结束。循环结束后,它将如下所示:

- - ----+----+----+----+----+----+----+---- - -
        |  H |  e |  l |  l |  o | \0 |
- - ----+----+----+----+----+----+----+---- - -
      ^    ^
      t    s

然后这是最后一行:

    puts("");

这将打印一个空字符串和最后一个换行符-字符串中没有换行符,但是我们需要一个换行符,因此这是一种实现方式。

答案 1 :(得分:0)

指针算术

当指针指向数组时,向指针添加整数或从指针中减去整数将指针在数组中来回移动。

应该向此函数传递指向字符串的char *s,该字符串是以空字符('\0')结尾的字符数组。然后size_t len = strlen(s);len设置为此字符串的大小,而char *t = s+len-1;t设置为指向空字符之前的最后一个字符。

然后,在循环t=t-1;中向后移动t

不幸的是,此循环使用t>=s作为控制条件。当t移至s之前的字符时即表示停止,这意味着它已退回到起点之前。但是,C标准仅为数组中的元素以及数组末尾的特殊位置定义了指针算法。如果将此函数传递给指向数组开头的s,则循环最终将使t指向数组之前,并且C标准未定义结果。

关于指针算法的其他须知

任何对象都可以视为一个元素的数组。如果您具有某种类型T和某些对象T x;,则可以设置一个指针T *p = &x;,然后允许将指针前进一个元素p = p+1;。未定义使用*p取消引用该指针,但是可以像在&x == p中进行比较,也可以从中减去一个指针。

如果将print_reverse的指针传递到数组的开头以外的地方,那么它的循环就可以了。但是,这就是示例代码中的用法。 print_reverse("Hello");不是很好的代码。

任何对象都可以视为字符数组。您可以将指向任何对象的指针转换为指向unsigned char的指针,然后检查组成对象的字节。这用于特殊目的。学习C时,不应在通用代码中使用它,但应了解它的存在。