C++中应该怎样理解实参和形参的区别?

Posted 编程应该这样学

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++中应该怎样理解实参和形参的区别?相关的知识,希望对你有一定的参考价值。

这就是精确理解概念的必要性所在,也是为什么垃圾书害人的原因所在。



“实参”和“形参”是语法层面的东西。


所谓形参,实质上是写程序/生成代码时用的“占位符”。


比如,函数max(a, b)呢,它的意思就是你给我传一个数字a,再传一个数字b;那么我就给你返回两个数字中较大的那个。

其中,数字a和数字b就是形式参数,是方便我说话/写程序用的:

int max(int a, int b) { return a>b?a:b;}

你看,写这个函数时,我不可能知道你将给我传什么进来;类似的,在一个程序运行起来之前,你经常也不知道自己传给max的真实数据是什么……


但关于“在一堆数据中找出最大值”这件事的讨论并不依赖真实数据。我们用a、b、c或者nums[0]、nums[1]指代它们就行了。


这种方便讨论、方便写代码的、在运行时会被实际数据替代的东西,就是所谓的“形式参数”——等同于数学里面的未知数x、y、z常数a、b、c。


到了“现实应用”时,厂长说这一车能拉多少东西?你怎么回答?

设车厢长为a,车宽为b,车厢高度为c,则汽车可载货a x b x c立方米;设货物密度为ρ,则载重量为a x b x c x ρ吨?

信不信厂长一耳刮子把你抽出去。

怎么办呢?

拿实参来。

咱厂的汽车,车厢长10米,车宽2米,车厢高3米,载货量可达60方;咱厂的煤密度1.7~1.9,一车能拉不到120吨。


你看,公式还是那个公式,只是用10、2、3、1.9把里面的abcρ替代了——abcρ就是形参,10、2、3、1.9是实参。


就这么简单点事,遇到半通不通又好装逼的,惨了。

他们会把概念给你模糊化、应用范围扩大化,换句话说似是而非似通非通的就那么搅合成一团了。


比如,形参改变不改变实参,实际上是这样的:

int max(int a, int b) {
if (b>a) a=b;
return a;
}
x=1;
y=2;
printf ("%d", max(x, y));

在这个案例中,函数参数是以传值方式传递;因此你在函数里修改了a值,并不影响函数外的变量x——注意,虽然从结果上说,他的确说对了;但这个讨论本身是错误的。如前所述,形参/实参是语法层面的东西,并不能拿来讨论某种语音关于某个类型的具体实现的语义,更不能把这种讨论等同于形参/实参本身的性质。


换句话说就是,一切编译器都要保证把你指定的x、y的值赋予形参a、b,使得函数max输出正确答案,这是语法规则;但除此之外的细枝末节都和语法无关。


事实上,相关问题的具体表现是“传值”还是“传引用”的区别:传值等于把x、y的值复制一份给a、b,所以改变a、b不影响x、y;而传引用则相当于临时把a、b等同于x、y,于是改变a、b就改变了x、y。


int max(int*a, int *b) {
if(*a < *b) *a=*b;
return *a;
}

int x=3;
int *p=&x;
max(p, &x);

对指针p,这里显然是传值;我们之所以能改变x,是因为指针p指向了x。

类似的,&x是临时取了x的指针,然后把这个指针传值进去;到了max函数里面又通过*a/*b访问了指针指向的空间,从而得到了修改x的效果——然而指针p却不可能在max里面修改,因为它是传值进去的。


你看,一旦把概念区分开,相关讨论是不是一下子变得简单明了、傻子都不可能理解错了?


把每个概念准确放回它自己的位置、准确理解和使用它,这是对初学者最重要也最节省未来精力的事。



如果一开始概念就模糊不清,如你所见,把形参实参扯过来眉毛胡子一把抓,那么自然是越学越晕,很快就发现复杂度失控、然后就再也别想真正学懂了。


以上是关于C++中应该怎样理解实参和形参的区别?的主要内容,如果未能解决你的问题,请参考以下文章

c语言中形参和实参的区别?

c语言中形参和实参的区别是啥?

python实参和形参的区别

什么是JAVA里面的方法体,方法头形参,实参方法调用和局部变量?

Java实参和形参与传值和传引用

c++,类的对象作为形参时一定会调用复制构造函数吗?