4.8 数据类型的声明
声明(declaration)用于向程序表明变量的类型和名字。声明是告诉编译器有一个变量或函数,并标明是什么类型的。简单点来说,声明是一条语句,声明是为对象起了一个名字,同时为名字确定了一个类型。
4.8.1 声明和定义的区别
在编译器中,声明就是向程序表明变量的类型和名字。而变量的定义就是为变量分配存储空间,还可为变量指定初始值。在程序中,变量有且仅有一个定义。
在声明和定义变量时需要注意以下几点:
(1)定义也是声明,关键字extern声明不是定义,即不分配存储空间。extern告诉编译器变量在其他地方定义了。
例如:
(2)如果声明有初始化时,就被当作定义,即使前面加了extern。只有当extern声明位于函数外部时,才可以被初始化。
例如:
extern double PI=3.1415926; //定义变量PI
(3)函数的声明和定义区别比较简单,带有{ }的就是定义,否则就是声明。
例如:
4.8.2 初始化
初始化是在声明一个变量的同时赋予它一个值,而赋值是已经声明过了变量,后续再对它进行赋值操作。
例如:
对于在一个块作用域中的局部变量来说,该变量会默认初始化。而内置类型默认初始化的时候,对其进行操作是违法的,编译器也会进行报错。
例如,在全局中进行初始化:
int i; //正确, i会被值初始化为.0, 也称为零初始化
静态变量在编译期间就可以确定它们的值,静态变量即使不提供初始值也会被零初始化。此外,类内静态变量同样如此,不过显式初始化是一个比较好的选择。
4.8.3 作用域
C++变量根据定义位置的不同,具有不同的作用域,作用域可分为5种:全局作用域、局部作用域、类作用域、命名作用域和文件作用域。
1. 从作用域区别
(1)全局变量具有全局作用域。全局变量只需在一个源文件中定义,就可以作用于所有的源文件。当然,其他不包括全局变量定义的源文件需要用extern关键字再次声明这个全局变量。
(2)静态局部变量具有局部作用域。它只被初始化一次,从第一次初始化直到程序结束都一直存在,它和全局变量的区别在于全局变量对于所有的函数都是可见的,而静态局部变量只对定义自己的函数始终可见。
(3)局部变量也只有局部作用域,它是自动对象,在程序运行期间不是一直存在的,而是只在函数执行期间存在,函数的第一次调用结束后,变量就被撤销,其所占用的内存也被收回。
(4)静态全局变量也具有全局作用域,它与全局变量的区别在于如果程序包含多个文件,它只作用于定义它的文件里,不能作用到其他文件里,被static关键字修饰的变量就具有文件作用域。这样即使两个不同的源文件都定义了相同的静态全局变量,它们也是不同的。
2. 从分配内存空间区别
全局变量、静态局部变量、静态全局变量都在静态存储区分配空间,而局部变量在栈区分配空间。
全局变量本身就是静态存储方式,静态全局变量当然也是静态存储方式,这两者在存储方式上没有什么不同。区别在于非静态全局变量的作用域是整个源程序,当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都有效。而静态全局变量限制了其作用域,即只在定义该变量的源文件内有效,在同一源程序的其他源文件中不能使用。由于静态全局变量的作用域限于一个源文件内,只能为该源文件内的函数共用,因此可以避免在其他源文件中引起错误。
(1)静态变量会被放在程序的静态数据存储区里,这样在下一次调用的时候还可以保持原来的赋值。这一点是它与堆栈变量的区别。
(2)变量用static告知编译器,自己仅仅在变量的作用域范围内可见,这一点是它与全局变量的区别。