函数声明顺序在c语言中是重要的还是我做错了什么?

时间:2012-11-08 20:26:52

标签: c function declaration

我收到此错误:

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

如果我在周围切换功能顺序就可以了 为什么呢?

5 个答案:

答案 0 :(得分:7)

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

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

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

答案 1 :(得分:5)

发生错误是因为符号通常必须在之前声明,而不是之后。

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

答案 2 :(得分:3)

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

由于对randomStr的调用发生在其声明/定义之前,因此假定它返回int,这与char *不兼容(您不能指定值为1)没有明确演员的另一个,因此错误。

从C99开始,不再允许隐式输入。

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

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

答案 3 :(得分:2)

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

例如:

int doesFileExist(const char* str);

将在main()之前。

这样做的原因是C编译器会运行您的代码,每次看到一个函数时,它都会查看该函数是否已经定义。如果找不到该功能,则会出错。 main()使用doesFileExist(),在编译器查看main()时尚未声明。要解决这个问题,您可以在顶部声明一个函数,如上所述。这告诉编译器,虽然尚未填充函数,但它将在稍后填充,因此将其视为函数确实存在,然后在稍后找到函数后再连接它们(即,在main()函数之后的某个地方。

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

答案 4 :(得分: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;
}