目录
1、普通const变量
定义时必需赋初始值(可以是宏、数值、常量名),且后期不能被改变。这里const int和int const是一样的。
#include<iostream>
using namespace std;
#define N 10
int main()
{
const int a = 1;
int const b = a;
const int c = N;
system("pause");
return 0;
}
2、指针和const的混合(3种情形)
#include<iostream>
using namespace std;
int main()
{
int a = 1;
int b = 2;
int* p = &a; // 普通指针
// 情形1
/* 指针i、j指向可以改变,但是不能通过*i或*j来改变所指向对象的值 */
const int * i = &a;
int const * j = &a;
i = &b; // 可以改变i的值
j = &b; // 可以改变j的值
// 情形2
/* 指针k是常指针,可以通过*k改变所指向地址的值,但不能改变k的值 */
int * const k = &a;
*k = 9; // 可以通过*k改变a的值
cout << a << endl; // 输出9
// 情形3
/* 下面的m、n指针,既不能改变指针的指向,也不能通过*m、*n改变所指对象的值;
定义时必须初始化,且只能用定义好之后的指针所指对象的值,不能改。
右边可以是对普通变量取地址 或 对const变量取地址,也可以是普通指针 或 const指针
*/
const int * const m = &a;
int const * const n = &b;
system("pause");
return 0;
}
这里有一个技巧,const在指针右边,说明const限制k,k是常量,如果在指针左边,说明是另一种情况 ---- 即,不能通过指针修改被指对象。
还需要注意,如果原变量是const的,指向它的指针也得是const的,如下:
#include<iostream>
using namespace std;
int main()
{
const int a = 1; // const类型
const int * x = &a; // 指向它的指针也必须是const
int const * y = &a; // 也可以这样写
system("pause");
return 0;
}
3、普通引用
记住,引用有个特点,定义时必需赋初始值。且定义之后,就没法改变绑定引用到的对象。
#include<iostream>
using namespace std;
int main()
{
int a = 1;
int &m = a; // 引用定义时就必须初始化,且后期不能更改引用对象,下面有例子
m = 2; // 通过引用改变被引用的对象的值
cout << a << " " << m << endl; // 输出2 2,说明被引用的对象a被改变
// 例子
/* 下面说明了引用赋值后,不能再次改变所绑定到的对象 */
int b = 5;
m = b; // 这里,m并未改变绑定对象,而是改变绑定对象a的值为b,即5
cout << m << " " << a << " " << b << endl; // 输出5 5 5
m = 15; // 再次改变绑定对象a的值,并不会对b有任何影响
// 下面输出15 15 5,b的值没有变,说明m = b那条语句不是改变绑定对象
cout << m << " " << a << " " << b << endl;
system("pause");
return 0;
}
还需要注意,如果原变量是const的,它的引用也得const的,如下:
#include<iostream>
using namespace std;
int main()
{
const int a = 1; // const类型
const int & x = a; // 引用也必须是const
int const & y = a; // 也可以这样写
system("pause");
return 0;
}
4、引用和const的混合
#include<iostream>
using namespace std;
int main()
{
int a = 1;
int b = 2;
/* 不能通过i、j改变所引用的对象a、b的值 */
const int &i = a;
int const &j = a;
/* 下面是会报错的 */
i = 5;
j = 5;
system("pause");
return 0;
}
5、指针和引用混合
#include<iostream>
using namespace std;
int main()
{
int a = 1;
int b = 2;
int *pa = &a;
int *pb = &b;
int* &m = pa; // 普通指针引用
*m = 5; // 通过改变指针的引用改变a的值
cout << a << " " << *pa << " " << *m << endl; // 输出5 5 5
m = pb; // 注意,这里并未改变引用m的绑定对象pa,它只是把pa的值变成了pb
cout << *pa << endl; // 输出为b的值-2,说明引用并不能被改变绑定对象
system("pause");
return 0;
}
6、指针、引用、const的混合
#include<iostream>
using namespace std;
int main()
{
int a = 1;
int b = 2;
int *pa = &a;
int *pb = &b;
const int *qa = &a;
const int *qb = &b;
/* 情形1 */
int* const &i = pa; // 不能通过引用i改变被引用对象pa的值
// int* const &i = &a; // 这时可以直接引用地址,因为i是常引用,&a就是常量
// i = pb; // 是错误的,会报错
*i = 3; // 但是可以通过*i改变pa所指对象的值,相当于*pa = 3
cout << a << endl; // 输出3,代表pa所指对象---a的值被改变
/* 情形2 */
/* j是const int* 类型的引用,q也必须是const int*类型;
j不能通过*j改变j所引用的对象的值,但是可以通过j改变被引用对象q的值 */
const int* &j = qa;
// *j = 4; // 是错误的,会报错
j = pb; // 通过引用j改变被引对象qa的值为qb,相当于qa = pb
cout << *qa << endl; // 输出为b的值--2,说明通过j改变qa的值为pb,即&b
/* 情形3 */
/* 这种情况,既不能通过k改变pa的值,也不能通过*k改变pa所指对象的值 */
const int* const &k = pa;
// k = pb; // 是错误的,会报错
// *k = 5; // 是错误的,会报错
const int* const &k = &a; // 这时可以直接引用地址,因为i是常引用,&a就是常量
system("pause");
return 0;
}
最后这里需要注意一点:
#include<iostream>
using namespace std;
int main()
{
int a = 1;
int b = 2;
int *pa = &a;
int *pb = &b;
const int *qa = &a;
const int *qb = &b;
const int* &j = qa; // j是const int*类型的引用,qa也必须是这种const类型指针
const int* const &k = pa; // 而k,所引用的pa可以不用是const类型,尽管它们都有相同的开头
system("pause");
return 0;
}
本人水平有限,若有误,欢迎评论留言指教。