C++ const用法
const限定符
在变量前面加上const,也可以创建一个常量。使用const创建常量的一般格式如下:
const type name = value;
使用const的时候应该注意在声明中对const变量进行初始化。
const int toes;
toes = 10;
以上用法是错误的,会带来编译错误。如果常量在声明的时候没有提供值,则该常量的值将是不确定的,且无法修改。
常量的三种命名习惯
1,首字母大写。这不是一个通用的约定,但是在阅读程序的时候有助于区分常量和变量。如
const int Month = 12;
Month的首字母大写,以提示用户它是一个常量。
2,整个名称都大写。这种方式通常在#define创建常量时使用。
3,以字母k打头,如kmonths.
const > #define
1, 它能够明确指定的类型。#define是一个预编译命令,在编译前编译器会读取宏的值,然后在代码中进行文本替换。因此,你可以将它理解成为一个文本替换工具。
2,可以使用C++的作用域规则将定义限制在特定的函数或文件中。
3,第三,可以将const用于更复杂的类型。比如数组和结构体中。
因此,如果你学过C语言,并打算使用#define来定义符号常量,请不要这样做,而应使用const。
C与C++在const上的区别
ANSI C也使用const限定符,这是从C++借鉴过来的。二者的区别主要体现在两个方面,一是作用域规则,这是C++独有的。二是C++中可以用const值来声明数组长度,但是C++却不允许。
const与指针
将const用于指针存在很微妙的地方,大体上有两种不同的方式。第一种方法是让指针指向一个常量对象,这样可以防止使用该指针来修改所指向的值。第二种方法是将指针本身声明为常量,这样可以防止改变指针指向的位置。
首先是第一种,声明一个指向常量的指针pt:
int age = 39;
const int * pt = &age;
age本身是一个变量,因此通过age修改自身的值是允许的,但是通过*pt来修改int的值却是被禁止的。
age = 20; // VALID
*pt = 20; // INVALID
cin >> *pt; // INVALID
以前我们都是将常规变量的地址赋给常规的指针,这里选择将常规变量的地址赋给一个const指针。作为一个交叉,还存在将const变量的地址赋值给const指针以及将const变量的地址赋值给常规指针。如下:
const float g_earth = 9.8;
const float * pe = &g_earth; // VALID
const float g_moon = 1.63;
float * pm = &g_moon; //INVALID
将const变量的地址赋值给const指针很容易理解,这样的话,既不能通过变量本身修改变量的值,也不能通过指针来修改变量的值。然而将const变量的地址赋值给常规指针为什么会被禁止也可以从另外一个角度来解释,如果这种行为合法的话,那么将可以通过常规指针来修改变量g_moon的值,这将使得g_moon作为一个const变量的地位很“尴尬”。
假设有一个由const数据组成的数组
const int months[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
则禁止将数组的地址赋值给非const指针。这也意味着不能将数组名作为参数传递给以非常量作为形参的函数。
在实际的编程中,我们经常会选择将指针参数声明为指向常量数据,主要有以下两条理由。
1,这样可以避免由于无意间修改数据而导致的编程错误。
2,使用const使得函数能够处理const和非const实参,否则将只能接受非const数据。
const int * 和 int * const的区别
int sloth=3;
const int * ps = &sloth; // 一个指向const int的指针
int * const finger = &sloth; // 一个指向int类型的const指针
二者的直观含义已经在上述代码中说明得很清楚。这里想说的是隐藏在直接定义背后的那层含义。对于第二行,不允许使用ps来修改sloth的值,但是却可以让ps指向其它地址。第三行中,finger所指向的地址不能改变,但是可以通过finger来修改sloth的值。
如果你愿意的话,甚至可以定义指向const对象的const指针,如下
int sloth = 3;
const int * const p = &sloth;
这样既不可以修改指针p的值,也不允许通过p来修改sloth的值。