const 它限定一个变量不允许被改变,表示只读变量。使用const在一定程度上可以提高程序的安全性和可靠性
const变量 & 常量
为什么下面的例子在使用一个const变量来初始化数组,ANSI C的编译器会报告一个错误呢?
const int n = 5;
int a[n];
上面讨 论的是“常量”与“只读变量”的区别。
常量肯定是只读的,因为常量是被编译器放在内存中的只读区域,当然也就不能够去修改它。
“只读变量”则是在内存中开辟一个地方来存放它的值,只不过这个值由编译器限定不允许被修改。
在ANSI C中,这种写法是错误的,因为数组的大小应该是个常量,而const int n,n只是一个变量(常量 != 不可变的变量,但在标准C++中,这样定义的是一个常量,这种写法是对的)。
enum类型和#define宏,这两个都可以用来定义常量。而被const修饰的只是只读变量
const变量 & const 限定的内容
下面的代码编译器会报一个错误,请问,哪一个语句是错误的呢?
typedef char * pStr;
char string[4] = "abc";
const char *p1 = string;
const pStr p2 = string;
p1++;
p2++;
答案与分析:
问题出在p2++上。
1)、const使用的基本形式: const char m;
限定m不可变。
2)、替换1式中的m, const char *pm;
限定*pm不可变,当然pm是可变的,因此问题中p1++是对的。
3)、替换1式char, const newType m;
限定m不可变,问题中的pStr就是一种新类型,因此问题中p2不可变,p2++是错误的。
const变量 & 字符串常量
请问下面的代码有什么问题?
char *p = "i'm hungry!";
p[0]= 'I';
答案与分析:
上面的代码可能会造成内存的非法写操作。分析如下, "i'm hungry"实质上是字符串常量,而常量往往被编译器放在只读的内存区,不可写。p初始指向这个只读的内存区,而p[0] = 'I'则企图去写这个地方,编译器当然不会答应。
const变量 & 字符串常量2
请问char a[3] = "abc" 合法吗?使用它有什么隐患?
答案与分析:
在标准C中这是合法的,但是它的生存环境非常狭小;它定义一个大小为3的数组,初始化为"abc",注意,它没有通常的字符串终止符'\0',因此这个数组只是看起来像C语言中的字符串,实质上却不是,因此所有对字符串进行处理的函数,比如strcpy、printf等,都不能够被使用在这个假字符串上。
变量
const int A; 常量
const int* pA; 指向常量的指针。 (*pA)++ 错误,不允许改变常量, 但是 pA = &D 可以改变指向的对象。
int const * pA; 常量指针,指向int。(*pA)++ 允许, 但不可以改变指向,既 pA = &D 错误
const int *const p3=&A;//p3不可变,*p3也不可变,此时既不能用*p3来修改其值,也不能转向
指针和引用的区别很简单,就是引用更简洁,更安全。因为引用声明是必须初始化
const指针可以接受const和非const地址,但是非const指针只能接受非const地址。所以const指针的能力更强一些,所以尽量多用const指针,这是一种习惯。
函数
const int a(); 返回常量
int const * a(); 返回常量指针
const int* a(); 返回指向常量的指针
形参是const类型的,说明该函数将不会修改其值,该函数便为const函数。
限定函数类型.
void function()const; //常成员函数, Const成员函数不能改变对象的成员函数。
如:
class Point {
public:
int GetY() const;
void SetPt (int, int);
...........................
};
int Point::GetY() const //该函数调用时没有修改类的数据成员,只是读取。
{
return yVal;
}
void Point:: SetPt (int x, int y) //该函数有改变类的数据成员,不能定义为常成员函数
{
xVal=x;
yVal=y;
}
const Point p;
int y=p.GetY() ; //正确的
p.SetPt(10,10); //错误的,常对象只能调用常成员函数
非常量成员函数不能被常量成员对象调用,因为它可能企图修改常量的数据成员。
构造函数和析构函数对这个规则例外,它们从不定义为常量成员,但可被常量对象调用(被自动调用)。它们也能给常量的数据成员赋值,除非数据成员本身是常量。
类的成员函数中,常常有一些成员函数不改变类的数据成员,也就是说,这些函数是"只读"函数。不改变数据成员的函数都加上const关键字进行标识,显然,可提高程序的可读性。其实,它还能提高程序的可靠性,已定义成const的成员函数,一旦企图修改数据成员的值,则编译器按错误处理。