Head First C string.h相关问题

0 c string reverse pointers function

#include <stdio.h>
#include <string.h>

void print_reverse(char *s)
{
    size_t len = strlen(s);
    char *t = s + len - 1;
    while (t >= s)
    {
        printf("%c", *t);
        t = t - 1;
    }
    puts("");
}
Run Code Online (Sandbox Code Playgroud)

以上是一个在屏幕上向后显示字符串的功能.但我不明白第7行(char*t = s + len-1;).请问有人解释这是英语口语吗?

Vla*_*cow 7

对于初学者这个功能

void print_reverse(char *s)
{
    size_t len = strlen(s);
    char *t = s + len - 1;
    while (t >= s)
    {
        printf("%c", *t);
        t = t - 1;
    }
    puts("");
}
Run Code Online (Sandbox Code Playgroud)

是错误的,并且有不确定的行为.:)

有两个问题.

第一个是传递的字符串作为参数可以具有零长度.在这种情况下这个声明

char *t = s + len - 1;
Run Code Online (Sandbox Code Playgroud)

会是这样的

char *t = s - 1;
Run Code Online (Sandbox Code Playgroud)

并且指针t可能是错误的.

第二个问题是这个表达式声明

t = t - 1;
Run Code Online (Sandbox Code Playgroud)

在指针t等于的情况下具有未定义的行为s.

来自C标准(6.5.6添加剂操作员)

  1. ...如果指针操作数和结果都指向同一个数组对象的元素,或者指向数组对象的最后一个元素,则评估不应产生溢出; 否则,行为未定义.

正确的函数实现可以采用以下方式

void print_reverse( const char *s)
                    ^^^^^
{
    size_t len = strlen(s);
    const char *t = s + len;
                    ^^^^^^^
    while (t != s)
           ^^^^^^
    {
        printf("%c", *--t);
                     ^^^^
    }
    puts("");
}
Run Code Online (Sandbox Code Playgroud)

至于你在本声明中提出的问题

char *t = s + len - 1;
Run Code Online (Sandbox Code Playgroud)

t尝试通过终止零之前的字符串的最后一个字符的地址来初始化指针.