经验分享 从C到C++(一)(1)(2)
3.即时声明
这是笔者杜撰的一个术语,它的原文为declarations mixed with statements,意即允许变量的声明与语句的混合使用。传统C程序提倡用户将声明和语句分开,如下形式:
- int i=100;
- float f; //declarations
- i++;
- f=1.0/i; //statements
而C抛弃这点可读性,允许用户采取更自由的书写形式:
- int i=100;
- i++;
- float f =1. 0/i;
即时声明常见于for循环语句中:
- for(int i = 0; i < 16; i++)
- for(int j = 0; j < 16; j++)
- putpixel(j i Color[i][j]);
这种形式允许在语句段中任点声明新的变量并不失时机地使用它(而不必在所有的声明结束之后)。
特别地,C++强化了数据类型的类概念,对于以上出现的“int i=1 j=2;”完全可以写成:int i(1) j (2);再如:
- char * Stringl("Youth Studio.”);
- char String2[]("Computer Fan.“);
这不属于“即时声明”的范畴,但这些特性足以让你的代码与先前愚昧的C产品区别开来。
4.作用域(scope)及其存取操作符(scope qualifier operator)
即时声明使C语言的作用域的概念尤显重要,例如以下语句包含着一条错误,因为ch变量在if块外失去了作用域。
- if(ok)
- char ch='!';
- else
- ch='?'; //error. access outside condition
- 作用域对应于某一变量的生存周期,它通常表现为以下五种:
- 块作用域:开始于声明点,结束于块尾,块是由{}括起的一段区域
- 函数作用域:函数作用域只有语句标号,标号名可以和goto语句一起在函数体任何地方
- 函数原型作用域:在函数原型中的参量说明表中声明的标识符具有函数原型作用域
- 文件作用域:在所有块和类的外部声明的标识符(全局变量)具有文件作用域
- 类作用域:类的成员具有类作用域
具有不同作用域的变量可以同名,如test02:
- //test02.cpp
- #include <iostream.h>
- int i=0;
- void main()
- {
- cout << i << ' '; //global 'int i' visible
- {
- float i(0.01); //global 'int i' overrided
- cout<< i << ' ';
- }
- cout<<i<<endl; //global 'int i' visible again
- }
- //输出结果 0 0.01 0
编译器并未给出错误信息。
作用域与可见性并不是同一概念,具有作用域不一定具有可见性,而具有可见性一定具有作用域。
在test02中,float i的使用使全局int i失去可见性,这种情形被称作隐藏(override)。但这并不意味着int i失去了作用域,在main()函数运行过程中,int i始终存在。
有一种办法来引用这丢了名份的全局i,即使用C++提供的作用域存取操作符::,它表示引用的变量具有文件作用域,如下例程:
- //test03.cpp
- #include <iostream.h>
- enum {boy girl};
- char i = boy;
- void main()
- {
- {
- float i(0.01);
- cout << "i=" << i << endl;
- ::i=girl; //modify global 'i'
- }
- cout << "I am a " << (i ? "girl." : "boy.");
- }
- 输出结果:
- i=0.01
- I am a girl.
在上例中,通过::操作符,第8行语句偷偷地改写了i所属的性别。更妙的是,::之前还可以加上某些类的名称,它表示引用的变量是该类的成员。
- 上一篇:C++入门之谈前置++与后置++的区别
- 下一篇:经验分享 C++编程技巧