【问题标题】:Not-SO Strange C Behavior不那么奇怪的 C 行为
【发布时间】:2014-03-17 09:57:02
【问题描述】:

我正在玩 C,并决定构建自己的 strlen() 函数并且我做到了。但是通过这样做,我很震惊地发现 {} 可以做什么。这是我的代码:

#include <stdio.h>
#include <assert.h>

int mystrlen(char *s)
{
    int i = 0;
    assert(s[0] !='\0');

    for(i = 0; s[i] !='\0'; i++)
    // Placing {} here causes the error to disappear //
    return i;
}

int main(void)
{
    char hello[] = "hello";
    int len = mystrlen(hello);
    printf("Length = %d\n", len);

    return 0;
   }

运行此代码会产生此错误:

mystrlen.c:12:1: warning: control reaches end of non-void function [-Wreturn-type]

但是在放置 {} 在while 循环之后不再出现错误。有人可以向我解释这种行为吗?

【问题讨论】:

    标签: c loops for-loop


    【解决方案1】:

    由于for() 循环中的分号丢失,return 被解析为循环体。

    for(i = 0; s[i] !='\0'; i++)
    return i;
    

    被解析为

    for(i = 0; s[i] !='\0'; i++)
    {
      return i;
    }
    

    这意味着在循环之后,函数结束时没有return。以大括号的形式添加一个空语句会使for 循环有一个空的主体,这会将return 移动到循环之外。

    【讨论】:

    • This means that after the loop, the function ends without a return. 我不这么认为 - 按照 OP 发布的代码 它保证返回 0ideone.com/gCkrb6
    • @al-Khwārizmī:尝试将 "" 传递给 OP 的 strlen()
    • @alk - 代码是静态的,OP 不会从任何地方获取输入。我清楚地提到了 OP 发布的内容。
    • 很公平...@al-Khwārizmī
    • @al-Khwārizmī 当然可以,但是从静态分析(编译器所做的)来看,该函数缺少return
    【解决方案2】:

    因为你少了一个分号:

    for(i = 0; s[i] !='\0'; i++)     ; //<--
    

    【讨论】:

    • 哦,我真傻。大错特错!
    • @cmaster 我现在真的明白为什么了。无需解释。
    【解决方案3】:

    为了防止这样的错误,我总是写大括号

    for(i = 0; s[i] !='\0'; i++)
    { /* increment i */ }
    

    还要注意:

    for ( <expression1> ; <expression2> ; <expression3> ) <statement>
    

    等于:

    <expression1>;
    while (<expression2>)
    {
       <statement>
       <expression3>;
    }
    

    所以更明确地说,你也可以这样写:

    i = 0;
    while (s[i] !='\0')
    {
       i++;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-09-24
      • 1970-01-01
      • 1970-01-01
      • 2018-01-03
      • 2019-04-10
      • 2019-05-24
      • 2016-07-15
      相关资源
      最近更新 更多