可以在“main”之前调用函数吗?如果是这样,会发生什么?

时间:2013-06-29 03:10:19

标签: c function-calls

我知道首先执行的是 main()函数,然后函数调用会将程序指向其他函数。如果函数在 * main()函数之前被调用 * ,该怎么办?什么时候会被执行?\

我有一个程序(我从互联网上下载),并且在main()之前有函数调用。

现在我不知道它们是什么,如果只在main()中执行(以及在main中调用的函数)。

这是该计划的碎片:

static void set_level_indices   (VideoParameters *p_Vid);
static void chroma_mc_setup     (VideoParameters *p_Vid);
static void init_img            (VideoParameters *p_Vid);
static void init_encoder        (VideoParameters *p_Vid, InputParameters *p_Inp);
static int  init_global_buffers (VideoParameters *p_Vid, InputParameters *p_Inp);
static void free_global_buffers (VideoParameters *p_Vid, InputParameters *p_Inp);
static void free_img            (VideoParameters *p_Vid, InputParameters *p_Inp);
static void free_params         (InputParameters *p_Inp);

static void encode_sequence     (VideoParameters *p_Vid, InputParameters *p_Inp);

*(SOME FUNCTION DECLARATIONS OMITTED)*

int main(int argc, char **argv)
{
  init_time();
#if MEMORY_DEBUG
  _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
#endif

  alloc_encoder(&p_Enc);

  Configure (p_Enc->p_Vid, p_Enc->p_Inp, argc, argv);

  // init encoder
  init_encoder(p_Enc->p_Vid, p_Enc->p_Inp);

  // encode sequence
  encode_sequence(p_Enc->p_Vid, p_Enc->p_Inp);

  // terminate sequence
  free_encoder_memory(p_Enc->p_Vid, p_Enc->p_Inp);

  free_params (p_Enc->p_Inp);  
  free_encoder(p_Enc);

  return 0;
}

现在我想到了, static 是否与main()正常之前完成的这些调用有关?

这是H.264的参考软件编码器。

修改

main()函数调用,函数原型或函数声明。你们都给出了不同的答案。请选择一个并通过提供格式解释原因。我真的认为这些语句是函数调用的形式。此外,函数原型可以包含在源代码中而不是头文件中吗?谢谢!

7 个答案:

答案 0 :(得分:14)

如果您在询问如何实现这一目标,则不是通过C语言的标准功能。

C运行时的工作原理是为执行二进制文件时操作系统提供一个入口点。该入口点运行特定于编译器实现的代码。它将设置一些初始化代码,然后调用main()函数(如果提供了任何命令行参数)。调用main()之前执行的C运行时之外的任何其他代码是C语言之外的机制(或编译器提供的C语言的扩展)。

在C ++中,全局构造函数在main()之前执行。

在C中,您的编译器实现可以提供一个扩展,允许在调用main()之前标记函数。在GCC中,可以使用constructor attribute完成此操作。

void foo () __attribute__((constructor));
void foo () { puts(__func__); }
int main () { puts(__func__); return 0; }

上述程序的输出(使用GCC编译时)是:

foo
main

答案 1 :(得分:5)

在您发布的代码中,函数在main之前声明,并不意味着调用这些函数。它们被声明,通知编译器这些函数将在程序中使用

答案 2 :(得分:3)

在您列出的代码中,main之前的函数是函数原型,也称为函数声明(它们是同义词)。它们是不是函数调用。你可以告诉他们这不是函数调用有两个原因:

  1. 无法从全局范围调用函数。全局范围是函数体的外部。这是识别它的最快方式,但它有点波动。
  2. 真正的原因是函数调用前面没有类型说明符或类型限定符,如voidstatic。这些关键字指定符号的类型,在这种情况下是声明的函数。函数调用没有类型(返回值有,但不是调用本身),所以你永远不会以这种方式为函数调用指定类型。
  3. 回答其他一些问题:

    • 在大多数实现中(根据C标准),要执行的第一个用户定义函数始终为main,在这种情况下,您无法编写在main之前调用任何其他函数的代码。在大多数情况下,编译器将生成自己的初始化代码,该代码在main函数之前执行。它执行诸如设置内存和初始化静态变量之类的操作。在某些情况下,您可以编写将用作初始化一部分的代码,但这种情况相对不常见,而且编译器具体如何执行此操作。
    • 函数原型或函数声明只是在实际定义/实现函数之前告诉编译器函数的一种方式。声明/原型(同样的事情)告诉编译器:a)这个符号是一个函数,b)它有这样的返回类型,c)它有这样的参数列表。这样,当编译器看到你尝试在代码中的其他地方调用该函数时,它就知道你要做什么。
    • static关键字称为存储说明符。在函数上,它只是意味着函数名称不会导出到链接器,因此无法从任何其他代码模块(即,从任何其他C源文件)调用它。所以它实际上只是限制功能的可见性或范围的一种方式。
    • 请记住,头文件只是在多个位置包含相同内容的一种方式。在#include文件的任何地方,编译器都会将其视为包含文件的内容直接出现在包含文件的位置。因此函数原型/声明将经常出现在头文件中。这允许该函数从包含标题的任何源文件中“已知”(并因此被调用)。函数实现(也称为函数定义)通常应该放在头文件中。这样做会导致每次包含文件时都定义函数,这通常会导致链接器抱怨(函数的)名称有多个定义。 (解决这个问题的唯一方法就是标记函数static,然后在每次包含头文件时真正定义文件本地函数,而不是实现具有全局作用域的单个函数。从多个源文件调用。后者通常是你想要的。)

答案 3 :(得分:2)

我认为你可能会误解函数声明和函数调用。

#include <stdio.h>
void foo(void);
int main(void)
{
    printf("main\n");
    foo();
    return 0;
}
void foo(void)
{
    printf("func\n");
}

在上面的简单程序中,由于foo的定义低于main,因此必须在main之前声明。将声明放在头文件中并包含它,或者将声明放在main之前或任何调用它们的函数中。

<强>更新

static的函数仅限于它们在文件中的范围,没有其他含义。

答案 4 :(得分:1)

只需在每个函数中编写一个print语句..

printf(" main");

printf("function 1")

您将获得被调用函数的序列。默认情况下,main函数总是先调用,在执行结束时,main函数应该返回一个int,float等,如主定义中声明的那样。

答案 5 :(得分:0)

如果在main函数之前调用函数,那么main函数的意义是什么? main是大多数语言编译器的起点。

如果你想在main()功能代码之前运行一个函数,只需在运行任何代码之前调用它。

答案 6 :(得分:-1)

如果在main函数之前调用函数,它们将在main函数之前执行。