- 名字的作用域分为:全局作用域和块作用域
- 如果一个名字(例如main,函数名)首次出现的位置的前几行离它最近的大括号是”后大括号“(”}“)则有全局作用域。它在整个程序的范围均可用。
- 如果一个名字(例如局部变量)首次出现的位置的前几行离它最近的大括号是”前大括号“(”{“)或则是关键词(例如for)则有块作用域。它的作用域是该前大括号为起始,与前大括号配对的后大括号为止,或则关键字体内(for循环体内)
- 如果一个对象处于全局作用域中,则该对象即便不初始化系统也会隐式的给它赋予相应的初值。
(1)如果该对象是vector容器,则使用该容器则将产生Debug(例如打 印它第一个元素)
1 vector<string>vec;//在全局作用域中定义一个未初始化的容器
1 int main() 2 { 3 auto it = vec.begin(); 4 cout << *it << endl; 5 }
则结果为:
(2)如果是数组的话在全局作用域不将其初始化,系统则会隐式的给数组初始化对应的值。
1 int a[4];//全局作用域下定义数组 2 string b[4];//全局作用域下定义数组
1 int main() 2 { 3 cout << a[0] << endl; 4 cout << b[0] << endl; 5 }
结果为:
- 如果一个对象处于块作用域中,如果该对象是string或则string数组,则系统将隐式初始化该对象(空字符串)或则将数组中每个元素都赋予空字符串,下面的语句也可以使用它。如果是其他基本类型则系统不会将它初始化,下面的语句如果使用它则会报错,如果是其他基本类型的数组的话,下面使用它不会报错但将产生意想不到的结果(比如使用cout输出,会输出未知的值)
这也就引出另外一个知识点:
在switch语句中不允许在case分支初始化任何对象;不允许在case分支中定 义string对象和string数组和任何vector容器,因为这个时候系统会隐式初始化该string对象和数组,这显然是不允许的,容器的话未知;可以在case分支中定义除string和string数组外的对象和数组,但是在其他case分支中最好先初始化它再对它使用,否则将输出意想不到的结果。
1 int main() 2 { 3 int i = 0; 4 switch (i) 5 { 6 case 0: 7 string a; 8 case 1: 9 ; 10 default: 11 break; 12 } 13 14 15 }
如果一定要定义string对象和数组,或则初始化一个对象的话,应该在该case分支中加入花括号单独成一个作用域,这样其他分支也不能使用该对象(因为在作用域外)