C语言中函数声明的顺序很重要吗?或者是我做错了什么?

6

I get this error:

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
-1 表示包含了太多无关的代码。请参考 http://SSCCE.ORG 了解为什么简短完整的示例很有帮助。 - Robᵩ
1
你需要在使用之前声明它。 - old_timer
@KevinDTimm - hw1.c:69:7: 错误:`randomStr' 的类型冲突,如果你经常使用C语言可能会非常明确。 - AturSams
3
@KevinDTimm你应该知道你50%的评论只是在这个问题上发布垃圾信息。我已经搜索了大约2个小时,寻找第一个错误,但没有发现任何问题。所以,你基本上是在说我懒得去 SO 上问问题,或者因为没有自己找到答案而愚蠢? 我最后一次检查 SO 在没有你侮辱初学的C程序员的情况下也很好地运作。如果你想帮助别人,我认为你应该花时间回答问题。 - AturSams
5个回答

10

在C语言中,除非特殊情况,否则不能在声明之前使用标识符。

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

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

5
错误的发生是因为符号通常必须在使用之前声明,而不是之后。对此有一个特殊的例外:函数。如果在声明之前使用它们,则会推断出特定的声明。在您的情况下,推断出的声明与最终定义不匹配。

1
自C99起,函数的隐式声明已被删除。 - ouah
1
注意,OP没有使用C99。 - Robᵩ

3
在 C89 及更早版本中,如果编译器在相应的声明或定义之前看到函数调用,则默认该函数返回 int。同样地,如果您在函数定义中省略类型说明符,则默认它返回 int(这就是为什么许多较旧的示例只有一个条目 main() {...} 而不是 int main(void) {...} 的原因)。
由于对 randomStr 的调用出现在其声明/定义之前,因此假定它返回 int,而这与 char * 不兼容(不能将一个值赋给另一个值而不进行显式转换),因此会出现错误。
自 C99 起,不再允许隐式类型。
选项 -ansi 使 gcc 编译为 C89。要编译为 C99,请使用 -std=c99。
通常我会在同一文件中首次使用函数之前放置函数定义,以便我的代码从下往上读取(main 通常是文件中最后一个定义的函数)。 这样我就不必担心保持声明和定义的正确性。

阅读我的帖子,很遗憾我们无法像阅读文本一样从上到下阅读代码。 - mercury0114

2

在使用未定义的函数之前,您需要先声明一个函数。

例如:

int doesFileExist(const char* str);

main()函数之前需要先声明 doesFileExist() 函数。

这是因为C编译器会扫描你的代码,并在每次发现一个函数时查看该函数是否已经被定义。如果找不到该函数,它就会报错。而 main() 函数使用了 doesFileExist() 函数,但在编译器查看 main() 函数时,doesFileExist() 函数还没有被声明。为了解决这个问题,你可以在代码开头部分声明该函数,就像我上面提到的那样。这告诉编译器虽然该函数还没有被完整地实现,但稍后会进行实现,因此应该将其视为存在的函数,然后在找到该函数后再连接它们(例如,在 main() 函数之后的某个位置)。

你的第二个代码块能够工作是因为编译器在到达 main() 函数时已经有了这些函数的定义。但是,你的第一个代码块无法工作,因为这些函数既没有被定义,也没有被声明过它们将在以后被定义。


1

只需添加一个函数原型

#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;
}

1
我并不是在挑剔,我其实不确定,那不是一个原型吧? - kumowoon1025
这样做是可以的,但是函数声明应该放在一个单独的.h头文件中。 - Reid Moffat

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接