C中的第一个可执行语句

时间:2016-06-02 13:02:14

标签: c scope initialization variable-assignment

主要是C程序中的第一个函数还是第一个可执行语句?如果存在全局变量int a=0;

,该怎么办?

我一直被告知主要是程序的起点。但是,在我看来,赋予某些值并且是可执行语句的全局变量呢?

6 个答案:

答案 0 :(得分:10)

在程序执行之前,静态存储持续时间的全局变量和一般对象在概念上初始化。

C11(N1570)5.1.2 / 1 执行环境

  

应初始化具有静态存储持续时间的所有对象(设置为   程序启动前的初始值。

给定托管环境,函数main被指定为必需入口点,程序执行开始。它可能有以下两种形式之一:

int main(void)
int main(int argc, char* argv[])

其中参数的名称不需要与上面相同(这只是一种惯例)。

对于独立环境入口点是实现定义,这就是为什么有时在嵌入式设备的C实现中遇到void main()或任何不同形式的原因。

C11(N1570)5.1.2.1/1独立环境:

  

在独立环境中(可能需要执行C程序)   没有操作系统任何好处的地方),名称和类型   在程序启动时调用的函数是实现定义的。

答案 1 :(得分:6)

main 是该计划的起点。程序的起点是程序的入口点,在大多数情况下,对于C程序员来说是透明的。通常它由 _start 符号表示,并在用汇编语言编写的启动代码中定义或预编译到C运行时初始化库(如crt0.o)中。它负责对您正在采用的内容进行低级初始化,例如将未初始化的静态变量初始化为零。完成后,它会调用预定义的符号main,这是您知道的main

答案 2 :(得分:5)

  

但是在我看来,分配了一些值并且是可执行语句的全局变量呢

你的意见是错误的。

在全局上下文中,只有变量定义才能存在,并且显式初始化。所有可执行语句(即赋值)都必须驻留在函数内。

详细说明,在全球范围内,你不能有像

这样的陈述
int globalVar;
globalVar = 0;  //error, assignement statement should be inside a function

然而,上述内容在函数内部完全有效,如

int main()
{
   int localVar;
   localVar = 0;  //assignment is valid here.

关于初始化,例如

int globalVar = 0;

初始化发生在main()开始之前,因此本身并不是执行的一部分。

详细说明全局变量初始化的场景,引用C11,第6.2章,

  

如果是声明标识符的声明符或类型说明符   出现在任何块或参数列表之外,标识符具有文件范围,其中   终止于翻译单元的末尾。

flie scope 变量,

  

如果   对象标识符的声明具有文件范围,没有存储类说明符,   它的联系是外在的。

外部链接的对象

  

在没有存储类说明符的情况下声明其标识符的对象   _Thread_local,以及外部或内部链接或存储类   说明符static具有静态存储持续时间。它的一生就是整个执行   程序及其存储的值仅在程序启动之前初始化一次。

答案 3 :(得分:0)

在理论上,仅限C标准的计划中,它是。

在实践中,它通常涉及更多。

在Linux,AFAIK上,内核将链接的图像加载到保留的地址空间,并首先调用可执行映像指定的动态链接器(除非可执行文件是静态编译的,在这种情况下没有动态链接部分)。

动态链接器可以加载依赖库,例如C库。 这些库可能会注册自己的启动代码,您也可以(gcc主要通过__attribute__((constructorr)))注册。 (C ++尤其需要用户提供的init代码,您需要在具有构造函数的C ++全局变量上运行一些启动代码。)

然后链接器调用图像的入口点,默认为_start(链接器允许您选择不同的名称,如果要深入挖掘),默认情况下由{{1提供}} 图书馆。 C通过调用_start来继续初始化C库。

在任何情况下,简单的全局初始化(例如main)应该被编译并链接到您的可执行文件中,然后由操作系统(而不是您的代码)一次性加载,作为加载过程映像的一部分这些变量不需要用户提供的初始化代码。

答案 4 :(得分:0)

如果使用turbo c watch,你会发现第一个全局声明,然后在编译时数据段(给全局和静态变量提供内存)的主启动执行初始化为0。 因此虽然无法进行赋值,但是在编译时进行声明。

答案 5 :(得分:0)

是的,当你声明一个变量内存在编译时分配给它时,除非你不使用堆段(分配内存到指针),即在运行时发生的动态分配。但是由于全局从RAM变量的数据段部分得到它的内存,所以在编译时分配内存。 希望这会有所帮助。