1. 要讨论的问题
在C/C++中有个const关键字,本文通过例子来说明const数据和const指针的含义。
通常会有如下几种表示方法:
char greeting[] = "Hello";
char* p1 = greeting;
const char* p2 = greeting; // const data
char* const p3 = greeting; // const pointer
const char* const p4 = greeting; // const data & const pointer
2. 原则&简单的类比例子
具体const针对的是数据还是指针,则以*为分界线。左边的const,是针对数据的;右边的const,是针对指针的。一个辅助理解的声明可以是:
const size_t BUFFER_SIZE = 1024;
显然在这里没有指针的概念,这里的const就是表示:变量BUFFER_SIZE是1024,不能改变这个变量的值。或者进一步地说,不能改变这个变量BUFFER_SIZE所指向的内存的值,就称为const数据好了。
对于const数据,如果修改该变量的值,会有error:
const size_t BUFFER_SIZE = 1024;
BUFFER_SIZE = 4096; //error: assignment of read-only variable 'BUFFER_SIZE'
注释部分即为编译器的输出。本文用到编译器如下:
D:\examples\cpp\const>gcc --version
gcc (GCC) 4.8.1
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
D:\examples\cpp\const>g++ --version
g++ (GCC) 4.8.1
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
另外一点,const size_t和size_t const是完全等价的,只是写法不一样。
3. const数据和const指针
在有了const变量(或简单称为const数据)的类比之后,我们就比较容易区分const数据和const指针了。
为便于阅读,把前面的代码拷贝过来:
char greeting[] = "Hello";
char* p1 = greeting;
const char* p2 = greeting; // const data
char* const p3 = greeting; // const pointer
const char* const p4 = greeting; // const data & const pointer
结论:
- p1: 因为没有const,所以p1这个变量可以再指向其他的字符串(修改指针),并且,还可以修改p1指向的这个字符串的值(修改数据)。
- p2:这里是const 数据,即p2所指向的数据是不能修改的,不能用p2[i]=c这种形式(不能修改数据)。但p2这个指针不是const,即可以修改p2这个指针,让它指向别的char*(修改变量)。
- p3:数据不是const的,但指针是const的。所以,可以修改p3指向的字符串,比如p3[i]=c。但这个指针是常量,不能让它指向其他的指针,比如p3=p1是不允许的。
- p4:const数据 && const指针。
下面的示例代码尝试修改数据和尝试修改指针,注释部分是编译的error信息:
#include <iostream>
int main()
{
char greeting[] = "Hello";
char another_greeting[] = "Hello, world!";
char* p1 = greeting;
const char* p2 = greeting; // const data
char* const p3 = greeting; // const pointer
const char* const p4 = greeting; // const data & const pointer
p1 = another_greeting; //ok
p1[0] = 'h'; //ok
p2 = "test"; //ok
//p2[0] = 'T'; //error: assignment of read-only location '* p2'
//p3 = "test"; //error: assignment of read-only variable 'p3'
p3[0] = 'h'; //ok
//p4 = "test"; //error: assignment of read-only variable 'p4'
//p4[0] = 'x'; //error: assignment of read-only location '*(const char*)p4'
// The cout is only used to remove all the warnings.
// e.g.: variable 'p2' set but not used [-Wunused-but-set-variable]
std::cout<<p1<<std::endl;
std::cout<<p2<<std::endl;
std::cout<<p3<<std::endl;
std::cout<<p4<<std::endl;
return 0;
}
4. 参考资料
在《C++程序设计语言特别版》5.4节,详细介绍了const的语法。 |