【C/C++】 常量指针,指针常量、指向常量的常指针 快速理解

const修饰指针的三种情况  

int main() {

	int a = 10;
	int b = 10;

    //常量指针
	//const修饰的是指针,指针指向可以改,指针指向的值不可以更改
    //const右侧紧跟着的是 "*"--> 指针, *p不可以改,p可以改。
	const int * p1 = &a; 
	p1 = &b; //正确
	//*p1 = 100;  报错
	

    //指针常量
	//const修饰的是常量,指针指向不可以改,指针指向的值可以更改
    //const右侧紧跟着的是 "p2"--> 变量, p不可以改,*p可以改。
	int * const p2 = &a;
	//p2 = &b; //错误
	*p2 = 100; //正确


    //指向常量的常指针
    //const既修饰指针又修饰常量
    //const右侧紧跟着的是 "*"--> 指针和 "p2"--> 变量, p和*p 都不可以改。
	const int * const p3 = &a;
	//p3 = &b; //错误
	//*p3 = 100; //错误

	system("pause");

	return 0;
}

技巧:看const右侧紧跟着的是指针还是常量, 是指针就是常量指针,是常量就是指针常量。

简而言之:

        常量指针,const int * p1 = &a;  由于,const 修饰的是 int,不是p1。因此p1的值可以改,即指针变量 p1 的指向可以改,如 p1 = &b;但指针变量p1指向的对象的值却不可以改,即 *p = 100非法。注意,可以直接通过a=100 的方法来修改a的值。

        指针常量,int * const p2 = &a;  const修饰的是 "p2"--> , p2的值不可以改,即指针变量p2的指向不可以改,p2 = &b非法。但指针变量p2指向的对象的值可以改,即*p2 = 100合法。

        指向常量的常指针,const int * const p3 = &a;  const右侧紧跟着的是 " * "--> 指针和 "p3"--> 变量, p和*p 都不可以改。

const int * (常量指针)在结构体中的使用场景

作用:用const来防止误操作。

示例:

//学生结构体定义
struct student
{
	//成员列表
	string name;  //姓名
	int age;      //年龄
	int score;    //分数
};

//常量指针,指针指向可以改,指针指向的值不可以更改。
void printStudent(const student *stu) //加const防止函数体中的误操作
{
	//stu->age = 100; //操作失败,因为加了const修饰
	cout << "姓名:" << stu->name << " 年龄:" << stu->age << " 分数:" << stu->score << endl;

}

int main() {

	student s = { "张三",18,100 };

	printStudent(&s);        //实参为结构体变量的地址

	system("pause");

	return 0;
}

输出:

        姓名:张三 年龄:18 分数:100 

        在定义函数时指定的形参,在未出现函数调用时,它们并不占内存中的存储单元,因此称它们是形式参数或虚拟参数,表示它们并不是实际存在的数据,只有在发生函数调用时,函数中的形参才被分配内存单元,以便接受从形参传来的数据。在调用结束和,形参所占的内存单元也被释放。 

        当我们传一个数据的地址的时候,只要传一个指针,占四个字节就可以了。但是采用值传递的形式,源数据有多大,值传的就有多多,会完全拷贝出一个新的副本。改传指针,可以节省空间。 

        当主函数调用 printStudent()函数时,进行虚实结合,把变量s1的地址传送给形参stu(它们都是struct student * 型指针变量),因此,*stu和s为同一存储单元

   

【C/C++】 常量指针,指针常量、指向常量的常指针 快速理解_第1张图片

常量指针,指针指向可以改,指针指向的值不可以更改。  

int * const (指针常量)/  引用的本质

作用:引用的本质在c++内部实现是一个指针常量.

示例:

//发现是引用,转换为 int* const ref = &a;
void func(int& ref){
	//int b=10;        //这两行代码非法
	//int &ref = b;    //声明一个引用后,不能再使之作为另一个变量的引用。
	ref = 100; // ref是引用,转换为*ref = 100
}
int main(){
	int a = 10;
    
    //自动转换为 int* const ref = &a; 指针常量是指针指向不可改,也说明为什么引用不可更改
	int& ref = a; 
	ref = 20; //内部发现ref是引用,自动帮我们转换为: *ref = 20;
    
	cout << "a:" << a << endl;
	cout << "ref:" << ref << endl;
    
	func(a);
	cout << "ref:" << ref << endl;
	return 0;
}

输出:

        a:20
        ref:20
        ref:100 

        声明一个引用时,必须同时使之初始化,即声明它代表哪一个变量。当引用作为函数形参时不必在声明中初始化,它的初始化是在函数调用时的虚实结合实现的,即作为形参的引用是函数实参的别名。

【C/C++】 常量指针,指针常量、指向常量的常指针 快速理解_第2张图片

指针常量的指向(ref的值)不能改,但指针变量的指向变量的值可以改。

const student & stu 对象的常引用

作用:常量引用,指针指向可以改,指针指向的值不可以更改。

示例:

//学生结构体定义
struct student
{
	//成员列表
	string name;  //姓名
	int age;      //年龄
	int score;    //分数
};


//常量引用,指针指向(stu的值)可以改,指针指向的值(stu.age)不可以更改。
void printStudent(const student &stu) //这里是引用
{
	//stu.age = 19;       //非法
	cout << "姓名:" << stu.name << " 年龄:" << stu.age << " 分数:" << stu.score << endl;

}

int main() {

	student s = { "张三",18,100 };

	printStudent(s);        //实参为结构体变量

	system("pause");

	return 0;
}

输出:

        姓名:张三 年龄:18 分数:100 


        

常量引用,指针指向(stu的值)可以改,指针指向的值(stu.age)不可以更改。

        


彩蛋

        本质上const关键字只是告诉编译器该修饰的变量不可以被修改,并不能改变它修饰的变量在内存中所存放的区域

参考链接:

        【C/C++】 常量指针,指针常量、指向常量的常指针详解

你可能感兴趣的:(【C/C++】,c++,c语言,开发语言)