我们可以在C中的main函数中定义函数原型吗?

时间:2017-12-10 12:19:56

标签: c prototype

在我的大学,我们的老师教我们"我们在主要功能之前定义功能原型。像:

#include<stdio.h>
void findmax(float, float);
int main()
{
    //code goes here
}

但今天我的朋友告诉我他们了解到他们把原型放在主要功能中。像:

#include<stdio.h>
int main()
{
    void findmax(float, float);

    float firstnum, secondnum;

    printf("Enter first:");
    scanf("%f", &firstnum);

    printf("Enter second:");
    scanf("%f", &secondnum);

    findmax(firstnum, secondnum);
}

void findmax(float x, float y)
{
    float maxnum;

    if(x>y)
    {
            maxnum=x;
    }

    else
    {
       maxnum=y;
    }

    printf("The max is %f", maxnum);
}

它们都有效。我想知道它们之间是否存在差异。感谢。

5 个答案:

答案 0 :(得分:5)

  

我们可以在C函数的主函数中定义函数原型吗?

  

我想知道他们之间是否存在差异

不同之处在于,第一个片段原型是全局的,而在第二个片段中,它是main的本地。 findmax在声明和/或定义后将会显示。

#include<stdio.h>
void foo();
int main()
{
    void findmax(float, float); 
    foo();
    findmax(10, 20);  // It knows findmax by the prototype declared above
}

void findmax(float x, float y)
{
    float maxnum;

    if(x>y)
        maxnum=x;
    else
        maxnum=y;

    printf("The max is %f", maxnum);
}

void foo(){   // foo is using findmax after its definition.
    findmax(12, 30);
}

答案 1 :(得分:2)

如果在main()中声明该函数,则它在main()中作用域,并且您无法在另一个函数中访问它。但是如果你在文件的开头或头文件中声明它,你可以在任何函数中使用它。

答案 2 :(得分:2)

如果在函数外部声明foo,则可以从同一文件中的任何函数调用它:

void foo(); // <-- global declaration

int main() {
  foo();    // <-- works, foo() is declared globally
}

void otherfunc() {
  foo();    // <-- works, foo() is declared globally
}

但是,如果在函数内声明了foo,它只能在同一范围内使用:

int main() {
  void foo(); // <-- scoped declaration
  foo();      // works, foo() is declared in same scope
}

void otherfunc() {
  foo();      // ERROR: foo() is not declared in scope of otherfunc()
}

在任何一种情况下,foo必须在使用之前声明。

答案 3 :(得分:0)

对你的问题直截了当的答案就是肯定的。但是当谈到范围时,我想添加更多。

其他人的建议是正确的 - 如果你在另一个函数中声明一个函数,那么第一个函数的范围通常仅限于第二个函数。对于您提供的示例,这样说是完全安全的。但总有可能并非如此。请考虑以下代码:

#include <stdio.h>

/* Can be accessed from anywhere in this file
 * because defined before anything else.
 */
void print_hello() {
        puts("Hello!");
}

int main() {
        void print_hello(); /* Not needed actually */
        void print_namaste();
        void print_hi();

        print_namaste();
        print_hi();
}

/* The following two functions cannot be
 * accessed from within the above two functions
 * unless these two are declared inside them
 * or at the starting of this file
 */
void print_namaste() {
        puts("Namaste!");
        print_hello();
}

void print_hi() {
        puts("Hi!");
}

您可以在此处看到print_hello()main()内声明。但这是多余的。 print_hello()已经引入编译器。没有必要声明在这个文件中使用它(如果你在其他文件中使用它并独立编译它们,那么你必须在这些文件中声明它或写一个头文件来这样做)。我的观点是,print_hello()内声明main()并未将其呈现为本地,至少在此示例中。您可以看到print_namaste()成功调用它而无需任何其他声明。

print_namaste()print_hi()并非如此。它们要求在main()内使用声明,因为只有在定义了main()之后才会将它们引入编译器。

print_namaste()仅对我们声明它的函数以及print_namaste()之后定义的函数可见。在此示例中,print_namaste()print_hello()不可见(除非在其中或之前声明),但main()可见,因为在其中声明,print_hi可见它的定义仅在print_namaste()

的定义之后出现

答案 4 :(得分:-1)

在VC2008中,以下内容有效:

int main(void)
{
    void foo(void);
    //...
}
void test(void)
{
    foo();
}

我相信原型声明在任何地方都有效,其范围至少从声明点到文件末尾。

查看C99标准:

  

6.2.1标识符的范围

     

标识符可以表示对象;功能;标签或结构,联合或成员   列举;一个typedef名称;标签名称;一个宏名;或宏参数...对于标识符指定的每个不同实体,标识符是可见的(即,可以是   used)仅在程序文本的一个区域内称为其范围...标识符的范围由其声明的位置决定(在一个   声明者或类型说明符)。如果是声明标识符的声明符或类型说明符   出现在任何块或参数列表之外,标识符具有文件范围,即   终止于翻译单元的末尾。如果是声明符或类型说明符   声明标识符出现在块内或参数声明列表中   一个函数定义,标识符有块作用域,它终止于   相关区块。

这意味着VC2008错了。