C如何精确运行?

时间:2018-07-24 08:13:41

标签: c forward-declaration

当我在C中定义一个函数并使用它时,我才意识到,我可以稍后使用它并定义该函数,或者稍后定义并使用它。例如,

int mult (int x, int y)
{
  return x * y;
}

int main()
{
  int x;
  int y;
  scanf( "%d", &x );
  scanf( "%d", &y );
  printf( "The product of your two numbers is %d\n", mult( x, y ) );
}

int main()
    {
      int x;
      int y;
      scanf( "%d", &x );
      scanf( "%d", &y );
      printf( "The product of your two numbers is %d\n", mult( x, y ) );
    }   

int mult (int x, int y)
    {
      return x * y;
    }

都可以正常运行。但是,在Python中,第二个代码将失败,因为它需要先定义mult(x,y)才能使用,并且Python从上到下执行(据我所知)。显然,在C语言中不可能如此,因为第二个脚本运行得很好。那么C代码实际上是如何流动的?

4 个答案:

答案 0 :(得分:13)

严格来说,第二个代码不是有效的C。

它使用编译器的灵活性来允许隐式声明函数,而C标准中不允许这样做。

C11站立的人在“序言”中明确提到了排除

  
      
  1. 第二版的主要变化包括:
  2.   
     

...

     
      
  • 删除隐式函数声明
  •   

您必须要么

  • Forward declare函数。
  • 在使用该功能之前先对其进行定义(如代码段1所示)。

在编译器中启用警告,然后编译器应生成一些警告消息,以使您了解此问题

答案 1 :(得分:1)

正如其他人指出的那样,应该在使用例程之前先声明 ,尽管在​​使用例程之前不必先定义 。另外,较早的C版本允许进行一些隐式的例程声明,而某些编译器仍然可以这样做,尽管这在很大程度上已经过时了。

关于C如何在定义函数之前就支持它们的调用,首先将C程序翻译成某种可执行格式,然后再执行

在翻译过程中,C编译器读取,分析和处理整个程序。对尚未定义的功能的任何引用都记录为需要在程序中解决的事物。在准备最终的可执行文件的过程中,链接器将遍历所有已处理的数据,查找功能定义,并通过插入被调用例程的地址(或其他信息)来解析引用。

最常见的是,C编译器将源代码转换为对象模块。对象模块包含该程序的机器语言指令。它还包含源代码中定义的程序的任何数据,并且包含有关编译器在分析源代码时发现的未解析引用的信息。多个源文件可以分别转换为多个对象模块。有时,这些翻译是由不同的人在不同的时间完成的。公司可能会产生一个软件库,该软件库是将其源文件转换为目标模块并将其打包为库文件的结果。然后,软件开发人员将编译自己的源文件,并将生成的对象模块与库中的对象模块链接。

可以将多个对象模块链接在一起以创建一个可执行文件。这是操作系统能够加载到内存中并执行的文件。

答案 2 :(得分:0)

对于第二个代码,您应该使用前向声明。这意味着首先声明该函数,以便编译器知道您将使用此函数。目前,您的代码是根据C编译器的灵活性执行的。

Python编译器不够灵活,因此无法编译。

答案 3 :(得分:0)

您说两种代码都可以正常工作。好吧,事实并非如此。第二个代码段将在我的编译器中显示一个错误,如果编译正确,则不应使用。

  • 它使C法规无效。
  • 如果需要太多用户定义的函数,则提前声明函数会很有帮助。