C函数声明

C函数声明,c,C,在使用函数之前是否需要声明它?如果我们不使用函数声明并直接调用它,编译器是否会给出错误。请按照标准C回答 如果是,那么如果函数的参数没有定义,那么类型的参数转换为int,浮点转换为double意味着什么呢?在C中,使用它之前需要定义所有内容。我认为这个想法是,它可以在一个过程中编译所有内容,因为当它到达时,它总是拥有它所需要的所有信息 我不确定你对第二部分的要求。如果没有定义函数,它就无法工作。在ANSI C中,您不必声明函数原型;但是,使用它们是最佳实践。标准允许您不使用它们的唯一原因是为了向

在使用函数之前是否需要声明它?如果我们不使用函数声明并直接调用它,编译器是否会给出错误。请按照标准C回答


如果是,那么如果函数的参数没有定义,那么类型的参数转换为int,浮点转换为double意味着什么呢?

在C中,使用它之前需要定义所有内容。我认为这个想法是,它可以在一个过程中编译所有内容,因为当它到达时,它总是拥有它所需要的所有信息


我不确定你对第二部分的要求。如果没有定义函数,它就无法工作。

在ANSI C中,您不必声明函数原型;但是,使用它们是最佳实践。标准允许您不使用它们的唯一原因是为了向后兼容非常旧的代码

如果您没有原型,并且您调用了一个函数,编译器将根据您传递给该函数的参数推断原型。如果稍后在同一编译单元中声明该函数,如果该函数的签名与编译器猜测的签名不同,则会出现编译错误

更糟糕的是,如果函数位于另一个编译单元中,则无法获得编译错误,因为没有原型就无法进行检查。在这种情况下,如果编译器出错,如果函数调用在堆栈上推送的类型与函数预期的不同,则可能会出现未定义的行为

约定是始终在头文件中声明与包含函数的源文件同名的原型

使用原型,编译器可以验证您是否正确调用了函数(使用正确数量和类型的参数)

如果没有原型,可能会出现以下情况:

// file1.c
void doit(double d)
{
    ....
}

int sum(int a, int b, int c)
{
    return a + b + c;
}
这是:

// file2.c

// In C, this is just a declaration and not a prototype
void doit();
int sum();

int main(int argc, char *argv[])
{
    char idea[] = "use prototypes!";

    // without the prototype, the compiler will pass a char *
    // to a function that expects a double
    doit(idea);

    // and here without a prototype the compiler allows you to
    // call a function that is expecting three argument with just
    // one argument (in the calling function, args b and c will be
    // random junk)
    return sum(argc);
}

6.5.2.2“函数调用”中的C99标准描述了函数调用表达式中发生的情况,包括编译器未看到函数的原型时:

如果表示被调用函数的表达式具有不包含原型的类型,则对每个参数执行整数提升,并将具有float类型的参数提升为double。这些被称为默认参数

稍后,它描述了如果函数调用表达式与函数的实际定义方式不匹配时会发生什么情况:

如果函数定义的类型与表示被调用函数的表达式所指向的类型(表达式的类型)不兼容,则行为未定义


显然,为了确保正确性,使用函数原型是正确的做法。足够的C++使得函数原型之一是“C.< /P>>P>P.”简短的回答:C89/90中没有必要,C99是必要的。 在C89/90中,调用函数无需声明。对于未声明的函数,编译器将假设函数返回类型(假设
int
)和函数参数类型(将从调用点的参数类型派生)


在C99中,必须事先声明函数才能调用。注意,即使在C99中,也不需要为函数提供原型,只需要一个声明,即非原型声明是可以的。这意味着编译器不再需要对函数返回类型进行任何假设(因为声明总是显式地指定它),但它可能仍然需要对函数参数进行假设(如果声明不是原型)。

@divya请阅读关于上一个问题的评论,然后修复它,这是家庭作业,与你上一个问题几乎一字不差。美好的但这仍然没有意义。可悲的是,你为了否决一个已结束的问题而花费了一些可怜的灵魂1代表。@Péter török:OP有可能在问题结束后改变它吗?似乎已经做了一些努力来缩小范围并澄清问题。@torak,哦,好的观点。。。我没注意到有多大的改进,但你似乎检查得更仔细了。显然,版主在此期间已经清理了他/她以前的业力,给他/她另一个机会:-)+1:使我免于键入大致相同的内容。我唯一的疑问是,我认为在C术语中,原型是一种声明,函数实现是定义。答案立刻就涉及到原型问题,而最初的问题是关于函数声明,而不是关于原型。原始问题在这个答案中没有得到回答。@torak:函数原型确实是一个声明,但函数声明不一定是一个原型。@AndreyT:你是想说实现也可以作为一个声明吗?它可以。或者,我遗漏了什么吗?@torak:No。我想说的是,例如,
void foo()
是函数声明,但不是函数原型。“原型”和“声明”不是一回事。Prototype是一种特殊的声明。在C中使用它之前不需要定义任何东西。要求是在使用它之前声明所有东西。这一要求仅存在于C99中,而不存在于C89/90中。