【问题标题】:Function declaration order matters in c language or am I doing something wrong?函数声明顺序在 c 语言中很重要,还是我做错了什么?
【发布时间】:2012-11-08 20:26:51
【问题描述】:

我收到此错误:

arthur@arthur-VirtualBox:~/Desktop$ gcc -o hw -ansi hw1.c
hw1.c: In function `main':
hw1.c:27:16: warning: assignment makes pointer from integer without a cast [enabled by default]
hw1.c: At top level:
hw1.c:69:7: error: conflicting types for `randomStr'
hw1.c:27:18: note: previous implicit declaration of `randomStr' was here

编译这段代码时:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char** argv)
{
        char *rndStr;
        rndStr = randomStr(FILE_SIZE);
        /* Do stuff */
        return 0;
}

/*Generate a random string*/
char* randomStr(int length)
{
        char *result;
        /*Do stuff*/
        return result;
}

如果我切换功能顺序,它就可以工作 为什么?

【问题讨论】:

  • -1 包含太多无关代码。请参阅 SSCCE.ORG 了解简短完整示例为何有用的信息。
  • 您需要在使用它之前声明它。
  • @KevinDTimm - hw1.c:69:7: error: 如果你经常使用 c,`randomStr' 的冲突类型可能非常准确。
  • @KevinDTimm 您确实意识到您的 50% 的 cmets 只会向这个问题发送垃圾邮件?我搜索了大约 2 个小时,寻找第一个错误,并没有发现任何问题。那又怎样,你基本上是在说我懒得问 SO 或者愚蠢地自己没有找到它?最后我检查了 SO 在没有你侮辱新手 C 程序员的情况下做得很好。如果你想帮助别人,我认为你应该把宝贵的时间花在回答问题上。

标签: c function declaration


【解决方案1】:

除了少数例外,C 中的标识符在声明之前不能使用。

以下是如何在其定义之外声明函数:

// Declare randomStr function
char *randomStr(int length);

【讨论】:

    【解决方案2】:

    出现错误是因为符号通常必须在使用之前声明,而不是之后。

    一个特殊的例外是函数。如果在声明之前使用它们,则会推断出特定的声明。在您的情况下,推断的声明与最终定义不匹配。

    【讨论】:

    • 请注意,自 C99 以来,函数的隐式声明已被删除。
    • 是的。另请注意,OP 未使用 C99。
    【解决方案3】:

    在 C89 及更早版本中,如果编译器在相应的声明或定义之前看到函数调用,则假定该函数返回 int。同样,如果您在函数定义中不使用类型说明符,则假定它返回 int(这就是为什么许多旧示例的条目只有 main() {...} 而不是 int main(void) {...})。

    由于对randomStr 的调用发生在其声明/定义之前,因此假定返回int,这与char * 不兼容(如果没有明确的说明,您不能将一个值分配给另一个) cast),因此出现错误。

    从 C99 开始,不再允许隐式类型。

    -ansi 选项导致 gcc 编译为 C89。要编译为 C99,请改用 -std=c99。

    我通常将函数定义在第一次使用之前放在同一个文件中,因此我的代码从下往上读取(main 通常是文件中定义的最后一个函数)。这样我就不必担心保持声明和定义的正确性。

    【讨论】:

      【解决方案4】:

      您需要在使用尚未定义的函数的任何函数之前放置函数声明。

      例如:

      int doesFileExist(const char* str);
      

      会在main()之前。

      这样做的原因是 C 编译器会运行您的代码,并且每次它看到一个函数时,它都会查看该函数是否已被定义。如果它找不到该功能,它会给你一个错误。 main() 使用 doesFileExist(),在编译器查看 main() 时尚未声明。为了解决这个问题,你可以在顶部声明一个函数,就像我上面提到的那样。这告诉编译器,虽然一个函数还没有被填充,但它会在以后被填充,所以把它当作函数确实存在,然后在你以后找到函数后去连接它们(即,在main() 函数之后的某个位置)。

      您的第二个代码块有效,因为编译器在到达那里时已经定义了您在main() 中使用的那些函数。您的第一个块不起作用,因为这些函数既没有定义也没有声明它们将在以后定义。

      【讨论】:

        【解决方案5】:

        只需添加一个函数原型

        #include <stdio.h>
        #include <stdlib.h>
        
        char* randomStr(int length);
        
        int main(int argc, char** argv)
        {
                char *rndStr;
                rndStr = randomStr(FILE_SIZE);
                /* Do stuff */
                return 0;
        }
        
        /*Generate a random string*/
        char* randomStr(int length)
        {
                char *result;
                /*Do stuff*/
                return result;
        }
        

        【讨论】:

        • 我不是在吹毛求疵,其实我也不确定,那不是原型吗?
        • 可行,但函数声明应该在单独的 .h 头文件中
        猜你喜欢
        • 1970-01-01
        • 2023-03-23
        • 2010-12-28
        • 2016-03-31
        • 1970-01-01
        • 2012-06-24
        • 1970-01-01
        • 2012-07-11
        • 1970-01-01
        相关资源
        最近更新 更多