const和指针的结合

目录

易错知识点

const和指针的结合

const和一级指针的结合

正误转换

巧用技巧

const是否参与类型

const和二级指针的结合

正误转换

巧用技巧

温故知新


易错知识点

1、常量不能作为左值,防止直接修改常量的值

2、不能将常量的地址泄露给普通指针或普通引用变量,防止间接修改常量的值

// 关于易错知识点第2点
// 不能将常量的地址泄露给普通指针或普通引用变量,防止间接修改常量的值
const int a = 10;
const int * p = &a; // 正确写法!
// int * p = &a;       // 错误写法!
// int * const p = &a; // 错误写法!
	// 以下写法均正确!
	 
	int a = 1;
	
	int * p1 = &a;
	
	const int * p2 = &a;
	int const * p3 = &a;
	
	int * const p4 = &a;
	
	const int * const p5 = &a;
	int const * const p6 = &a;

const和指针的结合

1、const修饰离它最近的类型

2、注意区分const修饰的类型和const修饰的表达式:

除去const和它修饰的类型,剩余部分就是const修饰的表达式(详见以下代码段)

3、如果const右边没有指针*,那么const不参与类型

const和一级指针的结合

正误转换

// 正确转换
// 1
const int *  <=  int *

// 2
int * const *  <=  int * *
// const因它右边*而参与类型
// 因此可将int * const *  <=  int * *看做是const *  <=  *
// 所以是正确转换


// 错误转换
// 1
int *  <=  const int *

// 2
int * *  <=  int * const *
// const因它右边*而参与类型
// 因此可将int * *  <=  int * const *看做是*  <=  const *
// 所以是错误转换

巧用技巧

// const和一级指针的结合
// 巧用“除去const和它修饰的类型,剩余部分就是const修饰的表达式”技巧

// 1
const int * p;
// const int * p;与int const * p;等价
// const修饰的类型为int,修饰的表达式为*p
// *p的值不能被修改,p的值可以被修改
// 指针p可以指向其它内存,但不能通过指针p修改内存的值

// 2
int const * p;
// int const * p;与const int * p;等价
// const修饰的类型为int,修饰的表达式为*p
// *p的值不能被修改,p的值可以被修改
// 指针p可以指向其它内存,但不能通过指针p修改内存的值

// 3
int * const p;
// *不能单独作为类型,const修饰的类型为int *,修饰的表达式为p
// p的值不能被修改,*p的值可以被修改
// 可以通过指针p修改内存的值,但指针p不能指向其它内存

// 4
const int * const p;
// const int * const p;与int const * const p;等价
// const int * const p;相当于const int * p;和int * const p;的综合
// 前const修饰的类型为int,修饰的表达式为*p
// 后const修饰的类型为int *,修饰的表达式为p
// 不能通过指针p修改内存的值,指针p也不能指向其它内存

// 5
int const * const p;
// int const * const p;与const int * const p;等价
// int const * const p;相当于int const * p;和int * const p;的综合
// 前const修饰的类型为int,修饰的表达式为*p
// 后const修饰的类型为int *,修饰的表达式为p
// 不能通过指针p修改内存的值,指针p也不能指向其它内存

// 总结
// 第一类:const int * p;与int const * p;等价
// 第二类:int * const p;
// 第一类和第二类综合形成第三类:
// const int * const p;与int const * const p;等价

const是否参与类型

// const和一级指针的结合
// 关于“3、如果const右边没有指针*,那么const不参与类型”

#include
#include
using namespace std;

int main()
{
    int * p1 = nullptr;
    int * const p2 = nullptr;
    cout << "int * p1定义的p1的类型为" << typeid(p1).name() << endl;
    cout << "int * const p2定义的p2的类型为" << typeid(p2).name() << endl;
    cout << "总结:如果const右边没有指针*,那么const不参与类型" << endl;
    cout << "-------------------------------------------" << endl;

    const int * p3 = nullptr;
    cout << "const int * p3定义的p3的类型为" << typeid(p3).name() << endl;
    cout << "总结:如果const右边有指针*,那么const参与类型" << endl;

    return 0;
}

const和二级指针的结合

正误转换

// 错误转换
int * *  <=  const int * *
const int * *  <=  int * *
// 关于const int * *  <=  int * *是错误转换的说明

// 例如,有如下错误代码:
int a = 1;
int * p = &a;
const int * * q = &p;
// 假如以上代码逻辑成立,
// 那么*q为指向const int类型的指针,那么可以写如下代码:
const int b = 2;
*q = &b;
// 值得注意的是,*q和p属于同一内存
// 而p是int *类型,是一个普通指针
// 这违背易错知识点第2点“不能将常量的地址泄露给普通指针或普通引用变量,防止间接修改常量的值”
// 所以const int * *  <=  int * *是错误转换
// 同理,int * *  <=  const int * *是错误转换

巧用技巧

// const和二级指针的结合
// 巧用“除去const和它修饰的类型,剩余部分就是const修饰的表达式”技巧

// 1
const int * * q;
// const修饰的类型为int,修饰的表达式为**q
// q能被赋值
// *q能被赋值
// **q不能被赋值

// 2
int * const * q;
// *不能单独作为类型,const修饰的类型为int *,修饰的表达式为*q
// q能被赋值
// *q不能被赋值
// **q能被赋值

// 3
int * * const q;
// const修饰的类型为int * *,修饰的表达式为q
// q不能被赋值
// *q能被赋值
// **q能被赋值

// 总结
// 第一类:const int * * q;
// 第二类:int * const * q;
// 第三类:int * * const q;

温故知新

1、注意理解前文的正确转换和错误转换!

2、如果const右边没有指针*,那么const不参与类型

// 1
int a = 1;
const int * p = &a;
// const int *  <=  int *,正确!
int * q = p;
// int *  <=  const int *,错误!

// 2
int a = 1;
int * const p = &a;
// int *  <=  int *,正确!
int * q = p;
// int *  <=  int *,正确!

// 3
int a = 1;
int * const p = &a;
// int *  <=  int *,正确!
int * const q = p;
// int *  <=  int *,正确!

// 4
int a = 1;
int * const p = &a;
// int *  <=  int *,正确!
const int * q = p;
// const int *  <=  int *,正确!

// 5(注意联系6和7)
int a = 1;
int * p = &a;
// int *  <=  int *,正确!
const int * * q = &p;
// const int * *  <=  int * *,错误!

// 6(注意联系5和7)
int a = 1;
const int * p = &a;
// const int *  <=  int *,正确!
const int * * q = &p;
// const int * *  <=  const int * *,正确!

// 7(注意联系5和6)
int a = 1;
int * p = &a;
// int *  <=  int *,正确!
const int * const * q = &p;
// const int * const *  <=  int * *,正确!

// 8
int a = 1;
int * p = &a;
// int *  <=  int *,正确!
int * const * q = &p;
// int * const *  <=  int * *
// 相当于const *  <=  *,正确!

// 9
int a = 1;
int * p = &a;
// int *  <=  int *,正确!
int * * const q = &p;
// int * *  <=  int * *,正确!

// 10
int a = 1;
int * const p = &a;
// int *  <=  int *,正确!
int * * q = &p;
// 注意!注意!
// int * *  <=  int * const *
// 相当于*  <=  const *,错误!

// 11
int a = 1;
const int * p = &a;
// const int *  <=  int *,正确!
int * const * q = &p;
// 注意!注意!
// int * const *  <=  const int * *
// 相当于const *  <=  *和int *  <=  const int *
// const *  <=  *,正确!
// int *  <=  const int *,错误!
// 综上,int * const *  <=  const int * *,错误!

你可能感兴趣的:(C++,c++,const,指针)