问题:指针如何理解?
这里有一个对指针概念的解释,比较长,我们从另外一个角度来理解指针:将指针理解为一个函数
问题:如何理解函数与参数之间的关系?
这里有一个对形式参数,实际参数的解释,我的理解:关键是函数对实际参数的“使用权”与“所有权”。
使用权 | 所有权 |
---|---|
只能使用,不能修改 | 随心所欲,可以用,可以改 |
问题:参数让不让你改?
要回答这个问题,就牵涉到另外一个东东:常量
下面,我们在逐步回答前面的问题。
- 常量与变量
int a = 0; // a 是一个变量
a = 90; // 可以对 a 的值进行修改
const int b = 1; // b 是一个常量
//b = 90; // 不能对 b 的值进行修改
- 函数的“使用权”与“所有权”
使用权
void fun1(int a, const int b){
a = 100; // a 是一个变量,可以修改
//b = 100;// 不能对 b 的值进行修改
}
状态 | int a | const int b |
---|---|---|
调用fun1之前 | 90 | 1 |
在fun1内 | 90 | 1 |
在fun1内修改变量之后 | 100 | 1 |
调用fun1之后 | 90 | 1 |
所有权
那,什么时候才能使得函数对变量用于“所有权”呢?
答:使用“引用传递”,或者指针。
下面先给出使用“引用传递”的例子。
void fun2(int& a){
a = 200;
}
状态 | int a |
---|---|
调用fun2之前 | 90 |
在fun2内 | 90 |
在fun2内修改变量之后 | 200 |
调用fun2之后 | 200 |
这里的int& a表示什么意思呢?为什么这时就可以改变a的值呢?
&表示“取地址”的意思,也就是说,函数fun2知道实际参数a的地址了,
“跑得了和尚,跑不了庙”,你家在哪我都知道了,也就用于“所有权”了,
可以对实际参数a的值进行修改。
指针的例子呢?
下面先说一下对指针的理解,然后再给出例子。
- 将指针理解为一个函数
int* pa = &a; // 指针 pa 是一个函数,能够获取 a 的地址
那,既然将指针理解为一个函数,这个“函数”对a 是拥有“使用权”还是“所有权”呢?
答:额,这个很复杂,要看 指针的类型了
int* pa1 = &a; // 指针 pa 是一个函数,能够获取 a 的地址
*pa1 = 300;
cout <<"after pa1, value of a is: "<<a <<endl;
const int* pa2 = &a;
//*pa2 = 400; // pa2 是指向 常量整型的指针,不能通过 pa2 修改a值
cout <<"after pa2, value of a is: "<<a <<endl;
指针 | int* pa1 | const int* pa2 |
---|---|---|
对a的权限 | 所有权 | 使用权 |
问题:为什么pa2 不能修改?pa2是否有另外的声明方式?
答:1)pa2 是一种“ 常量整型的指针”,可以理解为公安局,他们记录你们家的地址,只能把你叫过来问话,但是没有所有权。
2)也可以这样声明pa2:int const * pa2。为什么可以这样?,这就要参考最后一个说明了。
- 利用指针将函数对变量用于“所有权”
void fun3(int* pa1){
*pa1 = 500;
}
状态 | a的值 |
---|---|
调用fun3之前 | 300 |
在fun3内 | 300 |
在fun3内修改变量之后 | 500 |
调用fun3之后 | 500 |
这里可以看到,函数fun3的输入参数是 int* 类型的,也就是一个指针,
通过前面的分析我们知道,int* 类型的指针已经拥有对a的“所有权”了,
利用函数fun3,当然对a也拥有“所有权”了。
再看一个例子,
void fun4(const int* pa2){
//*pa2 = 600; // 不能修改 a 的值
}
函数 fun4,对a的作用变成了和 pa2 一样了。
这里,虽然a是变量,但是函数fun2通过pa2使用a也只能使用,即使在函数内部也不能修改,是最低级的“使用权”。
问题:前面提到的指针都是变量,那有没有:常量指针呢?
答:有,既是这个指针看成函数的话,它只能接收某个特定的参数。
声明方式如下:
int * const pa3 = &a;
*pa3 = 700;
cout <<"after pa3, value of a is: "<<a <<endl;
//pa3 = &b; pa3 不能在指向其他的量了
状态 | a的值 |
---|---|
调用pa3之前 | 500 |
调用pa3之后 | 700 |
这里pa3对a,且只能对a 拥有“所有权”,可以改变a的值,但是不能再拥有其他量了。
也就是说,pa3 此时只能“一夫一妻”
是不是很混乱?那为什么混乱?是什么造成的?
答:1)是的。
2)函数对变量的“所有权”与“使用权”不好理解。
3)因为指针的引入。
那为什么还要引入指针呢?
答:为了更多的灵活性,比如起到 fun4 的作用。
代价就是,不好理解。
这里的坑还有很多,这里只是抛砖引玉。
C++内部的机制是如何的呢?
放大招:读取规则,从右到左开始读
借用 这里的两张图理解,从右到左。
整体代码如下:
// csdn_code.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
void fun1(int a, const int b);
void fun2(int& a);
void fun3(int* pa);
void fun4(const int* pa2);
void fun1(int a, const int b){
a = 100; // a 是一个变量,可以修改
//b = 100;// 不能对 b 的值进行修改
}
void fun2(int& a){
a = 200;
}
void fun3(int* pa1){
*pa1 = 500;
}
void fun4(const int* pa2){
//*pa2 = 600; // 不能修改 a 的值
}
int main()
{
int a = 0; // a 是一个变量
a = 90; // 可以对 a 的值进行修改
const int b = 1; // b 是一个常量
//b = 90; // 不能对 b 的值进行修改
cout <<"value of a is: "<<a <<endl;
fun1(a,b);
cout <<"after fun1, value of a is: "<<a <<endl;
fun2(a);
cout <<"after fun2, value of a is: "<<a <<endl;
int* pa1 = &a; // 指针 pa 是一个函数,能够获取 a 的地址
*pa1 = 300;
cout <<"after pa1, value of a is: "<<a <<endl;
const int* pa2 = &a;
//*pa2 = 400; // pa2 是指向 常量整型的指针,不能通过 pa2 修改a值
cout <<"after pa2, value of a is: "<<a <<endl;
fun3(pa1);
cout <<"after fun3, value of a is: "<<a <<endl;
fun4(pa2);
cout <<"after fun4, value of a is: "<<a <<endl;
int * const pa3 = &a;
*pa3 = 700;
cout <<"after pa3, value of a is: "<<a <<endl;
//pa3 = &b; pa3 不能在指向其他的量了
// 将指针看做是一个函数,是否可以改变指针所指向的值
waitKey();
system("pause");
return 0;
}