为什么需要在函数原型后使用分号

why it is necessary to use semicolon after functions prototype

为什么我们在第二行的 int add(int,int) 语句后使用分号。

#include<stdio.h>
int add(int,int);
int main()
{
int a,b,c;
scanf("%d %d",&a,&b);
c=add(a,b);
printf("The sum of the 2 numbers is %d",c);
return 0;
}
int add(int x,int y)
{
int sum;
sum=x+y;
return sum;
}

如果没有分号,编译器需要一个函数定义(以左大括号开头),或者一个逗号来分隔一个定义和下一个定义。

分号只是一个终止符。由于没有定义函数的主体(例如,不像 main() { ... } ),这是一种让编译器知道不要期待任何其他东西的方法。

分号在C中结束语句。所以分号告诉C声明add函数的语句已经终止,后面的是一个新的语句。 在这种情况下,这是一个函数 declaration 并且分号表明没有更多可以期待的东西。如果没有分号,函数 definition 将预期带有大括号,如 main() {...}

int add(int, int);

这是一个前向声明 - 它是一种告诉编译器的方式 "there's a function called 'add' that takes two ints, so if you see me using it just trust me, I'll define it later"。因为您还没有定义它,所以不需要 {} 后面的大括号。分号出现在 C 中每行代码的末尾,除了某些大括号之后(例如 if 语句、函数 definitions)。所以前向声明后仍然需要分号。

理解什么是C/C++中的声明和定义很重要。当你声明一个变量或函数时,你是在告诉编译器有一些东西的名称指定了类型。编译器不必获取变量或函数的完整定义。

例子中,函数是先声明后定义的。声明语句的语法应包含分号。

阅读这篇文章你可以得到更清晰的概念:http://www.cprogramming.com/declare_vs_define.html

在C语法声明中定义如下

declaration:
    declaration-specifiers init-declarator-listopt ;
                                                  ^^^ 

如您所见,分号是必需的。

还有这个

int add(int,int);

是一个函数声明。因此,您必须在声明的末尾放置一个分号。

比较两个程序

int main( void )
{
    int add( int x, int y )

    {
        //...    
    }
}

int main( void )
{
    int add( int x, int y );

    {
        //...    
    }
}

第一个程序无效,因为编译器会认为函数add定义在函数main.

第二个程序有效。 main.

中有一个函数声明和一个代码块

所以需要分号来区分声明和其他程序结构。

这是必要的历史原因是,最初,在 K&R C 中,add() 会写成:

int add()
int x;
int y;
{
  return x+y;
}

原型后面没有分号,很难甚至不可能将其与以下内容区分开来:

 int add();
 int x;
 int y;

 {
   /* A nested block. */
 }

请记住,C 预处理器是一维的,它将程序转换为由空格分隔的标记列表。解析器看不到换行符或缩进来猜测你的意思。

此外,C 中的语句通常以分号结尾,保持一致比让程序员记住一堆任意异常更容易。