C中的第一个可执行语句

Har*_*sha 5 c scope initialization variable-assignment

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

我一直被告知主要是一个程序的起点.但是在我看来,赋予某些价值的全局变量又是一个可执行的陈述呢?

Grz*_*ski 10

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

C11(N1570)5.1.2/1 执行环境:

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

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

int main(void)
int main(int argc, char* argv[])
Run Code Online (Sandbox Code Playgroud)

其中参数的名称不需要与上面相同(这只是一个约定).

对于独立环境,入口点是实现定义的,这就是为什么有时可能遇到void main()嵌入式设备的C实现中的任何形式.

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

在独立环境中(可以在没有操作系统任何好处的情况下执行C程序),程序启动时调用的函数的名称和类型是实现定义的.

  • @KevinWallis C标准将在"托管"环境中执行程序的起点定义为`main()`函数.如果程序和主机符合标准,那么就是在这样的环境中开始执行的地方.但实际上,一些现有的编译器/链接器确实具有指定不同入口点的选项.例如,GNU工具链提供了这样的替代方案.使用它会使程序在这方面不合规,但这并不意味着它不起作用. (5认同)

Eug*_*Sh. 6

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


Sou*_*osh 5

但是在我看来,赋予某些价值的全局变量又是一个可执行的陈述呢?

你的意见是错的.

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

详细说来,在全球范围内,你不能有这样的陈述

int globalVar;
globalVar = 0;  //error, assignement statement should be inside a function
Run Code Online (Sandbox Code Playgroud)

但是,上面的函数内部完全有效,比如

int main()
{
   int localVar;
   localVar = 0;  //assignment is valid here.
Run Code Online (Sandbox Code Playgroud)

关于初始化,比如

int globalVar = 0;
Run Code Online (Sandbox Code Playgroud)

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

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

如果声明标识符的声明符或类型说明符 出现在任何块或参数列表之外,则标识符具有文件范围,该范围终止于转换单元的末尾.

对于flie范围变量,

如果对象的标识符声明具有文件范围而没有存储类说明符,则 其链接是外部的.

对于具有外部链接的对象,

声明标识符的对象,如果没有存储类说明符 _Thread_local,并且具有外部或内部链接或使用存储类说明符static,则具有静态存储持续时间.它的生命周期是程序的整个执行,它的存储值只在程序启动之前初始化一次.

  • @CarloCe这不会在C中编译,其中所有初始值设定项必须是常量表达式. (5认同)
  • 可惜的是,downvoters不会发表评论,从而剥夺了其他人的学习机会. (3认同)
  • @ Vrajendrav.t.全局`int i = 0;`在C中不执行代码!初始化发生在编译时. (2认同)