const可以用来定义常量,也可以用来修饰函数的参数和返回值。这里只对const修饰常量做一些探讨。
说const,就不能不说define。const和define的区别是很明显的,其中最大的区别在于const可以做类型检查,而define,显然,编译器是不可能做类型检查的,因为它根本就没有任何类型信息。
在c语言中,define在编译时就确定了其值,但是const的变量却不是,所以像这样定义是可以的:const int buf;
但是c++中不行,c++中必须在定义时初始化,因为其值是在编译时是嵌入到代码中的。因为同样的道理,如下的代码在c中编译是通不过的,但是在c++中可以。
const int buf = 100;
int array[buf];
如果在c++中非要只定义一个const而不初始化它,那就必须用到extern关键字,像这样定义
extern const int buf;
现在关于const和define在c和c++中的区别应该都清楚了,下面就专门讨论const在定义变量(或者说常量)时一些要注意的地方。
1:const定义的变量在编译时就已经确定并嵌入了具体值,所以像下面那样在程序运行过程中想改变其值是不可能的(c和c++中都一样,尽管在c中实际上并没有在编译时嵌入其值)。
const int value = 5;
value = 7; //错误
当一个指针要指向一个const的类型时,其指针也必须是const的,引用与指针相同,如下
int *pointer = &value; //错误
const int *pointer = &value; //正确
int &ref = value; //错误
const int &ref = value; //正确
以上指针和引用的特点是:想要改变其指向的地址,或者是改变其指向地址的内容都是不可能的。也就是说,任何把它们放在“=”号左边的做法都是错误的。(所以很多人都称他们为指向const的const指针,记为const int *const ptr)
int value2 = 2;
*pointer = 2; //错误
pointer = &value2; //错误
ref = 2; //错误
&ref = value2; //错误
另外,const int *const ptr还有下面的一种定义方法
int val =2;
const int *const ptr = &val;
同样,prt和*ptr都是不能改变的。当然,还是可以通过val来改变的。这是与上面不一样的地方,val并不是const的。
val = 3; //正确
2:const用在指针和引用上还可以这样定义:int *const ptr;这样定义的意思是指针ptr所指向的地址是不能改变的,但是地址的内容并不是const的类型,是可以改变的,如下面那样
int value = 2;
int *const pointer = &value;
*pointer = 3; //正确
int value2 = 3;
pointer = &value2; //错误
引用本身就是指向一个常量地址(固定地址),因此:int & ref 与int *const ref具有相同的行为,如下所示
int &ref = value;
ref = 3; //正确
&ref = &value //错误 实际上,任何把&ref放在“=”号左边的做法都 是错误的,因为它所引用的地址不能被改变。
3:还有一类const int *ptr; 指向const内容的指针,你可以改变ptr所指向的地址,但是你不能改变ptr所指向的内容。
int value = 1;
int value2 = 2;
const int *pointer = &value;
*pointer = 3; //错误
pointer = &value2; //正确
*pointer = 4; //错误,就算改变了pointer指向的地址,任然不能用 *pointer来改变其内容,当然,用value2 = 4是
可以的,如下:
value2 = 4 //正确
引用并没有单独的指向内容的引用一说,因为引用都是默认为引用一个固定地址的,不能改变。
总结:
1:int *const ptr;指向const地址的指针,指向的地址(ptr)不能变,地址的内容(*ptr)可以变。
2:const int *ptr; 指向const内容的指针,指向的地址(ptr)可以变,地址的内容(*ptr)不能变。
3:const int *const ptr;所谓的指向const的const指针,都不能变。
说const,就不能不说define。const和define的区别是很明显的,其中最大的区别在于const可以做类型检查,而define,显然,编译器是不可能做类型检查的,因为它根本就没有任何类型信息。
在c语言中,define在编译时就确定了其值,但是const的变量却不是,所以像这样定义是可以的:const int buf;
但是c++中不行,c++中必须在定义时初始化,因为其值是在编译时是嵌入到代码中的。因为同样的道理,如下的代码在c中编译是通不过的,但是在c++中可以。
const int buf = 100;
int array[buf];
如果在c++中非要只定义一个const而不初始化它,那就必须用到extern关键字,像这样定义
extern const int buf;
现在关于const和define在c和c++中的区别应该都清楚了,下面就专门讨论const在定义变量(或者说常量)时一些要注意的地方。
1:const定义的变量在编译时就已经确定并嵌入了具体值,所以像下面那样在程序运行过程中想改变其值是不可能的(c和c++中都一样,尽管在c中实际上并没有在编译时嵌入其值)。
const int value = 5;
value = 7; //错误
当一个指针要指向一个const的类型时,其指针也必须是const的,引用与指针相同,如下
int *pointer = &value; //错误
const int *pointer = &value; //正确
int &ref = value; //错误
const int &ref = value; //正确
以上指针和引用的特点是:想要改变其指向的地址,或者是改变其指向地址的内容都是不可能的。也就是说,任何把它们放在“=”号左边的做法都是错误的。(所以很多人都称他们为指向const的const指针,记为const int *const ptr)
int value2 = 2;
*pointer = 2; //错误
pointer = &value2; //错误
ref = 2; //错误
&ref = value2; //错误
另外,const int *const ptr还有下面的一种定义方法
int val =2;
const int *const ptr = &val;
同样,prt和*ptr都是不能改变的。当然,还是可以通过val来改变的。这是与上面不一样的地方,val并不是const的。
val = 3; //正确
2:const用在指针和引用上还可以这样定义:int *const ptr;这样定义的意思是指针ptr所指向的地址是不能改变的,但是地址的内容并不是const的类型,是可以改变的,如下面那样
int value = 2;
int *const pointer = &value;
*pointer = 3; //正确
int value2 = 3;
pointer = &value2; //错误
引用本身就是指向一个常量地址(固定地址),因此:int & ref 与int *const ref具有相同的行为,如下所示
int &ref = value;
ref = 3; //正确
&ref = &value //错误 实际上,任何把&ref放在“=”号左边的做法都 是错误的,因为它所引用的地址不能被改变。
3:还有一类const int *ptr; 指向const内容的指针,你可以改变ptr所指向的地址,但是你不能改变ptr所指向的内容。
int value = 1;
int value2 = 2;
const int *pointer = &value;
*pointer = 3; //错误
pointer = &value2; //正确
*pointer = 4; //错误,就算改变了pointer指向的地址,任然不能用 *pointer来改变其内容,当然,用value2 = 4是
可以的,如下:
value2 = 4 //正确
引用并没有单独的指向内容的引用一说,因为引用都是默认为引用一个固定地址的,不能改变。
总结:
1:int *const ptr;指向const地址的指针,指向的地址(ptr)不能变,地址的内容(*ptr)可以变。
2:const int *ptr; 指向const内容的指针,指向的地址(ptr)可以变,地址的内容(*ptr)不能变。
3:const int *const ptr;所谓的指向const的const指针,都不能变。