您现在的位置是:首页 >技术杂谈 >c++报错:does not name a type全局变量不能赋值问题分析网站首页技术杂谈
c++报错:does not name a type全局变量不能赋值问题分析
C++中,全局变量只能声明、初始化,而不能赋值.这是为什么?
在C++中,全局变量的生命周期是由静态存储类别控制的。静态存储类别分为四种:auto、register、static和extern。
-
auto:auto是C++11中新增的关键字,用于自动推断变量的存储类别。如果没有显式指定存储类别,则默认为auto。auto变量的生命周期与其所处的作用域相同。
-
register:register表示该变量的存储方式是寄存器(register),即存储在CPU的寄存器中。register变量的生命周期与其所处的作用域相同。
-
static:static表示该变量的存储方式是静态存储(static storage),即存储在程序的数据段中。静态变量的生命周期在整个程序执行期间都存在,因此可以在函数内部对其进行修改。
-
extern:extern表示该变量的存储方式是外部链接(external linkage),即该变量的定义存在于其他文件中。当多个源文件包含同一个头文件时,编译器会将所有定义都合并到一个对象文件中,然后在程序运行时使用这个对象文件中的定义。
对于全局变量来说,如果没有显式指定存储类别,则默认为static存储类别。因为全局变量的生命周期将持续到整个程序执行结束,所以它们必须在整个程序运行期间保持有效的状态。因此,我们不能在编译时对全局变量进行重新赋值,以避免可能存在的错误或不一致的状态。
另外,由于全局变量是在编译时进行初始化的,因此它们的值必须在编译时确定。如果我们在程序运行期间对全局变量进行重新赋值,那么这可能会导致不可预期的行为和错误。例如,如果我们在程序运行期间对一个全局数组进行了重新分配内存,那么这可能会导致数组元素被破坏或丢失。因此,为了保证程序的正确性和稳定性,C++中全局变量只能声明和初始化,而不能赋值。
下面我们来看代码:
#include <iostream>
using namespace std;
int a;
a = 2;//这里会报错!
int main() {
return 0;
}
上面代码会报错:
test.cpp:4:1: error: ‘a’ does not name a type
a = 2;//这里会报错!
^
在函数内赋值则不会报错
#include <iostream>
using namespace std;
int a;
//a = 2;
void add()
{
a=9; //这里是可以的
a++;
cout<<"add a++:" <<a <<endl;//这里输出9
}
int main() {
a = 3;//这里是可以的
add();//无论主函数调用与否,在函数里赋值全局变量都不会报错
return 0;
}
分析:
在函数中赋值全局变量不会报错的原因是,C++编译器会将全局变量的作用域限定在函数内部。具体来说,当一个函数被调用时,编译器会为该函数分配一块独立的内存空间,用于存储函数的局部变量和全局变量。因此,在函数内部对全局变量进行赋值操作实际上是在为该全局变量重新分配内存空间,而不是在函数内部创建一个新的全局变量。
如果使用了extern关键字,也是一样的
在C++中,全局变量的extern关键字可以用于声明和定义。具体来说,使用extern关键字声明全局变量时,编译器会在编译时检查该变量是否已经定义过,如果没有定义过,则会自动定义一个外部链接的全局变量。
在使用extern关键字定义全局变量时,需要在函数或主函数中进行初始化。这是因为在C++中,全局变量必须在程序开始运行之前进行初始化。如果没有进行初始化,那么程序可能会出现未定义的行为。
至于为什么不能对全局变量进行赋值,原因与静态变量一样。因为全局变量在整个程序执行期间都存在,因此可以在程序运行期间对其进行修改。但是,由于全局变量是在编译时进行初始化的,因此它们的值必须在编译时确定。如果我们在程序运行期间对全局变量进行重新赋值,那么这可能会导致不可预期的行为和错误。因此,C++中规定全局变量只能声明和初始化,而不能赋值。