80k
声誉撰稿人 R .. 告诉我,我们无法使用函数的返回值初始化全局变量,因为它不被认为是常量,而是全局变量必须用常量初始化。并且对于他的话来说,我得到了以下错误,正如预期的那样 - initializer element is not a constant
。这是程序:
#include<stdio.h>
int foo();
int gvar=foo(); //ERROR
int main()
{
printf("%d",gvar);
}
int foo()
{
return 8;
}
但在这种情况下,我只是不明白为什么上面程序的后续修改版本根本没有显示任何错误并且运行正常。在第二个程序中,我正在使用返回值初始化相同的全局变量相同函数foo()
。你能告诉我结果变化的严格技术原因是什么?为什么用函数的返回值初始化全局变量会导致错误,但是从函数中完成时,具有相同返回值的相同初始化是否正常工作?
#include<stdio.h>
int foo();
int gvar;
int main()
{
gvar=foo();
printf("%d",gvar);
}
int foo()
{
return 8;
}
输出 8
答案 0 :(得分:11)
其背后的原因是,为了确定函数产生的值,需要执行代码,并且在初始化静态和全局变量时没有在C中完成代码执行。
编译器和链接器协同工作以准备全局内存段的字节映像:编译器提供值,链接器执行其最终布局。在运行时,段的图像按原样加载到存储器中,无需进一步修改。这在任何代码执行之前发生,因此不能进行任何函数调用。
请注意,这并不意味着由于某些技术原因而不可能,只有C设计者决定不这样做。例如,C ++编译器生成一个调用全局对象构造函数的代码段,该代码段在控件传递给main()之前执行。
答案 1 :(得分:2)
第二个版本没有gvar
的初始值设定项。在没有初始化程序的情况下,在全局范围内声明和定义gvar
。它具有静态存储持续时间,因此它初始化为零。
main
中的赋值就是:赋值,而不是初始化。
答案 2 :(得分:1)
在案例1中,全局变量在声明时分配了变量。
但在第二种情况下,全局变量被赋值(已经声明为),返回值为foo()。
数据部分的形成,文本部分都在编译期间发生。
全局变量将在数据部分(bss或初始化数据部分),所以在编译时,foo()不会被调用吗?并且在编译期间不知道foo()的返回值。
但第二种情况,当文本部分执行时,gvar
被赋值为返回值foo()。这是有效的。
答案 3 :(得分:0)
您可以这样想:当main()
启动时,所有全局变量必须已经具有初始化值。正如你所知,他们不能通过调用函数来获取这些函数,因为main()
实际上是在C程序中执行的地方。
答案 4 :(得分:0)
我们无法从函数外部调用任何函数。不像shell脚本。函数只允许从函数体内部调用。
在第一次执行从main()
开始,编译器不知道函数调用,如果它位于函数外部,它可以作为原型,如果arg和返回类型提供。
我们可以通过从main或其他功能块调用函数的返回值,到变量,调用的函数(那个全局)变量。
但我们可以根据需要在全局变量中使用宏。 为:
#define max() 12
int glob=max();
main()
{
}