6.2 const
面试例题1:What does the keyword "const" means in C program Please at least make two examples about the usage of const.(const 有什么用途?请至少说明两种。)[中国台湾某著名CPU生产公司2005年面试题]
解析:在C程序中,const的用法主要有定义常量、修饰函数参数、修饰函数返回值。在C++(www.cppentry.com)程序中,它还可以修饰函数的定义体,定义类中某个成员函数为恒态函数,即不改变类中的数据成员。
答案:(1)可以定义const常量。(2)const可以修饰函数的参数和返回值,甚至函数的定义体。被const修饰的东西都受到强制保护,可以预防意外的变动,能提高程序的健壮性。
面试例题2:const与#define相比有什么不同?
答案:C++(www.cppentry.com)语言可以用const定义常量,也可以用#define定义常量,但是前者比后者有更多的优点:
const常量有数据类型,而宏常量没有数据类型。编译器可以对前者进行类型安全检查,而对后者只进行字符替换,没有类型安全检查,并且在字符替换中可能会产生意料不到的错误(边际效应)。
有些集成化的调试工具可以对const常量进行调试,但是不能对宏常量进行调试。在C++(www.cppentry.com)程序中只使用const常量而不使用宏常量,即const常量完全取代宏常量。
扩展知识
常量的引进是在早期的C++(www.cppentry.com)版本中,当时标准C规范正在制订。那时,常量被看做一个好的思想而被包含在C中。但是,C中的const的意思是"一个不能被改变的普通变量"。在C中,它总是占用内存,而且它的名字是全局符。C编译器不能把const看成一个编译期间的常量。在C中,如果写:
- const bufsize=100;
- char buf[bufsize];
尽管看起来好像做了一件合理的事,但这将得到一个错误的结果。因为bufsize占用内存的某个地方,所以C编译器不知道它在编译时的值。在C语言中可以选择这样书写:
const bufsize;
这样写在C + +中是不对的,而C编译器则把它作为一个声明,这个声明指明在别的地方有内存分配。因为C默认const是外部连接的,C++(www.cppentry.com)默认const是内部连接的,这样,如果在C++(www.cppentry.com)中想完成与C中同样的事情,必须用extern把内部连接改成外部连接:
- extern const bufsize;//declaration only
这种方法也可用在C语言中。在C语言中使用限定符const不是很有用,即使是在常数表达式里(必须在编译期间被求出)想使用一个已命名的值,使用const也不是很有用的。C迫使程序员在预处理器里使用# define。
面试例题3:有类如下:
- Class A_class
- {
- void f() const
- {
-
- ......
- }
- }
在上面这种情况下,如果要修改类的成员变量,应该怎么办?[美国著名软件企业GS公司2007年12月面试题]
解析:在C++(www.cppentry.com)程序中,类里面的数据成员加上mutable后,修饰为const的成员函数,就可以修改它了,代码如下:
- #include <iostream>
- #include <iomanip>
- using namespace std;
-
- class C
- {
-
- public:
- C(int i):m_Count(i){}
- int incr() const
- //注意这里的const
- {
- return ++m_Count;
- }
- int decr() const
- {
- return --m_Count;
- }
- private:
- mutable int m_Count;
- //可以将这里的mutable去掉再编译试一试
- };
- int main()
- {
- C c1(0),c2(10);
- for(int tmp,i=0;i<10;i++)
- {
- tmp = c1.incr();
- cout<<setw(tmp)<<setfill('
- ')<<tmp<<endl;
- tmp = c2.decr();
- cout<<setw(tmp)<<setfill('
- ')<<tmp<<endl;
- }
- return 0;
- }
答案:在const成员函数中,用mutable修饰成员变量名后,就可以修改类的成员变量了。