顶层const: 表示任意的对象是常量。
底层const: 与指针和引用等复合类型有关。
对指针而言, 顶层const表示指针本身是个常量, 而底层const表示指针所指的对象是一个常量。
int i = 22;
const int ci = 20; //顶层const, 不能修改ci的值
const int *p1= &ci; //底层const, 允许修改p1的值, 但是不能通过*p1修改ci
的值。
int *const p2 = &i; //顶层const, 不能修改p2的值, 但是允许通过*p2修改i
的值
用实参初始化形参时, 会忽略掉顶层const, 也就是说,当形参有顶层const时, 传给它常量对象或者非常量对象都是可以的。
总结
int cube(int i); 实参可以为int类型, 也可以为const int类型。 在函数体中可以修改i的值, 函数不会修改实参的值。
int cube(const int i); 实参可以为int类型, 也可以为const int类型。 在函数体中不可以修改i的值, 函数不会修改实参的值。
int pCube(int * pi); 实参为int * 类型的指针, 不能为const int * 类型。 可以通过修改* pi 的值修改实参指向的对象的值, 修改pi对实参没有影响。
int pCube(const int pi); 实参可以为const int 类型,也可以为int * 类型。 不可以通过修改* pi 的值修改实参指向的对象的值, 修改pi对实参没有影响。
int pCube(int * const pi); 实参为 int * 类型, 不能为const int * 类型。 可以通过修改* pi 的值修改实参指向的对象的值, 不可以给pi赋值。
void reset(int &r); 实参为int类型, 不可以为const int 类型。 可以通过修改r的值, 从而修改实参的值。
void print(const int &r); 实参可以为int类型, 也可以为const int类型, 不可以修改r的值。
#include<iostream>
using namespace std;
int fun1(int i);
int fun2(const int i);
int pfun1(int *pi);
int pfun2(const int *pi);
int pfun3(int *const pi);
int rfun1(int &r);
int rfun2(const int &r);
int main()
{
//num1为int类型的变量,可以修改它的值
//num2为int类型的常量,不可以修改它的值
int num1 = 10;
const int num2 = 10;
num1 = 20;
//num2 = 20;
//普通指针,可以修改p1的值,也以通过修改*p1来修改num1的值。
//所以只能用int类型的数据来初始化,不能用const int类型,不能修改常量的值
int *p1 = &num1;
//int *p2 = &num2; //出错
//底层const,可以修改指针(p3,p4),但是不可以通过*p3,*p4,去修改num1, num2的值。
//可以使用int类型或const int类型的数据来初始化
const int *p3 = &num1;
const int *p4 = &num2;
//顶层const,不可以修改指针(p5,p6),但是可以通过*p5去修改num1的值。
//所以只能使用int类型的数据来初始化,不能const int类型
int * const p5 = &num1;
//int * const p6 = &num2; //错误
//int类型的引用,可以通过r1去修改num1的值,所以只能用int类型去初始化,不能使用const int类型
int &r1 = num1;
//int &r2 = num2; //出错
//const int类型的引用,不能修改r3,r4的值
//可以使用int类型的数据来初始化,也可以使用const int类型
const int &r3 = num1;
const int &r4 = num2;
//实参为int类型或const int类型
cout << fun1(num1) << " "<< fun1(num2) << endl;
cout << fun2(num1) << " " << fun2(num2) << endl;
//实参只能为int类型
cout << pfun1(&num1) << endl;
//cout << pfun1(&num2) << endl; //出错
//所以实参可以是int类型,也可以是const int类型
cout << pfun2(&num1) << " " << pfun2(&num2) << endl;
//所以实参类型只能是int类型
cout << pfun3(&num1) << endl;
//cout << pfun3(&num2) << endl; //出错
//实参类型只能是int类型
cout << rfun1(num1) << endl;
//cout << rfun1(num2) << endl; //出错
//实参类型可以是int类型,也可以是const int类型
cout << rfun2(num1) << " " << rfun2(num2) << endl;
return 0;
}
//可以修改形参i
int fun1(int i)
{
//i = 0;
return i * i * i;
}
//不可以修改形参i
int fun2(const int i)
{
//i = 0; //出错
return i * i * i;
}
int pfun1(int *pi)
{
//*pi = 0;
return *pi * (*pi) *(*pi);
}
//可以修改pi,但是不可以修改*pi。所以实参可以是int类型,也可以是const int类型
int pfun2(const int *pi)
{
//*pi = 0; //出错
return *pi * (*pi) *(*pi);
}
//不可以修改pi,但是可以修改*pi,所以实参类型只能是int类型
int pfun3(int *const pi)
{
//*pi = 0;
return *pi * (*pi) *(*pi);
}
//可以修改r,实参类型只能是int类型
int rfun1(int &r)
{
//r = r * r * r;
return r * r * r;
}
//不可以修改r,实参类型可以是int类型,也可以是const int类型
int rfun2(const int &r)
{
//r = r * r * r; //出错
return r * r * r;
}