2.3.4 变量初始化规则
#include "stdafx.h"
#include <iostream>
int num4;
int main()
{
std::cout << num4 << std::endl;
}
1. 内置类型变量的初始化
内置类型变量是否自动初始化取决于变量定义的位置。在函数体外定义的变量都初始化成0,在函数体里定义的内置类型变量不进行自动初始化。除了用作赋值操作符的左操作数,未初始化变量用作任何其他用途都是没有定义的。建议每个内置类型的对象都要初始化。虽然这样做并不总是必需的,但是会更加容易和安全,除非你确定忽略初始化式不会带来风险。
2. 类类型变量的初始化
如果定义某个类的变量时没有提供初始化式,这个类也可以定义初始化时的操作。它是通过定义一个特殊的构造函数即默认构造函数(default constructor)来实现的。
有些类类型没有默认构造函数。对于这些类型来说,每个定义都必须提供显示的初始化式。没有初始值是根本不可能定义这种类型的变量的。
2.3.5 声明和定义
变量的定义(definition)用于为变量分配存储空间,还可以为变量指定初始值。在一个程序中,变量有且仅有一个定义。
声明(declaration)用于向程序表明变量的类型和名字。定义也是声明:当定义变量时我们声明了它的类型和名字。可以通过使用extern关键字声明变量名而不定义它。不定义变量的声明包含对象名、对象类型和对象类型前的关键字extern。
extern声明不是定义,也不分配存储空间。事实上,它只是说明变量定义在程序的其他地方。程序中变量可以声明多次,但只能定义一次。
只用当extern声明位于函数外部时,才可以含有初始化式。
因为已初始化的extern声明被当作是定义,所以该变量任何随后的定义都是错误的。
在C++语言中,变量必须且仅能定义一次,而且在使用变量之前必须定义或声明变量。
任何在多个文件中使用的变量都需要有与定义分离的声明。在这种情况下,一个文件含有变量的定义,使用该变量的其他文件则包含该变量的声明(而不是定义)。
2.3.6 名字的作用域
用来区分名字的不同意义的上下文称为作用域(scope)。一个名字可以和不同作用域中的不同实体相关联。
大多数作用域是用花括号来界定的。
定义在所有函数外部的名字具有全局作用域(global scope),可以在程序中的任何地方访问。名字sum定义在main函数的作用域中,在整个main函数中都可以访问,但在main函数外则不能。变量sum有局部作用域(local scope)。名字val更有意思,它定义在for语句的作用域中,只能在for语句中使用,而不能在main函数的其他地方。它具有语句作用域(statement scope)。
C++中作用域可嵌套
名字还可以在内部作用域中重新定义,但局部变量最好使用不同的名字。
C++还有另外两种不同级别的作用域:类作用域(class scope)和命名空间作用域(namespace scope)。
2.3.7 在变量使用处定义变量
在对象第一次被使用的地方定义对象可以提高程序的可读性。
变量只有在从其定义处开始到该声明所在的作用域的结束处才可以访问。必须在使用该变量的最外层作用域里面或之前定义变量。