全局变量编译器规则
‘壹’ 如何在c语言中定义及引用全局变量
1、全局变量也称为外部变量,它是在函数外部定义的变量。
它不属于哪一个函数,它属于一个源程序文件。其作用域是整个源程序。在函数中使用全局变量,一般应作全局变量说明。
只有在函数内经过说明的全局变量才能使用。全局变量的说明符为extern。
但在一个函数之前定义的全局变量,在该函数内使用可不再加以说明。外部变量是在函数外部定义的全局变量,它的作用域是从变量的定义处开始,到本程序文件的
结尾。在此作用域内,全局变量可为各个函数所引用。编译时将外部变量分配在静态存储区。
有时需要在其他文件中使用extern来声明外部变量,以扩展外部变量的作用域。
也可用static声明外部变量,使该变量不能被其他文件引用。有时候他们是一样的,只有稍微一点的区别而已,不用太过于区分的。
2、定义及引用方法:
#ifdef xxx_GLOBALS
#define xxx_EXT#else#define xxx_EXT extern
#endif 上面位于.H 文件中,每个全局变量都加上了xxx_EXT的前缀,xxx代表模块的名字。该模块的.C文件中有以下定义:#define xxx_GLOBALS
当编译器处理.C文件时,它强制xxx_EXT(在相应.H文件中可以找到)为空,(因为xxx_GLOBALS已经定义)。所以编译器给每个全局变量分配内存空间,而当编译器处理其他.C文件时,xxx_GLOBAL没有定义,xxx_EXT被定义为extern,这样用户就可以调用外部全局变量。进阶:在abc.H:#ifdef abc_GLOBALS
#define abc_EXT#else
#define abc_EXT extern#endif
abc_EXT unsigned int Ctr;
同时,abc.H有中以下定义:#define abc_GLOBALS
当编译器处理abc.C时,它使得头文件变成如下所示,因为abc_EXT被设置为空。unsigned int Ctr;
这样编译器就会将这些全局变量分配在内存中。当编译器处理其他.C文件时,头文件变成了如下的样子,因为abc_GLOBAL没有定义,所以abc_EXT被定义为extern。extern unsigned int Ctr;
在这种情况下,不产生内存分配,而任何 .C文件都可以使用这些变量。这样的就只需在 .H 文件中定义一次就可以了。
‘贰’ C语言中如何定义全局变量
1、首先,我们可以在函数外面定义变量,就是全局变量。
‘叁’ 操作系统和编译器是怎么识别全局变量和局部
操作系统,只管调度进程,线程编译器根据编程语言的定义,确定变量的作用于,存储类型,生命周期!
定义在函数外部的变量,只有文件静态变量,和外部变量
外部变量,是实实在在的全局变量,不论作用域还是生命周期。
静态变量是局部作用域的,生命周期为,程序的生命周期的变量。
自动变量和函数参数,是局部作用域的生命周期为函数结束的局部变量。
寄存器变量,用register定义,是局部变量;
函数内部的静态变量,语句组内部的静态变量,局部作用域的,生命周期为,程序的生命周期的变量。
静态变量,编译器,可以通过static关键字知道。
自动变量,1)函数内部定义的非静态变量,非寄存器变量是自动变量。
2)函数参数,只能是自动变量,不过也可能定义在寄存器中。
这和调用约定有关,因此不可以用register定义。
C语言没有全局变量这种数据类型。
只有4种存储类型,和变量的作用域与生命周期的概念。
C++同样没有全局变量这种数据类型。
有另外的两种作用域
1)namespace作用域。
2)类(类型)作用域。
C只有全局,文件,函数以及函数内部的语句组,4种逐渐缩小的作用域。
其中内层,对外部作用域,具有完全的遮蔽作用。
C++可以通过作用域限定符,区分不同作用域(类,名空间)的名字。
类作用域,可以通过访问权限,限制外部的访问权。
函数作用域(语句组作用域)是封闭的作用域,外部不可以使用函数内部定义的名字。
也不会和外部有命名冲突,只会遮蔽外部的名字。
类作用于,和名空间由于访问方式不同,命名冲突和遮蔽有些特殊。
函数和全局域,基本不会和类作用域有命名冲突,除非类方法内部。
命名空间,可以避免命名冲突。
类继承体系中,则有遮蔽现象。
还有访问权限问题。
实际上,全局变量,有两个概念可以判定
1)作用域(空间)===>由定义和声明位置,和定义和声明使用的关键字决定。
2)生命周期(时间)===>外部和静态变量,的生命周期是全局的,从初始化到程序结束。
函数参数,和函数局部非静态变量,是局部变量
函数参数的传递,是跨函数的(实参,变成形参);
函数内部定义的,局部变量,只有定义处可见,作用域是函数甚至语句组局部,
其中静态变量,生命周期是全局的,非静态是函数甚至语句组的。
全局变量,不是C,C++的概念。
而是,使用编程语言的程序员的概念。
所以,全局变量和C,C++的存储类型,作用域,生命周期等,不是一一对应的概念。
所以,可以有不同的理解。
所以这个概念是很模糊的,不清晰的。
比如局部静态变量,类的静态变量,是否全局变量,就不是可以清晰的说明的。
‘肆’ 全局变量和局部变量有什么区别是怎么实现的
1、 全局变量的作用用这个程序块,而局部变量作用于当前函数
2、前者在内存中分配在全局数据区,后者分配在栈区
3、 生命周期不同:全局变量随主程序创建和创建,随主程序销毁而销毁,局部变量在局部函数内部,甚至局部循环体等内部存在,退出就不存在歼御
4、 使用方式不同:通过声明后全局变量程序的各个部分都可以用到,局部变量只能在局部使用
操作系统和编译器通过内存分配的氏早岩位置来知道的全局变量分配在全局数据段,并且在程序被运行的时候就被加载。
编译器通过语法词法的分析,判断出是全局变量还是局部变量。如果是全局变量的话,编译器在将源代码翻译成二进制代码时就为全局变量分配好一个虚拟地址 (windows下0x00400000以上的地址,也就是所说的全局区),所以程序在对全局变量的操作时是睁配对一个硬编码的地址操做。
局部变量的话,编译时不分配空间,而是以相对于ebp或esp的偏移来表示局部变量的地址,所以局部变量内存是在局部变量所在的函数被调用时才真正分配。 以汇编的角度来看:函数执行时,局部变量在栈中分配,函数调用完毕释放局部变量对应的内存,另外局部变量可以直接分配在寄存器中。
操作系统通过变量的分配地址就可以判断出是局部变量和全局变量。
‘伍’ vs2022如何定义全局变量
vs2022如何定义全局变量:
在开始讲解函数之前,我们理解的变量就是在内存中开辟一个存储数据的位置,并给它起个名字,因为只有一个main函数,所以我们才对它的作用范围一无所知,觉得定义了变量就可以随时随地地使用它。学习函数之后发现不同的函数定义的变量,它们是无法相互进行访问的。
在上面的代码中func函数有一个参数,两个变量,他们的作用范围仅限于func函数的内部,在main函数中无法访问参数a以及变量b和c。同样在func函数中也无法访问在main函数里边定义的m和n两个变量。另外在func函数的内部还有一个复合语句(for语句以及其体内用大括号包裹的若干语句构成一个复合语句),在for语句的第一个表达式部分声明变量i(C99标准),它的作用范围仅限于复合语句的内部。
在main函数中定义了两次i变量,但编译器竟然通过了(在同一个函数中重复定义同名变量是不允许的),这是因为第二个变量i是定义于for语句构成的复合语句中,它的作用范围仅限于for循环体的内部,所以两者并不会发生冲突。
这里for语句因为定义了同名的i变量,所以它屏蔽了第一个定义的i变量。在for语句循环体重,无法直接访问到外边的i变量。C语言是允许在程序中“随处”声明变量的。允许变量在需要时才声明这是一个很棒的特性,因为当函数体非常庞大的时候没有人会团旁愿意往前翻好几页的代码去看某个变量的注释。不用担心重复定义(编译器会找出重复定义的变量并且报错),所以只管使用就可以了全局变量在函数里面定义的变量称为局部变量;在函数外面定义的变量称为外部变量,也叫做全局变量,因为全局变量可以被本程序中其他函数所共用。
这个count 变量定义于函数之外,他就是全局变量。它的作用范围是整个程序,所以无论是main函数还是a,b,c函数,都可以对它进行访问和修改,这样一来,全局变量无疑就拓宽了函数之间交流的渠道。与局部变量不同,如果不对全局变量进行初始化,那么它塌枯橡会自动初始化为零。如果在函数的内部存在一个与全局变量同名的局部变量,编译器并不会报错,而是在函数中屏蔽全局变量(也就是说在这个函数中,同名局部变量将代替全局变量)
程序定义了a和b两个全局变量,其中a并没有对其进行初始化。进入main函数后,先打印a和b的值,发现a默认被初始化为零。接着调用func函数,恰好func函数中定义了于全局变量同名的局部变量b。由于出现了同名的局部变量,所以对应的全局变量b的值。最后回到main函数,打印的是两个全局变量的值,发生在func函数中对b进行修改,并不会影响全局变量的值。如果一个全局变量在函数定以后才被定义,编译器就会报错。
因为编译器对代码的解读是从上到下的,所以func函数中,没有发现前面有count函数的定义,就会报错‘count变量未定义’。对于这种情况,就可以在func函数中,用extern关键字对后面定义的count全局变量进行修饰。这样就相当于告诉编译器: 这个变量在后面才定义,先别急着报错。
不要大量使用全局变败山量
(1)使用全局变量会使程序占用更多的内存。因为全局变量从被定义开始,直到程序退出才被释放; 而局部变量是当函数调用完成即可释放。现在使用C语言开发,要么是非常的注重效率的驱动,底层开发,要么是嵌入式开发,都是“寸土寸金”的领域。等学到结构体,定义出来的变量可就不是只占用一点儿的空间。(2)污染命名空间。虽然局部变量会屏蔽全局变量,但是这样一来也会降低程序的可读性,往往很难一下子判断每个变量的含义和作用范围。(3)提高了程序的耦合性。使用全局变量会牵一发而动全身,时间久了,代码长了,连自己都不知道全局变量被哪些函数修改过。在模块化程序设计指导下应该尽量设计内聚性强,耦合性弱的模块,也就是要求函数的功能要尽量单一与其他函数的相互影响尽可能地少,而大量使用全局变量会正好相反。
‘陆’ C/C++里面的全局变量是不是每运行一下,那个值要变
首先全局变量的值不加以认为改动,不会改变。
其次全局变量的值在子函数中改动也会影响到主函数。
最后在以个函数中纤行,重新定义了一个与全局变量的变量名相同纤陵的变量时,会在这个函数里蔽屏掉全局变量,一出这个函数就恢复正常。
#include<stdio.h>
int
a=1;
int
n(int
p)
{
p=12;
}
main()
{
printf("%d\n",a);
a=n(a);
printf("%d\n",a);
int
a;
printf("%d\n",a);
}
运行结果是毁竖哗:
‘柒’ 编译器编译高级语言为低级语言的时候,给全局变量或静态变量是如何分配内存的
对于C和C++的编译器,全局变量和静态变量都是在专门的数据区保存的,更具体一点,一般是在.data和.bss段保存的,具体在哪个段,编译器会根据代码中是否对这些变量进行了初始化来决定,如果初始化过,并且初始化的值不为0,那么这个这个变量一般就会被放在编译结果的.data段中,否则就是放在.bss段中。
.data段中就保存变量的符号,还保存变量的初始化值,而在.bss段中,只保存变量的符号,而不保存值,这是因为这部分的变量都将被初始化为0,这也是为什么static声明的变量即使没有初始化也会是0的原因。
这些段都会在程序被执行的时候由操作系统(或链接器)加载到指定的内存中,便完成相应的初始化。
‘捌’ python函数中局部变量与全局变量遵守规则
(1)简键山银单数据类型变量唯哗无论是否与全局变量重名,仅在函数内部创建和使用,函数退出后变量被释放,如有全局同名变量,其值不变。
(2)简单数据类型变量在用global保留字声明后,作为全局变量使用,函数退出后该变量保留且值被函数改变。
(3)对于组合数据类型的全局变量,如果在函数内部没有被真实创建的同名变量,则函数内部可以直接使用并修改全局变量的值。
(4)如果函数内部真实创建了组合数据类稿宴型变量,无论是否有同名全局变量,函数仅对局部变量进行操作,函数退出后局部变量被释放,全局变量值不变。
*《python语言程序设计基础》.高等教育出版社
‘玖’ C语言怎样定义和声明全局变量和函数最好
定义是分配空间并赋初值(如轮氏果有) 的声明。最好的安排是在某个相关的.c 文件中定义, 然后在头文件(.h) 中进行外部声明, 在需要使用的时候, 只要包含对应的头文件即可。定义变量的.c 文件也应该包含该头文件, 以便编译器检查定义和声明的一致性。这条规则提供了高度的可移植性: 它和ANSI C 标准一致, 同时也兼容大多数ANSI 前的编译器和连接器。Unix 编译器和连接器通常使用“通用模式” 允许多重定义, 只帆桐枝要保证最多对一处进行初始化就可以了; ANSI C 标准称这种行为为“公共扩展”, 没有语带双关的意思。
可以使用预处理技巧来使类似DEFINE(int, i);的语句在一个头文件中只出现态敏一次, 然后根据某个宏的设定在需要的时候转化成定义或声明。但不清楚这样的麻烦是否值得。如果希望让编译器检查声明的一致性, 一定要把全局声明放到头文件中。特别是, 永远不要把外部函数的原型放到.c 文件中: 通常它与定义的一致性不能得到检查, 而矛盾的原型比不用还糟糕。
‘拾’ 全局变量在编译时怎么分配空间
关于这个问题,全局变量(成员变量)是在创建对象的时候分配内存的创建对象过程为1分配空间2递归的创建父类对象(无父类这步可省略)3初始化成员变量4调用构造方法创建一个对象
静态变量是在类加载的时候分配空间的,静态变量和对象没有关系是在jvm第一次读到一个类的时候加载信息的过程中分配空间的类加载过程为1加载父类(如果父类已经加载过,则不在加载)2初始化静态属性3按顺序的初始化静态代码块
初始化的前提就是分配空间
而且静态变量在以后的创建对象的时候不在初始化所以一般用静态来保存共享信息
希望对你有所帮助