【问题标题】:Head First C string.h related questionsHead First C string.h 相关问题
【发布时间】:2023-03-26 19:20:01
【问题描述】:
#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("");
}

Above 是一个在屏幕上向后显示字符串的函数。但我不明白第 7 行(char *t = s+ len-1;)。谁能解释一下这是英语口语吗?

【问题讨论】:

  • char *t = s+ len-1; 指向字符串的最后一个字符。
  • len 元素数组的最后一个索引是什么?
  • 您可能还想find a good beginners book 了解指针指针算法
  • 如果strlen()返回0,这将不起作用。
  • 但从技术上讲,该代码是非法的,因为t 在数组传递给它之前将指向1 char,并且比较t &gt;= s 可能不起作用。

标签: c string function pointers reverse


【解决方案1】:

对于初学者来说这个功能

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("");
}

是错误的并且有未定义的行为。:)

有两个问题。

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

char *t = s + len - 1;

看起来像

char *t = s - 1;

而指针t 可能是错误的。

第二个问题是这个表达式语句

t = t - 1;

在指针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("");
}

至于你的问题然后在这个声明中

char *t = s + len - 1;

指针t试图用终止零之前的字符串最后一个字符的地址来初始化。

【讨论】:

  • 在 OP 下发表评论,然后看到你的答案。如果这是书中的示例代码,它对“Head First C”的评价并不好。
  • @DavidBowling 我失业了。我不知道这些细节。:)
【解决方案2】:

这个函数背后的主要逻辑是这段代码:

char *t = s+ len-1;

返回一个指针,指向您传递给函数的 char 指针中最后一个 char 的地址。循环通过递减来打印它:

t = t - 1;

简单来说,它从后面打印字符指针。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-11-13
    • 2020-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-29
    • 2021-11-27
    • 2017-09-26
    相关资源
    最近更新 更多