-
2020-08-26 21:16:02
形参
所谓形参,就是形式参数,在你没有调用它的时候他是没有值的。
实参
可以理解为你创建的变量就是实参,有具体的值。就算你不赋值他也会有默认的初始值。
形参会不会影响实参?
答案是:会!
但是并不是全部都会影响
形参不会影响基本数据类型的实参public static void changeNumber(int num) { num = 10; System.out.println("执行change方法时" + num); } public static void main(String[] args) { /*基本数据类型*/ int num = 1; System.out.println("执行方法前:" + num); changeNumber(num); System.out.println("执行方法后:" + num); }
输出结果
执行方法前:1 执行change方法时10 执行方法后:1
结果显示基本数据类型时,形参并不会影响实参。
形参可以影响引用类型的实参public static void main(String[] args) { /*引用数据类型*/ StringBuffer stringBuffer = new StringBuffer("abc"); System.out.println("执行方法前:"+stringBuffer); changeString(stringBuffer); System.out.println("执行方法后:"+stringBuffer); } public static void changeStringBuffer(StringBuffer stringBuffer){ stringBuffer.append("def"); System.out.println("执行方法时:"+stringBuffer); }
输出结果
执行方法前:abc 执行方法时:abcdef 执行方法后:abcdef
形参影响了引用类型的实参!
下一个例子!public static void main(String[] args) { /*引用数据类型*/ String string = "abc"; System.out.println("执行方法前"+string); changeString(string); System.out.println("执行方法后"+string); } public static void changeString(String string) { string = string.concat("def"); System.out.println("执行方法时" + string); }
执行结果:
执行方法前abc 执行方法时abcdef 执行方法后abc
形参没有影响引用类型的实参?
那么什么情况下才会有 形参影响实参呢?
这就要考虑到底是怎么改变的。
首先要知道引用数据类型,变量存储的只是一个地址值!
形参只有在执行的时候才会创建一个临时的空间存储这个形式参数,方法结束这个形式参数的生命周期就结束了。那么形式参数影响实参的时机就肯定是在这个生命周期内!
一步一步考虑,调用方法的时候需要将实参传入方法,让形参暂时有一个值,因为是引用数据类型,所以形参此时存储的是和实参一样的地址值。
此时形式参数进行一系列的操作都是对堆空间中的同一个内容进行操作的,所以如果形式参数对堆空间的值修改了,那么实参再查看堆空间里面的数据的时候就是已经被改变过了的数据。这就是为什么StringBuffer受到了形参的影响的原因。
那么为什么String就没有受到影响呢?
看changeString()
方法种,执行的是String的concat方法。public String concat(String str) { int otherLen = str.length(); if (otherLen == 0) { return this; } int len = value.length; char buf[] = Arrays.copyOf(value, len + otherLen); str.getChars(buf, len); return new String(buf, true); }
这是String类中的concat方法,怎么处理的不用看明白,直接看他的返回值
return new String(buf, true);
new是干嘛的?创建了新的对象啊!创建对象就是再堆空间新开辟空间了呀!
这就意味着此时形参存储的地址值现在已经不再是最开始实参给他的地址值了,不管他在怎么操作都是对一个新的堆空间地址中的数据进行操作,原来的实参的堆空间的数据没有发生过改变,所以方法结束后,实参的内容并没有发生改变。
总结来说就是形参影响引用数据类型的实参,要看地址值是不是发生了改变,如果形参的地址值发生了改变,那么形参就不会影响实参,如果形参的地址值没有发生改变,那他就会影响实参。总结
形参并不会影响基本数据类型的实参。
形参只有在存储的地址值不发生变化的时候才会影响实参。更多相关内容 -
浅谈c++中形参不能改变实参
2020-04-03 18:48:52c语言我们都知道形参不能改变实参,实参能改变形参,我们能保证自己很熟悉这个概念吗,能不能保证自己每次都不犯错,掉坑里。 #include <iostream.h> #include <string.h> void fun( char *s) { char a...c语言我们都知道形参不能改变实参,实参能改变形参,我们能保证自己很熟悉这个概念吗,能不能保证自己每次都不犯错,掉坑里。
#include <iostream.h>
#include <string.h>
void fun( char *s)
{
char a[10];
strcpy ( a, “AAAAAA” );
cout<<“形参未改变,实参传递给实参的值:”<<s<<endl;
s=a;
cout<<"形参改变后字符串后的值: "<<s<<endl;
}
main( )
{
char *p= “BBBBBB” ;
fun( p );
cout<<"实参在形参被改变后的值: "<<p<<endl;
}
这是我自己写的实参改变形参的一段代码,末尾我会附上运行截图
在谈论这个问题前先明确几个概念形参是什么?
形参变量只有在被调用时才分配内存单元,在调用结束时,即刻释放所分配的内存单元。因此,形参只有在函数内部有效。函数调用结束返回主调函数后则不能再使用该形参变量。实参是什么?
实参可以是常量、变量、表达式、函数等,无论实参是何种类型的量,在进行函数调用时,它们都必须具有确定的值,以便把这些值传送给形参。因此应预先用赋值,输入等办法使实参获得确定值。要实现调用函数,形参传递到实参要注意的事项有哪些?
实参的类型,数量定义的顺序都是不能改变的,这样才能调用,不然会出现不匹配错误,比如定义一个函数
void ss(int a,char c) //a和c就是形参
我们在调用的时候就要提前定义实参,严格按照 整形,字符型的顺序才能调用
int f;
char v;
ss(f,v);//f和v就是实参
参数的传递方向是单向的,只能从实参传到形参(不要妄想形参反客为主改变实参,那是不可能的,之后用代码进一步证明)附上我写的字符串复制的例子,感兴趣的话可以自己实践一下,也可以复制我的操作一下
简单解释一下我的这个指针指向的例子
实参p是字符型指针,赋给初始值为BBBBBB,然后利用函数,形参为字符型指针s,形参改变实参的证明就是我们没给s赋初值但是初始值为实参的值,这里输出BBBBBB,所以实参改变了形参;s初始值和实参一样为BBBBBB,我们这里继续改变形参的值,改为AAAAAA,输出,发现形参s改变成AAAAAA;
我们都知道C语言是从上到下按顺序执行的,我们在main函数调用函数后来看一下有没有通过改变形参的值改变了实参,输出实参p,实际上没有改变,实参p的值依然是BBBBBB,所以实参并没有受到改变;
本人很菜,有什么不完全或者有误的地方请指出,有问题请留言或者私聊我,写作不易,有帮助的话请留下一个赞,谢谢。
附上我的运行截图帮助理解: -
java形参的改变会影响实参吗?
2021-05-07 11:42:27java形参的改变会影响实参吗? 昨天做题的时候遇到了这个问题(如图所示),传入的参数是int[]数组,实参跟着形参一起改变了。但是之前传入int型参数时形参的改变是不会影响实参的。所以想探究一下这个问题,到底...java形参的改变会影响实参吗?
昨天做题的时候遇到了这个问题(如图所示),传入的参数是int[]数组,实参跟着形参一起改变了。但是之前传入int型参数时形参的改变是不会影响实参的。所以想探究一下这个问题,到底什么情况下形参的改变会影响实参。
- 形参和实参:首先分清楚形参和实参区别。简要来说形参就是定义方法的时候用到的参数,方法被调用时就是靠它来接收传入的参数。例如上图中的reverse(int[] arr,int k),这里的arr和k就是形参。实参就是调用方法时传进去的参数。例如上图中的reverse(arr,k),这里的arr和k是实参。
- 值传递和引用传递: 值传递就是在调用方法时,实参把它的值给到形参,形参把这个值拷贝一份,再拿到方法里用。所以传参之后它俩互不相关了,形参的改变就不会影响到实参。而引用传递,在调用方法时传递的是值的引用,也就是说形参拿到的是实参所对应的内存空间的地址,那么传参之后形参和实参指向的就是同一个内存空间,理所当然实参会跟形参一起改变。
分清了值传递和引用传递之后再来看文章开头说的int[]和int类型的参数有什么区别。
当参数为int[]数组:// int[]数组作为参数 public static void main(String[] args){ int[] arr = {3,2,1,4}; reverse(arr,3); System.out.println("翻转后数组为:"); for(int i : arr) { System.out.print(i); } } //翻转数组从0到k-1 public static void reverse(int[] arr,int k) { int i = 0,j=k-1; int temp=0; while(i<j) { temp= arr[i]; arr[i]=arr[j]; arr[j]=temp; i++; j--; } }
输出结果:
可见调用方法之后实参跟着形参一起被修改了。当参数为int数值:
// 当参数为int型 public static void main(String[] args){ int a = 0; changeInt(a); System.out.println("主函数中实参a的值为:"+a); } //修改数的值 public static void changeInt(int a) { a=100; System.out.println("changeInt方法中形参a的值为"+a); }
输出结果:
可见形参虽然被修改了,但是实参还是原来的值,并没有一起被修改。发生这样的情况,原因在于:数组是引用类型,它作为参数时发生的传递是引用传递;而int是基本类型,它作为参数时发生的传递是值传递。
特别:需要注意的是封装类和String类比较特殊,虽然是引用类型,但是由于其本质是由final修饰的,不能被修改,所以作为传参时实参是不会跟随形参发生改变的。
例如Integer作为参数:public static void main(String[] args){ Integer a = 0; changeInt(a); System.out.println("主函数中实参a的值为:"+a); } //修改数的值 public static void changeInt(Integer a) { a=100; System.out.println("changeInt方法中形参a的值为"+a); }
输出结果:
String作为参数:public static void main(String[] args){ String a = "0"; changeString(a); System.out.println("主函数中实参a的值为:"+a); } //修改数的值 public static void changeString(String a) { a="100"; System.out.println("changeString方法中形参a的值为"+a); }
输出结果:
总结:例如数组之类的引用类型作为参数时,形参的修改会影响实参;而基本类型和特别的引用类型(封装类、String类)作为参数时,形参的修改不会影响实参。关于封装类的地址传递参考链接: Interger是值传递还是地址(引用)传递?
-
形参与实参
2021-04-18 17:06:52形参变量: 形参变量是功能函数里的变量,只有在被调用的时候才分配内存单元,调用结束后立即释放。所以形参只在函数内部...举例一:(形参不能改变实参) 看看下面这段代码中实参和形参的位置, 这个过程中实参并形参变量:
形参变量是功能函数里的变量,只有在被调用的时候才分配内存单元,调用结束后立即释放。所以形参只在函数内部有效。
实参变量:
实参可以是常量,变量,表达式,函数等等,但无论是何类型,在进行函数调用是,他们必须有确定的值,以便把这些值拷贝给形参。
形参和实参在内存中有不同的位置:
在函数运行时,形参和实参是不同的变量,他们在内存中处于不同的位置。形参将实参的内容拷贝一份,在该函数运行结束的时候释放,实参内容不变。
举例一:(形参不能改变实参)
看看下面这段代码中实参和形参的位置,
这个过程中实参并未得到改变,交换函数无效!从这个例子我们也理解了“形参不能改变实参”。举例二:(避免形参不能改变实参的做法)
利用指针解引用直接对实参进行操作!!
再看下面这段代码,我们来看看这个过程中形参与实参在内存里的位置:
这个过程里,我们通过对指针的解引用,实现了对实参的直接改变,交换函数有效!
举例三:(实参中数组在调用函数时退化成指针)
选中部分这样的操作是不被允许的,它得到的结果只能是*arr的大小,是不会得到数组ar的大小的。这是因为再调用函数时,实参中数组退化先为指针,然后再被调用。故而非法。这也是c语言一大惊天bug。而解决的办法就只能是再系统调用函数之前就计算出数组的大小,我们就不得不引入变量size了。
-
形参改变实参的值不变(C语言基础知识加例题讲解)
2017-02-18 22:46:18即形参的值改变不影响实参的值,不是为了说明,形参的值改变,调用函数进行计算出来的值不变,而是为了说明,形参和实参同名的情况下,改变形参的值实参的值不变。 34 在C语言中,只有在使用时才占用内存单元的... -
c语言——指针作为函数形参,改变实参的值的问题。
2021-05-23 21:03:49所以一般的传值传参不会改变实参的值。但是若是函数的形参是指针变量的话在调用函数时将变量的地址传递给指针,在函数内部对函数进行解引用改变指针的值那么相应实参的值也会被更改。这就是所谓的传址传参。这种传参... -
方法的参数传递(形参影不影响实参) 成员变量和局部变量
2022-01-12 12:48:07对于基本数据类型的参数,形参的改变不影响实参的值。 public class comDemo { public static void main(String[] args) { int number = 100; System.out.println("调用change方法前"+number); change(number... -
形参对实参的影响
2020-12-25 20:26:44形不改实 形参的改变一般不会影响实参的...由上面的例子可以看出,实参的改变没有影响到实参的改变。 原因是形参a,b的作用域只在fun1函数里,函数结束形参也就被释放了。而且调用函数fun1时,实参传递给形参时,不是用 -
在c语言中怎样使形参值改变实参值也跟着改变呢,c语言的初始化的几个小例子。
2021-05-21 08:37:09/*==============================================================================文 件 名 : testpointer.c功 能 : 关于指针改变实参的测试例子,仅供测试作 者 : jernymy日 期 : 2010/01/10备 注 : 基于VC6.0的... -
java中值传递的三种情况,形参的改变不影响实参
2018-03-25 16:02:41public static void main(String[] args) { //第一种基本数据类型 int a= 1; int b= 2; System.out.println("a:"+a+"---"+"b:"+b); change(a,b); System.out.println("... -
【C语言】关于函数中形参与实参(实例分析)
2022-02-06 15:28:38作者目前就读于,双非本科,大一,很多地方理解不当还望各位大佬耐心教导。万分感谢! 现在也是大年初六,在这给大家们拜一个...3.无论实参是何种类型的量,在进行函数调用时,它们都必须有确定的值, 以便... -
c语言函数的值传递机制(swap函数怎么通过形参改变实参的值)
2021-10-03 20:41:43swap函数中体现出的c语言函数的值传递机制(形参中int * &是什么意思) 目前初学C语言,对于深层内存机制了解不是十分透彻,只是将自己的理解方式简单记录一下。 我们知道交换两个变量的数值非常简单,只需要一... -
C语言形参和实参的区别(非常详细)
2019-11-03 17:45:23如果把函数比喻成一台机器,那么参数就是原材料,返回值就是最终产品;从一定程度上讲,函数的作用...形参(形式参数) 在函数定义中出现的参数可以看做是一个占位符,它没有数据,只能等到函数被调用时接收传递进来... -
Java形参和实参
2021-08-05 18:41:28PJava 形参和实参 /– 例子 –/ public class Test { public static void main(String[] args) { Integer a = 1; Integer b = 2; System.out.println(“a 和 b 的原始的值:”+a+" “+b); swap(a,b); System.out.... -
C语言中,如何利用函数和指针变量通过形参变量的值改变实参变量的值
2021-05-22 08:45:47必备知识:c语言中的函数调用和...函数的一个功能就是传递数值进行运算,那么我们如何利用函数和指针变量通过形参变量的值改变实参变量的值呢?首先,让我们先举一个例子。#includeint main(){void func(int a,int ... -
形参和实参的区别
2020-04-09 17:11:13实参可以是常量、变量、表达式、函数等, 无论实参是何种类型的量,在进行函数调用时,它们都必须具有确定的值, 以便把这些值传送给形参。 因此应预先用赋值,输入等办法使实参获得确定值。 ... -
c++实参形参
2020-02-22 20:55:58形参(形式参数) 在函数定义中出现的参数可以看做是一个占位...形参和实参的功能是传递数据,发生函数调用时,实参的值会传递给形参。 当形参是引用类型时,对应的实参被引用传递,引用形参是对应的实参的别名。 形... -
Python中实参随形参改变而改变的问题
2022-03-04 22:15:30我们对常见的数据类型进行实验,检测形参的该表是否会改变传入的实参。 变量 def change(a): a = 2 print(a) b = 1 change(b) print(b) >>2 >>1 可见,变量的值并没有随形参的改变而改变 元组 def ... -
形参和实参
2018-06-10 11:11:281、概念形参全称为“形式参数”是在定义函数名和函数体的时候使用的参数,目的是用来接收调用该函数时传递的参数。形参的作用是实现主调函数与被调函数之间的联系,通常将函数所处理的数据,影响函数功能...实参实参... -
c++形参改变实参(对指针的理解
2016-04-15 16:28:00由于作业设涉及到用形参改变实参,特意的再探指针定义。 下面看例子: 1.使用指针形参 正确代码: 1 #include 2 using namespace std; 3 class test 4 { 5 int a; 6 public : ... -
C语言之形参和实参详解
2021-05-21 16:06:52一 形参与实参1).定义形参:形式参数。就是定义函数的时候,写在函数名小括号后面的参数叫形参实参:实际参数。就是调用函数的时候,调用函数时写在函数名...值传递:在函数内改变了形参的值,不会影响到外面的实参d... -
C语言形参跟实参详解
2019-01-29 15:27:56今天我们来说下c语言形参与实参的区别,形参跟实参理解的话也很简单,但是好多同学关于这个知识点都是一知半解,没有真正的去透彻,在真正引用的时候还会出现很多问题,而百度的时候又会说看不懂,所以我们今天来做... -
java形参实参传递
2021-02-12 14:06:59Java参数传递(其实java参数传递都是值传递,只不过当参数是对象时,传递的是地址,所以参数是对象时,如果通过形参改变对象内的内容,实参对象的内容也会改变,当对形参重新赋值时,这意味形参指向了别的对象,所以... -
形参和实参之间的三种传递方式
2021-05-24 07:03:51//形参和实参之间的三种传递方式void fun(int i){ i++;}void fun(int &i){ i++;}void fun(int *i){ *i=*i+1;}若指针指向的是数组的首地址,则数组元素的访问方式1.数组名[i] 指针名[i]2.*(数组名+i) *(指针名+i)... -
Java 形参和实参
2018-09-22 21:56:54/*-- 例子 --*/ public class Test { public static void main(String[] args) { Integer a = 1; Integer b = 2; System.out.println("a 和 b 的原始的值:"+a+" "+b); swap... -
python 实参与形参
2020-01-10 14:48:42实参是一个实实在在存在的参数,是实际占用内存地址的,而形参只是意义上的一种参数,在定义的时候是不占内存地址的,如在上面例子中,username就是一个形参,尼古拉斯赵四是我在调用函数时传入的一个实参,它的值被... -
形参不会改变实参,int &m与int m作为形参对比
2020-05-20 16:17:38今天遇到一个关于实参传入形参后对形参赋值会不会改变实参的问题,有点绕,看一下例子: #include <stdio.h> int test(int m) { m=5; } int test1(int &m) { m=5; } int main() { int a=0; ...