今天来探究一下指针作为函数参数的情况,顺便说两句它和引用的关系

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void GlableFunction(int* p)
{
p++;
(*p)=100;
//输出
cout<<*p<<endl;
}
int main() {
int num=10;
int* p=&num;
//输出
cout<<*p<<endl;
GlableFunction(p);
//输出
cout<<*p<<endl;
return 0;
}

Error

输出结果:

1
2
10
100

看上去没有错误,不过缺少一个数据,其实是有输出的,显示为空白行

Analysis

上面这个疑惑,还得从下面这段代码说起:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void GlableFunction(int* p)
{
cout<<&p<<endl;
}
int main() {
int num=10;
int* p=&num;
cout<<&p<<endl;
GlableFunction(p);
cout<<&p<<endl;
return 0;
}

输出结果:

1
2
3
0x7fff10e5cc88
0x7fff10e5cc68
0x7fff10e5cc88

从上面的结果可以看出,传入的指针,其实重新开辟了存储空间,相当于是值传递,相当于有一个临时指针,但是其指向的内容没有变.
回到最开始的代码,我们将临时指针指加1,那么我们指向的内容变了.接着赋值.那么,我们其实没有改变main函数指针指向的值,因此输出的结果不同,但是我纳闷的是,为什么最后一个输出是空了?,于是就有了下面这段代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void GlableFunction(int* p)
{
p++;
(*p)=100;
cout<<p<<endl;
}
int main() {
int num=10;
int* p=&num;
cout<<p<<endl;
GlableFunction(p);
cout<<p<<endl;
return 0;
}

输出结果:

1
2
3
0x7ffff1e84f74
0x7ffff1e84f78
0x7fff00000064

这里我们惊奇的发现,第一个和第三个输出居然不一样了,p指针居然发生改变了,那么为什么最开始的代码没有第三个输出就解释得通了,但是指针为什么会变化我就无能为力了

下面来使用一下引用,看看有什么不同:

1
2
3
4
5
6
7
8
9
10
11
12
void GlableFunction(int& p)
{
cout<<&p<<endl;
}
int main() {
int p=10;
cout<<&p<<endl;
GlableFunction(p);
cout<<&p<<endl;
return 0;
}

输出结果

1
2
3
0x7fffc1db240c
0x7fffc1db240c
0x7fffc1db240c

居然把存放指针p的地址传进去了,那么我们在函数内做任何操作,就是直接对p操作了,这才是真正的引用传递

Summary

引用传递比指针传递安全多了,指针传递不知道什么时候就抽风(因为程序员可能对指针进行++等操作),引用其实可以简单的理解成是一个别名,对别名的操作就是对变量本身操作,是通过const指针实现的.
1:引用不能为null
2:引用只能初始化一次.