【问题标题】:Reversing a string in C using pointers - purpose of if statement?使用指针反转 C 中的字符串 - if 语句的目的?
【发布时间】:2015-02-21 01:29:27
【问题描述】:

在下面反转字符串的代码中,我不明白 if 语句的目的是什么。 if 语句试图捕捉的情况是什么?

这不是多余的吗,因为您已经设置了 char*e​​nd= str,因此 if(str) 语句必须为真,否则此时您的代码已经失败?

void reverse(char* str)
{
    char *end = str;
    char temp;
    if (str) 
    {
        while (*end)
        {
            end++;
        }
    }
    end--; //pulls back one for \0 character
    while (str < end)
    {
        temp = *str;
        *str++ = *end;
        *end-- = temp;
    }    
}

【问题讨论】:

  • 这段代码有问题,如果str 为空,end--; 会导致未定义的行为。它需要if ( !str ) return; 在函数的开头而不是,尝试什么都不做是没有意义的。

标签: c string


【解决方案1】:

它可以防止取消引用 NULL 指针,非常好的做法。

如果str == NULL,那么*end 将是未定义的行为,因此在取消引用之前检查它确实是一件好事,因为忽略这种可能性会导致一个很难检测到的错误,除了当然使用调试器,但是,为什么要保留跟踪问题的需要,通常情况下,您几乎可以不惜任何代价来避免它。

其实做这样的事情会更好

if (str == NULL)
    return;

【讨论】:

  • 其余的代码肯定会导致它崩溃:P——它仍然会被执行。测试后的所有东西都应该放在同一组大括号内。
  • 啊,我明白了。因此,即使 str 为 NULL,也可以分配 char*e​​nd = str,但是一旦您取消引用,那就是当您想要检查未定义行为的 b/c 时(例如进入相邻内存或带有 end++ 的东西线)。谢谢。
  • @Jongware。好点子。似乎 if 语句的范围应该更广泛。 end-- 如果 str 为 NULL,仍会立即引起问题。如果 str 为 NULL,也不想运行该 while 循环
  • @Ragnar 它不会以任何方式运行,因为如果end == NULL 那么str == NULLstr &lt; end 将是错误的。但是,end--; 肯定会导致问题。
  • @iharob 实际上,end-- 应该将NULL 地址更改为 0xFFFFFFFF,这将大于 str
【解决方案2】:

这不是多余的,因为你已经设置了 char*e​​nd= str,所以 语句 if(str) 必须为真,否则您的代码已经 到此为止失败了吗?

其实是行

char *end = str;

不会导致“代码失败”,即使将空指针作为参数传递也是如此。然后它会将NULL 分配给end

这个 if 语句试图捕捉什么情况?

由于我们还不知道我们是否传递了一个 NULL 指针,我们应该在取消引用之前检查它。这就是 if 语句的用途。

【讨论】:

    【解决方案3】:

    这段代码可以正常工作:

    void reverse(char* str)
    {
        if (str != NULL) 
        {
            char *end = str;
            while (*end != '\0')
                end++;
            end--; //pulls back one for \0 character
            while (str < end)
            {
                char temp = *str;
                *str++ = *end;
                *end-- = temp;
            }
        }
    }
    

    此代码也可以工作:

    void reverse(char* str)
    {
        if (str == NULL) 
            return;
        char *end = str;   // Assumes C99 or later
        while (*end != '\0')
            end++;
        end--; //pulls back one for \0 character
        while (str < end)
        {
            char temp = *str;
            *str++ = *end;
            *end-- = temp;
        }
    }
    

    两者都确保您永远不会弄乱空指针。像在原始代码中那样减少空指针会导致灾难(或者,至少,未定义的行为)。不要冒险。

    你也可以使用strlen()——小心确保你不会遇到空字符串的问题:

    void reverse(char* str)
    {
        if (str == NULL || *str == '\0') 
            return;
        char *end = str + strlen(str) - 1;
        while (str < end)
        {
            char temp = *str;
            *str++ = *end;
            *end-- = temp;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2012-11-15
      • 1970-01-01
      • 1970-01-01
      • 2012-05-05
      • 2015-10-19
      • 1970-01-01
      • 2019-04-15
      相关资源
      最近更新 更多