全局变量和局部变量的区别?

时间:2020-12-21 19:36:06
int a,b;
int n=10;
int func()
{
   int m=10;
   a=m*3;
   b=n*3;
   return 0;
}
int main()
{
   fumc();
   return 0;
}
以上这个程序的n和m变量的区别是什么?
比如效率上的差别?程序在执行的时候具体是怎么操作这两个变量的?

50 个解决方案

#1


就你这个程序而言,n和m没多大区别。但如果在大的工程里,全局变量和局部变量的区别就明显了。不过,就运行效率上看,是要求尽量少用全局变量的,特别是嵌入式编程更为注意。稍不留神就溢出

#2


局部变量只有当前作用域中有效,比如上面的m就只在func 中有效果
全局变量在整个project中有效,你在程序的任何地方都可以引用这个变量


硬是要比较访问效率的话,局部变量比较高

#3


在C++中,内存分成4个区,他们分别是堆,栈,静态存储区和常量存储区
  1)栈,就是那些由编译器在需要的时候分配,在不需要的时候自动清除的变量的存
    储区.里面的变量通常是局部变量,函数参数等.
  2)堆,又叫*存储区,它是在程序执行的过程中动态分配的,它最大的特性就是动.
    态性.由new分配的内存块,他们的释放编译器不去管,由我们的应用程序去控制,
    一般一个new就要对应一个delete.如果程序员没有释放掉,那么在程序结束后,
    操作系统会自动回收.如果分配了堆对象,却忘记了释放,就会产生内存泄漏.而
    如果已释放了对象,却没有将相应的指针置为NULL,该指针就是"悬挂指针".
  4)静态存储区.所有的静态对象,全局对象都于静态存储区分配.
  5)常量存储区,这是一块比较特殊的存储区,他们里面存放的是常量,不允许修改
    (当然,你要通过非正当手段也可以修改,而且方法很多)
    常量字符串都存放在静态存储区,返回的是常量字符串的首地址.

n是全局变量,储存在静态区.进入main函数之前就被创建.生命周期为整个源程序.
m是局部变量,在栈中分配.在函数func被调用时才被创建.生命周期为函数func内.
n只创建一次.
m每次调用func都会创建,函数结束就销毁.

对变量讨论效率没什么意义.



#4


主要是生命期的区别。时间效率没什么区别,栈上分配时间可以忽略。空间效率上,局部变量效率高。
全局变量会被自动初始化。
从空间效率和软件工程角度(例如,模块化、易于维护等等),尽量减少全局变量的使用。

#5


全局变量和局部变量作用域不一样,一个是全局都可以访问,一个是在一个函数内访问的,所以它们的生存期也不一样,全局变量的生命周期是永远(只要电路不断电),局部变量只在函数被调用到底是何零时创建的!
效率,我觉得两个没多大差别,具体要看汇编代码,看看对两种变量的寻址方式是否相同!

#6


当Cache命中的时候,CPU访问内存的效率是最高的

由于局部变量是存在栈中的,当一个函数占用的栈空间不是很大的时候,这部分内存很有可能全部命中cache,这时候CPU访问的效率是很高的。

相反,如果一个函数里既使用了全局变量又使用了局部变量,那么当这两段地址相差较大时,cpu cache需要来回切换,那么效率会下降。

所以不太好说全局还是局部变量的效率高

#7


1.访问M时,用到的是栈基地址寄存器BP作为段基地址,访问N时,用到的是数据段寄存器DS或者ES作为段基地址.
2.N的空间是程序载入内存时运行之前就分配好的.没有初始化的开销.M的空间是代码运行时分配的.需要至少一个指令周期为M分配空间.
3.N是全局的,因此它的在代码中只要不改变N的值那么N的值就永远不变,但是M是在栈内分配的,当函数返回后M的值有可能发生变化,但是M占的空间还是可以访问的.这也是为什么语言强制你不要使用作用域外的变量.你可以访问M的地址,但是你会发现即使你不对进行改变,它的值也随着程序的执行在发生变化,并且没有规律性.
4.从整个程序的效率上说,全局变量效率高,因为不执行时不用为它分配空间.但是从程序设计角度看,全局变量隐患较大,不便于维护.
5.单单从访问变量的效率上来说,全局变量分配的地址可能没有对齐.即整数的地址值不是4的倍数.这样访问效率不高.而局部变量的地址往往会经过编译器优化到与内存地址对齐,从而访问效率较高.

#8


区别在于生命期和作用域,效率上没有差别

#9


*和地方

#10


引用 6 楼 Chiyer 的回复:
当Cache命中的时候,CPU访问内存的效率是最高的

由于局部变量是存在栈中的,当一个函数占用的栈空间不是很大的时候,这部分内存很有可能全部命中cache,这时候CPU访问的效率是很高的。

相反,如果一个函数里既使用了全局变量又使用了局部变量,那么当这两段地址相差较大时,cpu cache需要来回切换,那么效率会下降。

所以不太好说全局还是局部变量的效率高

up

#11


引用 6 楼 Chiyer 的回复:
当Cache命中的时候,CPU访问内存的效率是最高的

由于局部变量是存在栈中的,当一个函数占用的栈空间不是很大的时候,这部分内存很有可能全部命中cache,这时候CPU访问的效率是很高的。

相反,如果一个函数里既使用了全局变量又使用了局部变量,那么当这两段地址相差较大时,cpu cache需要来回切换,那么效率会下降。

所以不太好说全局还是局部变量的效率高


这个很精辟

#12


#include <iostream>
#include <time.h>
using namespace std;
long double result=0.0;
int n=100000000;
int main()
{

long double pi;
clock_t t1 = clock();

int i;
long double x,h;
h = 1.0 / (long double) n;
for (i = 1;i <= n;i++)
{
x = h * ((long double)i - 0.5);
        result += 4.0 / (1.0 + x*x);
    }
pi =(1.0 / (long double) n) * result;
printf("pi = %lf\n",pi);
    clock_t t2=clock();
printf("time = %d ms\n",t2-t1);
return 0;
}
这个程序如果把你定义为全局变量和局部变量运行时间会有很大差别,这个是什么原因?具体是怎么造成这样的差距的?

#13


这个程序如果把n定义为全局变量和局部变量运行时间会有很大差别,这个是什么原因?具体是怎么造成这样的差距的?

#14


up

#15


引用 13 楼 licostar 的回复:
这个程序如果把n定义为全局变量和局部变量运行时间会有很大差别,这个是什么原因?具体是怎么造成这样的差距的?


这个跟编译器的优化实现由关系,在我这儿gcc编译的,两种情况基本没有差别

#16


这样啊,我是在vs里跑的

#17


vc中一个是1600ms,一个是3000多ms,的确差距很大,看了汇编后,发现在for循环中i <= n对比的时候,代码不同
1600ms的是:004012A2   cmp         ecx,dword ptr [n (00438dc0)]
3000ms的是:004012A6   cmp         ecx,dword ptr [ebp-0Ch]

具体什么意思,等高人来解释!

#18


1600ms中n的地址是固定的00438dc0,3000ms中,n的地址要通过ebp计算一下得到[ebp-0Ch],估计就是这次计算,累计消耗量1000多ms的时间!

#19


vs和vc跑的结果是反的,很诡异。咳,不知道具体原因?

#20


引用 19 楼 licostar 的回复:
vs和vc跑的结果是反的,很诡异。咳,不知道具体原因?

vs不就是vc吗?vs包含vb,vc,vc#等等啊!

#21


可是跑的结果就是不一样

#22


vc++6.0
vs2008
我在这两个平台运行的

#23


int a,b; 
int n=10; 
int func() 

  int m=10; 
  a=m*3; 
  b=n*3; 
  return 0; 

int main() 

  fumc(); 
  return 0; 


n是全局变量,可以在func() 和 main() 函数中使用,而m是func() 函数中的局部变量,只在func() 函数中作用,换句话说,m在其他的函数例如 main() 
函数中是不能用的;如果你在 main() 中再定义一个m,与前一个m是不一样的!

#24


全局变量和局部变量的区别主要在于生存周期不同,全局变量在整个程序生成期间可见,局部变量在自己的作用域内可见。全局变量的内存分配是静态的,位于PE文件在数据区,在main()前由C、C++运行期函数初始化,如果没有初值,会被初始化为0。局部变量的内存分配是动态的,位于线程堆栈中。如果没有初始化的,初值视当前内存内的值而定。

#25


直顶3楼

#26


引用 22 楼 licostar 的回复:
vc++6.0 
vs2008 
我在这两个平台运行的

VC6的编译器应该比VC8的编译器要差,毕竟微软也是在修改bug的!
我刚才又试了一下,在VC6中,如果使用release来编译的话,两种写法耗时是一样的都是1600ms左右,用debug来编译才会出现差异,所以那个二次寻址应该是为了调试使用的,造成了性能的损失!

#27


就局部变量和全局变量其实没那么复杂额
   n:文件作用域(从声明位置到文件尾),外部链接属性(一个或多个文件声明表示同一个实体)
   m:代码块作用域(从声明位置到当前代码块结束位置),空链接属性(一个或多个文件声明表示不同实体)

#28


除非深入编译器,否则就是生命周期和作用域的差别。

#29


引用 2 楼 Chiyer 的回复:
局部变量只有当前作用域中有效,比如上面的m就只在func 中有效果 
全局变量在整个project中有效,你在程序的任何地方都可以引用这个变量 


硬是要比较访问效率的话,局部变量比较高


应该是全局变量效率更高,因为局部变量是运行时才放入栈中的,入栈和出栈操作有更大的开销。全局变量是编译时就分配了空间的。

#30


引用 3 楼 ckt1120 的回复:
在C++中,内存分成4个区,他们分别是堆,栈,静态存储区和常量存储区 
  1)栈,就是那些由编译器在需要的时候分配,在不需要的时候自动清除的变量的存 
    储区.里面的变量通常是局部变量,函数参数等. 
  2)堆,又叫*存储区,它是在程序执行的过程中动态分配的,它最大的特性就是动. 
    态性.由new分配的内存块,他们的释放编译器不去管,由我们的应用程序去控制, 
    一般一个new就要对应一个delete.如果程序员没有释放掉,那么…

回答的很详细、很耐心。

#31


就是作用域和生命周期了。。。。少用全局变量。

#32


简单  全局变量自定义开始到文件结束有效

#33


学习下~~~

#34


凑个热闹也。

据我说知,据说局部变量比全局变量效率高,不过个人认为在32位“平坦”寻址空间中,这两种差别应该不会很大。

但是,本人观点,如果能够避免,就千万不要使用全局变量,如果没有全面掌握代码——谁会知道上一次更改到底发生在什么时间什么地点?

#35


回帖是一种美德!传说每天回帖即可获得 10W 分可用分!

#36


全局变量指从程序执行开始,一直到程序结束,它都存在。
局部变量指它只在它所在的那个作用域中起作用,离开那个作用域就消亡了。

#37


全局变量在程序中任何位置有效

局部变量只在其函数范围内有效

当局部变量和全局变量有冲突的时候

以 

局部变量优先

#38


能不能给我介绍下debug和release编译的区别,release编译把代买优化过了吗?

#39


讨论这个问题很无聊,反汇编看看不就知道了。

#40


jf

#41


趁此学习一下O(∩_∩)O哈哈~

#42


引用 38 楼 licostar 的回复:
能不能给我介绍下debug和release编译的区别,release编译把代买优化过了吗?

release肯定是优化过的,至于怎么优化,那是各个编译器的法宝了,呵呵!
一篇文章参考一下:http://itcase.blog.163.com/blog/static/50951420077141099546/

#43


主要是在生存期和作用域上的区别吧

#44


变量的作用域是不同的,多看几个实例就清楚了

#45


up

#46


up

#47


作用域不一样!

#48


我完全不懂。还要考试郁闷死了

#49


全局变量,固定地址,变量初始化,直接在程序的数据段里。程序结束,由操作系统收回。
局部变量,用编译器分配,在x86处理中,在堆栈中,函数调用结束,局部变量的位置被释放或被别的局部变量覆盖。局部变量的初始化占用一条汇编语句。

#50


给力呀!!你会的!!!!!主要就是作用域,不要想那么多!!!!!

#1


就你这个程序而言,n和m没多大区别。但如果在大的工程里,全局变量和局部变量的区别就明显了。不过,就运行效率上看,是要求尽量少用全局变量的,特别是嵌入式编程更为注意。稍不留神就溢出

#2


局部变量只有当前作用域中有效,比如上面的m就只在func 中有效果
全局变量在整个project中有效,你在程序的任何地方都可以引用这个变量


硬是要比较访问效率的话,局部变量比较高

#3


在C++中,内存分成4个区,他们分别是堆,栈,静态存储区和常量存储区
  1)栈,就是那些由编译器在需要的时候分配,在不需要的时候自动清除的变量的存
    储区.里面的变量通常是局部变量,函数参数等.
  2)堆,又叫*存储区,它是在程序执行的过程中动态分配的,它最大的特性就是动.
    态性.由new分配的内存块,他们的释放编译器不去管,由我们的应用程序去控制,
    一般一个new就要对应一个delete.如果程序员没有释放掉,那么在程序结束后,
    操作系统会自动回收.如果分配了堆对象,却忘记了释放,就会产生内存泄漏.而
    如果已释放了对象,却没有将相应的指针置为NULL,该指针就是"悬挂指针".
  4)静态存储区.所有的静态对象,全局对象都于静态存储区分配.
  5)常量存储区,这是一块比较特殊的存储区,他们里面存放的是常量,不允许修改
    (当然,你要通过非正当手段也可以修改,而且方法很多)
    常量字符串都存放在静态存储区,返回的是常量字符串的首地址.

n是全局变量,储存在静态区.进入main函数之前就被创建.生命周期为整个源程序.
m是局部变量,在栈中分配.在函数func被调用时才被创建.生命周期为函数func内.
n只创建一次.
m每次调用func都会创建,函数结束就销毁.

对变量讨论效率没什么意义.



#4


主要是生命期的区别。时间效率没什么区别,栈上分配时间可以忽略。空间效率上,局部变量效率高。
全局变量会被自动初始化。
从空间效率和软件工程角度(例如,模块化、易于维护等等),尽量减少全局变量的使用。

#5


全局变量和局部变量作用域不一样,一个是全局都可以访问,一个是在一个函数内访问的,所以它们的生存期也不一样,全局变量的生命周期是永远(只要电路不断电),局部变量只在函数被调用到底是何零时创建的!
效率,我觉得两个没多大差别,具体要看汇编代码,看看对两种变量的寻址方式是否相同!

#6


当Cache命中的时候,CPU访问内存的效率是最高的

由于局部变量是存在栈中的,当一个函数占用的栈空间不是很大的时候,这部分内存很有可能全部命中cache,这时候CPU访问的效率是很高的。

相反,如果一个函数里既使用了全局变量又使用了局部变量,那么当这两段地址相差较大时,cpu cache需要来回切换,那么效率会下降。

所以不太好说全局还是局部变量的效率高

#7


1.访问M时,用到的是栈基地址寄存器BP作为段基地址,访问N时,用到的是数据段寄存器DS或者ES作为段基地址.
2.N的空间是程序载入内存时运行之前就分配好的.没有初始化的开销.M的空间是代码运行时分配的.需要至少一个指令周期为M分配空间.
3.N是全局的,因此它的在代码中只要不改变N的值那么N的值就永远不变,但是M是在栈内分配的,当函数返回后M的值有可能发生变化,但是M占的空间还是可以访问的.这也是为什么语言强制你不要使用作用域外的变量.你可以访问M的地址,但是你会发现即使你不对进行改变,它的值也随着程序的执行在发生变化,并且没有规律性.
4.从整个程序的效率上说,全局变量效率高,因为不执行时不用为它分配空间.但是从程序设计角度看,全局变量隐患较大,不便于维护.
5.单单从访问变量的效率上来说,全局变量分配的地址可能没有对齐.即整数的地址值不是4的倍数.这样访问效率不高.而局部变量的地址往往会经过编译器优化到与内存地址对齐,从而访问效率较高.

#8


区别在于生命期和作用域,效率上没有差别

#9


*和地方

#10


引用 6 楼 Chiyer 的回复:
当Cache命中的时候,CPU访问内存的效率是最高的

由于局部变量是存在栈中的,当一个函数占用的栈空间不是很大的时候,这部分内存很有可能全部命中cache,这时候CPU访问的效率是很高的。

相反,如果一个函数里既使用了全局变量又使用了局部变量,那么当这两段地址相差较大时,cpu cache需要来回切换,那么效率会下降。

所以不太好说全局还是局部变量的效率高

up

#11


引用 6 楼 Chiyer 的回复:
当Cache命中的时候,CPU访问内存的效率是最高的

由于局部变量是存在栈中的,当一个函数占用的栈空间不是很大的时候,这部分内存很有可能全部命中cache,这时候CPU访问的效率是很高的。

相反,如果一个函数里既使用了全局变量又使用了局部变量,那么当这两段地址相差较大时,cpu cache需要来回切换,那么效率会下降。

所以不太好说全局还是局部变量的效率高


这个很精辟

#12


#include <iostream>
#include <time.h>
using namespace std;
long double result=0.0;
int n=100000000;
int main()
{

long double pi;
clock_t t1 = clock();

int i;
long double x,h;
h = 1.0 / (long double) n;
for (i = 1;i <= n;i++)
{
x = h * ((long double)i - 0.5);
        result += 4.0 / (1.0 + x*x);
    }
pi =(1.0 / (long double) n) * result;
printf("pi = %lf\n",pi);
    clock_t t2=clock();
printf("time = %d ms\n",t2-t1);
return 0;
}
这个程序如果把你定义为全局变量和局部变量运行时间会有很大差别,这个是什么原因?具体是怎么造成这样的差距的?

#13


这个程序如果把n定义为全局变量和局部变量运行时间会有很大差别,这个是什么原因?具体是怎么造成这样的差距的?

#14


up

#15


引用 13 楼 licostar 的回复:
这个程序如果把n定义为全局变量和局部变量运行时间会有很大差别,这个是什么原因?具体是怎么造成这样的差距的?


这个跟编译器的优化实现由关系,在我这儿gcc编译的,两种情况基本没有差别

#16


这样啊,我是在vs里跑的

#17


vc中一个是1600ms,一个是3000多ms,的确差距很大,看了汇编后,发现在for循环中i <= n对比的时候,代码不同
1600ms的是:004012A2   cmp         ecx,dword ptr [n (00438dc0)]
3000ms的是:004012A6   cmp         ecx,dword ptr [ebp-0Ch]

具体什么意思,等高人来解释!

#18


1600ms中n的地址是固定的00438dc0,3000ms中,n的地址要通过ebp计算一下得到[ebp-0Ch],估计就是这次计算,累计消耗量1000多ms的时间!

#19


vs和vc跑的结果是反的,很诡异。咳,不知道具体原因?

#20


引用 19 楼 licostar 的回复:
vs和vc跑的结果是反的,很诡异。咳,不知道具体原因?

vs不就是vc吗?vs包含vb,vc,vc#等等啊!

#21


可是跑的结果就是不一样

#22


vc++6.0
vs2008
我在这两个平台运行的

#23


int a,b; 
int n=10; 
int func() 

  int m=10; 
  a=m*3; 
  b=n*3; 
  return 0; 

int main() 

  fumc(); 
  return 0; 


n是全局变量,可以在func() 和 main() 函数中使用,而m是func() 函数中的局部变量,只在func() 函数中作用,换句话说,m在其他的函数例如 main() 
函数中是不能用的;如果你在 main() 中再定义一个m,与前一个m是不一样的!

#24


全局变量和局部变量的区别主要在于生存周期不同,全局变量在整个程序生成期间可见,局部变量在自己的作用域内可见。全局变量的内存分配是静态的,位于PE文件在数据区,在main()前由C、C++运行期函数初始化,如果没有初值,会被初始化为0。局部变量的内存分配是动态的,位于线程堆栈中。如果没有初始化的,初值视当前内存内的值而定。

#25


直顶3楼

#26


引用 22 楼 licostar 的回复:
vc++6.0 
vs2008 
我在这两个平台运行的

VC6的编译器应该比VC8的编译器要差,毕竟微软也是在修改bug的!
我刚才又试了一下,在VC6中,如果使用release来编译的话,两种写法耗时是一样的都是1600ms左右,用debug来编译才会出现差异,所以那个二次寻址应该是为了调试使用的,造成了性能的损失!

#27


就局部变量和全局变量其实没那么复杂额
   n:文件作用域(从声明位置到文件尾),外部链接属性(一个或多个文件声明表示同一个实体)
   m:代码块作用域(从声明位置到当前代码块结束位置),空链接属性(一个或多个文件声明表示不同实体)

#28


除非深入编译器,否则就是生命周期和作用域的差别。

#29


引用 2 楼 Chiyer 的回复:
局部变量只有当前作用域中有效,比如上面的m就只在func 中有效果 
全局变量在整个project中有效,你在程序的任何地方都可以引用这个变量 


硬是要比较访问效率的话,局部变量比较高


应该是全局变量效率更高,因为局部变量是运行时才放入栈中的,入栈和出栈操作有更大的开销。全局变量是编译时就分配了空间的。

#30


引用 3 楼 ckt1120 的回复:
在C++中,内存分成4个区,他们分别是堆,栈,静态存储区和常量存储区 
  1)栈,就是那些由编译器在需要的时候分配,在不需要的时候自动清除的变量的存 
    储区.里面的变量通常是局部变量,函数参数等. 
  2)堆,又叫*存储区,它是在程序执行的过程中动态分配的,它最大的特性就是动. 
    态性.由new分配的内存块,他们的释放编译器不去管,由我们的应用程序去控制, 
    一般一个new就要对应一个delete.如果程序员没有释放掉,那么…

回答的很详细、很耐心。

#31


就是作用域和生命周期了。。。。少用全局变量。

#32


简单  全局变量自定义开始到文件结束有效

#33


学习下~~~

#34


凑个热闹也。

据我说知,据说局部变量比全局变量效率高,不过个人认为在32位“平坦”寻址空间中,这两种差别应该不会很大。

但是,本人观点,如果能够避免,就千万不要使用全局变量,如果没有全面掌握代码——谁会知道上一次更改到底发生在什么时间什么地点?

#35


回帖是一种美德!传说每天回帖即可获得 10W 分可用分!

#36


全局变量指从程序执行开始,一直到程序结束,它都存在。
局部变量指它只在它所在的那个作用域中起作用,离开那个作用域就消亡了。

#37


全局变量在程序中任何位置有效

局部变量只在其函数范围内有效

当局部变量和全局变量有冲突的时候

以 

局部变量优先

#38


能不能给我介绍下debug和release编译的区别,release编译把代买优化过了吗?

#39


讨论这个问题很无聊,反汇编看看不就知道了。

#40


jf

#41


趁此学习一下O(∩_∩)O哈哈~

#42


引用 38 楼 licostar 的回复:
能不能给我介绍下debug和release编译的区别,release编译把代买优化过了吗?

release肯定是优化过的,至于怎么优化,那是各个编译器的法宝了,呵呵!
一篇文章参考一下:http://itcase.blog.163.com/blog/static/50951420077141099546/

#43


主要是在生存期和作用域上的区别吧

#44


变量的作用域是不同的,多看几个实例就清楚了

#45


up

#46


up

#47


作用域不一样!

#48


我完全不懂。还要考试郁闷死了

#49


全局变量,固定地址,变量初始化,直接在程序的数据段里。程序结束,由操作系统收回。
局部变量,用编译器分配,在x86处理中,在堆栈中,函数调用结束,局部变量的位置被释放或被别的局部变量覆盖。局部变量的初始化占用一条汇编语句。

#50


给力呀!!你会的!!!!!主要就是作用域,不要想那么多!!!!!