C++形参与实参的区别实例解析

本文以实例阐述了C++中形参与实参的区别,有助于读者加深对于C++形参与实参的认识。

形参出现在函数定义中,在整个函数体内都可以使用, 离开该函数则不能使用。实参出现在主调函数中,进入被调函数后,实参变量也不能使用。 形参和实参的功能是作数据传送。发生函数调用时, 主调函数把实参的值传送给被调函数的形参从而实现主调函数向被调函数的数据传送。

1.形参变量只有在被调用时才分配内存单元,在调用结束时, 即刻释放所分配的内存单元。因此,形参只有在函数内部有效。 函数调用结束返回主调函数后则不能再使用该形参变量。

2.实参可以是常量、变量、表达式、函数等, 无论实参是何种类型的量,在进行函数调用时,它们都必须具有确定的值, 以便把这些值传送给形参。 因此应预先用赋值,输入等办法使实参获得确定值。

3.实参和形参在数量上,类型上,顺序上应严格一致, 否则会发生“类型不匹配”的错误。

4.函数调用中发生的数据传送是单向的。 即只能把实参的值传送给形参,而不能把形参的值反向地传送给实参。 因此在函数调用过程中,形参的值发生改变,而实参中的值不会变化。

参考如下示例:

void Exchg1(int x, int y)
{
 int tmp;
 tmp=x;
 x=y;
 y=tmp;
 printf("Exchg1:x=%d,y=%d\n",x,y);
}
void Exchg2(int &x, int &y)
{
 int tmp;
 tmp=x;
 x=y;
 y=tmp;
 printf("Exchg2:x=%d,y=%d\n",x,y);
}
void Exchg3(int *x, int *y)
{
 int tmp;
 tmp=*x;
 *x=*y;
 *y=tmp;
 printf("Exchg3:x=%d,y=%d\n",*x,*y);
}

void main()
{
 int a=4,b=6;
 Exchg1 (a,b) ;
 printf("a=%d,b=%d\n",a,b);
 Exchg2 (a,b);
 printf("a=%d,b=%d\n",a,b);
 Exchg3(&a,&b) ;
 printf("a=%d,b=%d\n",a,b);
}

这里Exchg1函数被调用的时候,并没有成功交换a跟b的数据。为何呢。
int a=4,b=6;
Exchg1 (a,b) ;   //这里本质上发生的是:Exchg1 (intx=a,int y=b) ;   x跟y是函数定义里面的形参,也就是说这里只是把实参a跟b的值赋予了x,y这2个形参变量。接下来,函数里发生的值互换只换掉了x跟y的值,而实参a跟b没有影响。
再看Exchg2 (a,b);   //再看本质Exchg2 (int &x=a,int &y=b);   这里x跟y都是a,b的引用,操作x跟y交换就等于a跟b交换,自然,调用Exchg2 可以成功交换a跟b
Exchg3(&a,&b) ;   //Exchg3(int *x=&a,int *y=&b);   x跟y2个形参是a跟b的指针,也就是实参数据存放的地址。然后函数里交换了x跟y指向的数据,也就是实参a跟b,所以,交换也是成功的。

代码运行的结果,exchg1没有交换a,b值;exchg2交换了a,b值,到了exchg,a,b的值似乎没有交换,仍旧是a为4,b为6,刚开始以为代码有问题,后来设置了断点之后,发现代码运行到exchg3(&a,&b)时,a=6,b=4了,所以代码运行结果和初始值一样的话,说明已经交换了a,b的值,至此说明代码是没有任何问题的。

(0)

相关推荐

  • c++指针使用形参改变实参的方法

    将10个整数按由小到大的顺序排列 #include <iostream> using namespace std; int main() { //使用形参改变实参数 //将10个整数按由小到大的顺序排列 void select_sort(int *p, int n);//函数声明 int a[10], i; cout << "enter the originl array:" << endl; for (i = 0; i < 10; i++)

  • 老生常谈C++中实参形参的传递问题

    函数中参数的传递 这里说的传递当然是指 实参是如何传递给形参的啦 还挺复杂的~~~~~~~~⊙﹏⊙b汗,这里讲述了4种参数传递的情况和注意事项: 1.非引用形参 这是最普通,也是最简单的形参传递了. 参数传递,即是使用实参副本(注意啊,是副本,不是实参本身)来初始化形参: 因此,在函数体内对形参的修改不会影响实参的值. 如果形参是指针类型的,那么函数体内是否可以修改指针所指向的对象的值呢? 如果您产生这样的疑问,表示您很有想法~~~ 答案是~~~需要分情况讨论. 如果函数的形参是非const类型

  • C++形参与实参的区别实例解析

    本文以实例阐述了C++中形参与实参的区别,有助于读者加深对于C++形参与实参的认识. 形参出现在函数定义中,在整个函数体内都可以使用, 离开该函数则不能使用.实参出现在主调函数中,进入被调函数后,实参变量也不能使用. 形参和实参的功能是作数据传送.发生函数调用时, 主调函数把实参的值传送给被调函数的形参从而实现主调函数向被调函数的数据传送. 1.形参变量只有在被调用时才分配内存单元,在调用结束时, 即刻释放所分配的内存单元.因此,形参只有在函数内部有效. 函数调用结束返回主调函数后则不能再使用该

  • python数据类型判断type与isinstance的区别实例解析

    在项目中,我们会在每个接口验证客户端传过来的参数类型,如果验证不通过,返回给客户端"参数错误"错误码. 这样做不但便于调试,而且增加健壮性.因为客户端是可以作弊的,不要轻易相信客户端传过来的参数. 验证类型用type函数,非常好用,比如 >>type('foo') == str True >>type(2.3) in (int,float) True 既然有了type()来判断类型,为什么还有isinstance()呢? 一个明显的区别是在判断子类. type(

  • JavaScript常用截取字符串的三种方式用法区别实例解析

    stringObject.substring(start,stop) 用于提取字符串中介于两个指定下标之间的字符. start必需.一个非负的整数,规定要提取的子串的第一个字符在 stringObject 中的位置. stop可选.一个非负的整数,比要提取的子串的最后一个字符在 stringObject 中的位置多 1.如果省略该参数,那么返回的子串会一直到字符串的结尾. start从0开始 到stop(不包含stop)结束 不接受负的参数. stringObject.substr(start,

  • C#中out与ref的区别实例解析

    本文实例讲述了C#中Out与Ref的区别,可以加深C#程序设计人员对Out和Ref用法的理解,具体分析如下: 一.区别分析: Out和Ref作为参数传递到方法体中,所传递的都是引用地址,两者在操作上本身没有区别. 但Out传递到方法体时,参数会清空,这意味着在方法体内使用Out参数前必须赋值. 而Ref传递到方法体时,其参数也是一起被传递进来,所以作为Ref参数传递,方法体中可以不对其参数赋值. 二.实例代码如下: class Program { /*ref是有进有出,out是只出不进*/ st

  • C#入门之checked和unchecked的区别实例解析

    本文以实例形式对比测试了C#中checked和unchecked的区别,对于C#初学者来说有很好的借鉴参考价值.具体分析如下: int类型的最大值是2147483647,2个最大值相加就会超出int的最大值,即出现溢出. class Program { static void Main(string[] args) { int y = 2147483647; int x = 2147483647; int z = x + y; Console.WriteLine(z.ToString()); C

  • C#中委托和事件的区别实例解析

    本文实例分析了C#中委托和事件的区别,分享给大家供大家参考之用.具体如下: 大致来说,委托是一个类,该类内部维护着一个字段,指向一个方法.事件可以被看作一个委托类型的变量,通过事件注册.取消多个委托或方法.本篇分别通过委托和事件执行多个方法,从中体会两者的区别. 一.通过委托执行方法 class Program { static void Main(string[] args) { Example example = new Example(); example.Go(); Console.Re

  • JavaScript undefined及null区别实例解析

    在JavaScript中,将一个变量赋值为undefined或null,老实说,几乎没区别. var a = undefined; var a = null; 上面代码中,a变量分别被赋值为undefined和null,这两种写法几乎等价. undefined和null在if语句中,都会被自动转为false,相等运算符甚至直接报告两者相等. if (!undefined) console.log('undefined is false'); // undefined is false if (!

  • Java instanceof和getClass()区别实例解析

    对象 instanceof 类名,表示 对象是类名的实例,或者是其子类的实例,返回 true,否则返回 false. 对象.getClass() == 类名.class ,表示 只有对象是该类的实例,才返回 true class A { } class B extends A { } Object o1 = new A(); Object o2 = new B(); o1 instanceof A => true o1 instanceof B => false o2 instanceof A

  • Java泛型extends及super区别实例解析

    <? extends T>和<? super T>是Java泛型中的"通配符(Wildcards)"和"边界(Bounds)"的概念. <? extends T>:是指"上界通配符(Upper Bounds Wildcards)" <? super T>:是指"下界通配符(Lower Bounds Wildcards)" 为什么要用通配符和边界? 使用泛型的过程中,经常出现一种很

  • Vue中computed及watch区别实例解析

    计算属性computed : 1. 支持缓存,只有依赖数据发生改变,才会重新进行计算 2. 不支持异步,当computed内有异步操作时无效,无法监听数据的变化 3.computed 属性值会默认走缓存,计算属性是基于它们的响应式依赖进行缓存的,也就是基于data中声明过或者父组件传递的props中的数据通过计算得到的值 4. 如果一个属性是由其他属性计算而来的,这个属性依赖其他属性,是一个多对一或者一对一,一般用computed5.如果computed属性属性值是函数,那么默认会走get方法:

随机推荐