栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

深入理解指针作为函数形参

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

深入理解指针作为函数形参

楼主刚从java转到c++,被这个指针搞得头疼,今天晚上碰到这个问题,想了好久,翻书也翻了很久,终于弄明白这其中的奥秘。

首先我们得明白c++中的函数参数传递一个重要规则X(姑且命名X,方便下面叙述)是:

每次调用一个函数,都会重新建立一个形参(类似于临时变量),传入的实参作为初始化值拷贝给形参,一旦实参的值拷贝给形参后,形参和实参其实是两个不同的对象了(c++Prime原话,啃书!!!),就互不干涉了。这句话真的太重要!!!

接下来,通过一个简单的例子,来演示一下指针作为函数形参的两个容易混淆的问题。

1)可以改变指针指向的内容:
void test(int* s) {//指针作为形参

	//s = new int(2);//p指向2这块内存空间
	*s = 20;//指针指向的内容修改
    
}
int main() {
	int a = 1000;
	int* p = &a;
	cout << "调用前p的地址" << p << endl;//调用前p的地址004FFEC0

	cout << "调用前p指向的值" << *p << endl;//调用前p指向的值1000
	test(p);
	cout << "调用后p的地址" << p << endl;//调用后p的地址004FFEC0
	cout << "调用后p指向的值" << *p << endl;//调用后p指向的值20
}

如上面代码所示,main函数中的指针p原本是指向a的内存,且存的数是1000,输出为:

“调用前p的地址004FFEC0”

“调用前p指向的值1000”

 根据X规则,test()函数在调用时,形参s生成临时变量int* s,实参p用于s的初始化,所以s等于p,也可以理解s和p指向同一块内存,故通过*s对指针指向的内容进行修改:*s= 20,也就是等同于*p=20!所以调用后输出:

“调用前p的地址004FFEC0”

“调用前p指向的值20”

即地址没变,但是值修改了。

2) 不可以改变指针的地址:
void test(int* s) {//指针作为形参
	s = new int(2);//p指向2这块内存空间
    cout << "调用后s的地址" << s << endl;//调用后s的地址01034FC8
	//*s = 20;//指针指向的内容修改
}
int main() {
	int a = 1000;
	int* p = &a;
	cout << "调用前p的地址" << p << endl;//调用前p的地址010FF7BC

	cout << "调用前p指向的值" << *p << endl;//调用前p指向的值1000
	test(p);
	cout << "调用后p的地址" << p << endl;//调用后p的地址010FF7BC

	cout << "调用后p指向的值" << *p << endl;//调用后p指向的值1000
}

由第一个例子其实也可以看出来,地址没改变,下面这个例子更加具有说服力。

这个例子中我让test函数对指针的指向进行改变。main中的p仍然指向a,在调用后,根据输出语句的地址发现:指向的还是a,地址未发生改变。但是s的地址和p的地址不一样了,因为“一旦实参的值拷贝给形参后,形参和实参其实是两个不同的对象了,就互不干涉了。”注意!这个s和p不是一个东西了。

3)针对1)和2)的思考

为什么指针作为形参可以改变指针指向的内容,却不可以改变指针的指向?我觉得一定得从函数的参数传递本质着手,函数参数传递的规则是实参是形参的初始化,一旦实参的值拷贝给形参后,形参和实参其实是两个不同的对象了。这个一定好好理解一下!基于这个规则:

当一个函数将指针作为形参时,我们给这个形参传入一个实参(指针(非引用类型)),这个实参的值究竟是什么?其实是指针的地址值,这个地址值传给形参后,后续形参怎么折腾,跟这个实参无关的。如:1)中只是*s = 20,这个s其实就是p,因为s没有对指针指向进行修改(可以理解成s和p指向同一个内存,那么s修改了指针指向的内存保存的值,p指向的值当然也得变)。2)中 s = new int(2);就是把s指向了另一个内存,虽然test函数中s的地址变了;但是跟p没有半毛钱关系,所以main中输出的两个p的地址还是一样的。归根结底还是因为“一旦实参的值拷贝给形参后,形参和实参其实是两个不同的对象了,就互不干涉了”。 这句话理解了, 就啥都明白了。

第一次写帖子,只是想分享今天学到的心得。可能总结的不好,不喜勿喷。如果有错的地方,希望大佬们给与指正!感谢!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/604205.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号