-
2021-01-29 10:38:02
一、复习巩固
首先我们复习一下什么叫做值传递,什么叫做地址传递
1.值传递
在实参向形参传递的过程中,传递的只是实参的值,而在函数体操作的时候,实际操作的并不是实参而是形参,所以,值传递不改变原变量值
2.地址传递
在实参向形参传递的过程中,传递的是实参的地址,实参和形参共同指向同一块地址,所以,在函数内部修改形参的同时也修改了实参,即,地址传递会改变原变量
二、代码实例讲解:
#值传递 a = 2 def valueTransmit(x): print('x没有修改之前的值:{}'.format(x)) print('x没有修改之前的地址:{}\n'.format(id(x))) x = 3 print('x修改之后的值:{}'.format(x)) print('x修改之后的地址:{}\n'.format(id(x))) pass pass print('a没有传递之前的值:{}'.format(a)) print('a没有传递之前的地址:{}\n'.format(id(a))) valueTransmit(a) print('a传递之后的值:{}'.format(a)) print('a传递之后的地址:{}'.format(id(a))) #运行结果: a没有传递之前的值:2 a没有传递之前的地址:23031952 x没有修改之前的值:2 x没有修改之前的地址:23031952 x修改之后的值:3 x修改之后的地址:23031968 a传递之后的值:2 a传递之后的地址:23031952
这里证明a的传递是值传递,函数内部对a的改变对他没有丝毫影响
#地址传递 listA = [] def addressTransmit(x): print('x没有修改之前的地址:{}'.format(id(x))) print('x没有修改之前的值:{}\n'.format(x)) x.append([1,2,3,4]) print('x修改之后的地址:{}'.format(id(x))) print('x修改之后的值:{}\n'.format(x)) pass pass print('listA传递之前的地址:{}'.format(id(listA))) print('listA传递之前的值:{}\n'.format(listA)) addressTransmit(listA) print('listA传递之后的地址:{}'.format(id(listA))) print('listA传递之后的值:{}'.format(listA)) #运行结果: listA传递之前的地址:33668040 listA传递之前的值:[] x没有修改之前的地址:33668040 x没有修改之前的值:[] x修改之后的地址:33668040 x修改之后的值:[[1, 2, 3, 4]] listA传递之后的地址:33668040 listA传递之后的值:[[1, 2, 3, 4]]
这里证明listA的传递是地址,函数直接对原来的变量进行操作,所以listA最终的值改变了。
三、归纳总结
1.函数传参过程中,对于一些基本数据类型,如int(整型),float(浮点型),str(字符串)等,是值传递,函数内部对以上数据类型的数据进行修改时并不会改变原值。
2.对于list(列表)、dict(字典)、tuple(元组)则是地址传递,函数内部对以上数据类型操作时会改变原数据值。
更多相关内容 -
C语言值传递与地址传递
2021-07-14 20:36:33二、C语言函数的地址传递 三、局部变量作为函数返回值 #include <stdio.h> char *fun(void) { static char buf[] = "helo world!";//这里有没有static会影响输出结果,加上static相当于数据存储在数据区 ...一、C语言函数的值传递
C语言的值传递,顾名思义就是使用常量、数组等作为函数的参数,定义一个函数后,其在被主函数调用的过程中,实际是将实参的值复制到形参相应的存储单元中,即形参和实参分别占用不同的存储单元。
值传递的特点:
值传递的最大的特点就是单向传递,即主调函数被调用时给形参分配存储单元,把实参的值传递给形参,在调用结束后,形参的存储单元被释放,而形参值的任何变化都不会影响到实参的值,实参的存储单元仍保留并维持数值不变。
如下代码所示,定义了一个函数swap()用于交换两个参数的值,在被主函数调用的过程中,a和b的值相当于被拷贝了一份过去swap函数,无论在swap()函数中完成了什么操作,都是不会影响到主函数中定义的两个变量a、b存储的值的。#incldue <stdio.h> void swap(int x,int y) { int temp; temp = x; x = y; y = temp; } int main(int argc, char *argv[]) { int a = 12,b = 24; swap(a,b); // 值传递 printf("a = %d b = %d",a,b); return 0; }
程序运行后的结果如下:
C:\Users\11197\Desktop\main>swap a = 12 b = 24
二、C语言函数的地址传递
大家呢都知道,在C语言中,数组名就代表着数组存储空间的首地址,所谓的地址传递,就是函数的参数是数组名或者指针,传递的是数组的首地址或指针的值,而形参接收到的是地址,即指向实参的存储单元,形参和实参占用相同的存储单元,即形参和实参是相同的。
地址传递的特点:
形参并不存在存储空间,编译系统不为形参数组分配内存。因此在数组名或指针作函数参数时所进行的传送只是地址传送,形参在取得该地址之后,与实参共同拥有一段内存空间,形参的变化也就是实参的变化。
实例代码如下,函数swap()传入的是两个地址,在主函数调用的过程中,将变量a、b的地址传入了swap()函数中,在swap()函数中,通过指针解引用等操作完成了两个地址的存储值的值交换。
#include <stdio.h> void swap(int* x,int* y) { int temp; temp = *x; *x = *y; *y = temp; } int main(int argc, char *argv[]) { int a = 12,b = 24; swap(&a,&b); //地址传递 printf("a = %d b = %d\n",a,b); return 0; }
函数运行结果如下:
C:\Users\11197\Desktop\main>dizhi a = 24 b = 12
可以看到,通过地址传递的方式,成功的交换了变量a、b中存储的值。
三、局部变量作为函数返回值
局部变量是不会进行存储的?所以函数void *fun(void)调用结束的时候,buf[]被释放了,没法返回一个地址。
#include <stdio.h> char *fun(void) { char buf[] = "helo world!"; return buf; } int main() { char *p; p=fun(); printf("the p is %s\n",p); return 0; }
可以看到程序运行的结果如下:
C:\Users\11197\Desktop\main>jububianliang the p is Pi
接下来在函数中的bud前面加上static看看效果,加上这个值相当于将buf[]存储在不易被改变的静态区
#include <stdio.h> char *fun(void) { static char buf[] = "helo world!";//这里有没有static会影响输出结果,加上static相当于数据存储在数据区 return buf; } int main() { char *p; p=fun(); printf("the p is %s\n",p); return 0; }
我们来看运行输出的效果:
C:\Users\11197\Desktop\main>jububianliang the p is helo world!
将函数void *fun(void)改变为只单单返回一个“hello world!”也可以看到相同的效果:
#include <stdio.h> char *fun(void) { return "hello world!"; } int main() { char *p; p=fun(); printf("the p is %s\n",p); return 0; }
运行效果如下:
C:\Users\11197\Desktop\main>jububianliang the p is helo world!
-
C语言函数传递方式-值传递和地址传递
2020-03-02 12:10:20C语言函数传递方式 值传递 定义 所谓的值传递,顾名思义就是使用变量、常量、数组等作为函数的参数。 地址传递C语言函数传递方式
值传递
定义
- 所谓的值传递,顾名思义就是使用变量、常量、数组等作为函数的参数。实际是将实参的值复制到形参相应的存储单元中,即形参和实参分别占用不同的存储单元。
特点
- 值传递的特点是单向传递,即主调函数被调用时给形参分配存储单元,把实参的值传递给形参,在调用结束后,形参的存储单元被释放,而形参值的任何变化都不会影响到实参的值,实参的存储单元仍保留并维持数值不变。
示意图
其实值传递过程中由隐含的一步,如下代码所示:int x = a; int y = b;
所以swap1函数交换的是x和y,而原来的a和b从未改变。
代码演示
void swap1(int x,int y) { int temp; temp = x; x = y; y = temp; printf("x = %d,y = %d\n",x,y); } int main(int argc, char *argv[]) { int a = 12,b = 24; swap1(a,b); // 值传递 printf("a = %d b = %d",a,b); }
运行结果
地址传递
说明
- 大家都知道,在C语言中,数组名就代表数组的首地址。所谓的地址传递,指的就是函数的参数是数组名或者指针。传递的是数组的首地址或指针的值,而形参接收到的是地址,即指向实参的存储单元,形参和实参占用相同的存储单元,即形参和实参是相同的。
特点
- 形参并不存在存储空间,编译系统不为形参数组分配内存。因此在数组名或指针作函数参数时所进行的传送只是地址传送,形参在取得该地址之后,与实参共同拥有一段内存空间,形参的变化也就是实参的变化。
示意图
注意:这里也有一个隐含动作,如下代码所示:x = &a; y = &b;
分别将a的地址,b的地址赋值给x和y,这样swap2函数操作的数其实就是a和b。
代码演示
void swap2(int* x,int* y) { int temp; temp = *x; *x = *y; *y = temp; printf("x = %d y = %d\n",*x,*y); } int main(int argc, char *argv[]) { int a = 12,b = 24; swap2(&a,&b); //地址传递 printf("a = %d b = %d",a,b); }
运行结果
以上就是C语言值传递和地址传递的区别了,相信大家应该很清楚了吧! -
C++ 值传递和地址传递的区别
2021-08-20 16:42:04这里写目录标题1.概念解释1.1值传递:1.2指针传递:2.代码案例2.1值传递 1.概念解释 1.1值传递: 形参是实参的拷贝,在外部某个函数中改变形参的值并不会...形参为指向实参地址的指针,当对形参的指向操作时,就相当1.概念解释
1.1值传递:
形参是实参的拷贝,在外部某个函数中改变形参的值并不会影响主函数内的数据。从被调用函数的角度来说,值**传递是单向的(实参->形参),参数的值只能传入,不能传出**,当函数内部需要修改参数,并且不希望这个改变影响调用者时,采用值传递。但是当数据量很大,某个函数只用其中的一部分的时候是不可取的,因为它会把整份数据都拷贝过来。
1.2指针传递:
形参为指向实参地址的指针,当对形参的指向操作时,就相当于对实参本身进行的操作,函数传递的时候只传入一个指针占用四个字节的空间。但是在函数中数据外部数据也会发生改变。
2.代码案例
#include<iostream> using namespace std; //定义结构体与创建结构体变量 struct Student { string name; int age; }; // 采用值传递的方式改变结构体变量与输出 void printStudent1(Student p) { p.age = 18; cout << "采用值传递的方式:" << " 姓名:" << p.name << " 年龄: " << p.age << endl; } // 采用地址的方式改变结构体变量与输出 void printStudent2(Student *p) { p->age = 18; cout << "采用地址传递的方式:" << " 姓名:" << p->name << " 年龄: " << p->age << endl; } int main() { Student s = { "张三",15 }; printStudent1(s); cout << "源结构体的变量:" << " 姓名:" << s.name << " 年龄: " << s.age << endl; printStudent2(&s); cout << "源结构体的变量:" << " 姓名:" << s.name << " 年龄: " << s.age << endl; system("pause"); return 0; }
结果如下:
可以理解为值传递的时候函数把源数据传递给了新变量,而函数中的更改都是对新变量的操作
指针传递是在函数中传递了指向源数据的指针,函数中的数据都是对源数据的操作
如果指针传递的时候防止误修改可使用const修饰void printStudent2( const Student *p) { p->age = 18; cout << "采用地址传递的方式:" << " 姓名:" << p->name << " 年龄: " << p->age << endl; }
这时候如果在程序中修改程序会报错
-
C++函数的三种传参方式(值传递,地址传递,引用传递)
2021-11-02 10:14:23} 这里所用的就是地址传递了,所谓地址传递,也很好理解,传递的是地址,那么主函数调用的时候就要传进x和y的地址,这里就要用到取地址符(&),将x和y的地址传进去,函数里面由于a和b都是指针类型,所以在交换的... -
值传递和地址传递
2020-07-09 14:39:59值传递和地址传递 值传递:是指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数。 package dubhe; public class text { public static void main(String[] ... -
C++中函数参数传递的三种方式:值传递、地址传递、引用传递及const在函数形参中的应用
2022-04-17 16:54:481 值传递 调用子函数时把主函数中实参的值传递给子函数的形参,在子函数中完成对应的操作。此时,子函数中的所有操作都是对形参来进行的,因此主函数中的实参不受子函数的影响。 且子函数的形参存放在栈区,函数... -
指针与引用, 值传递与地址传递的关系
2019-05-21 22:43:20前言 “引用”的这个词我到经常使用到,但是它经常是作为动词出现的,而作为名词,我却很少用到。这个上次面试就问我指针和引用的...在函数中可以使用但是无法修改原来的实参的值,而地址传递则是将变量的地址传递... -
C语言中关于值传递、地址传递和引用传递的区别
2019-03-10 14:19:11大多数人都知道,使用值传递对形参的更改不会影响实参,但是地址传递和引用传递却会, 最经典的例子莫过于交换两个数字。 但是,为什么在使用值传递的时候,传递一个地址给行参依然没有影响到实参了,是因为改变只... -
Java中的值传递和地址传递(传值、传引用)
2021-02-12 15:09:20有人已经总结过: 参见 1、对象是按引用传递的 2、Java 应用程序有且仅有的一种参数传递机制,即按值传递 3、按值传递意味着当将一个参数传递给一个函数时,函数接收的是原始值的一个副本 4、按引用传递意味着当将... -
Java方法中值传递与地址传递的区别
2019-04-07 20:47:43Java方法中,值传递和地址传递一直让我很迷惑,在考试前夕,认真看资料分析了一下,供大家参考。 01 首先看题目: public class test { public static void main(String[] args) { String str1="abc"; ... -
C++中值传递、地址传递与引用传递
2020-04-08 17:05:011.值传递 所谓值传递,就是函数调用时实参将数值传入给形参 值传递时,如果形参发生改变,并不会影响实参 void swap(int a, int b) { int temp = a; a = b; b = temp; cout << "swap函数中a = " <&... -
C语言指针值传递和地址传递
2020-07-05 21:08:32C语言传参分为值传传递和地址传递。C语言指针传参时,可以通过指针引用方式改变指针指向的值。改变变量,可以使用指针应用方式,改变地址,使用指针的指针引用方式。 C语言值传递: 形参是实参的拷贝,改变形参的... -
传递数组参数时最好使用地址传递
2021-03-13 21:33:42在把数组作为参数传递给函数时,有值传递(by value)和地址传递(by reference)两种方式。在值传递方式中,在声明和定义函数时,要在数组参数的尾部加上一对方括号([]),调用函数时只需将数组的地址(即数组名)传递给... -
详解C指针(函数的值传递和地址传递)
2019-05-27 14:26:312、变量名:变量名实际上是一个地址的符号,当程序编译的时候,操作系统会为变量在内存中分配内存空间,所以每一个变量都会有一个实际的内存地址。系统将变量名和内存地址关联起来,这样我们在操作变量名的时候,... -
如何正确实现数组的函数传参(值传递/用指针进行地址传递)(C++实现)
2021-12-03 15:57:25实现一些功能时,我们经常要进行对数组的操作。...(包括一维数组的两种值传递、两种地址传递,二维数组的一种值传递、一种地址传递) 尤其需要注意函数形参的语法格式 指针 * 到底从属于形参的变量类型.. -
什么是 值传递,地址传递和引用传递 有什么区别
2018-08-25 10:10:38什么是值传递,地址传递和引用传递?它们有什么不同?这在学校考试,找工作面试中都是常见的问题。它们之间的区别容易搞错,长时间不用也容易忘记。最近又被问到这个问题,想想还是整理一下记下来,也方便以后参考。... -
函数参数传递三种方式(传值方式,地址传递,引用传递)
2021-06-01 10:45:46函数参数传递三种方式(传值方式,地址传递,引用传递) 形参与实参 形参即形式上的参数,对实参的一种抽象类型描述只是声明一个函数能够接受什么类型的实参,而不确定接受的实参的具体内容是什么 实参即传递给函数... -
从内存角度理解函数值传递与地址传递的区别
2020-09-05 18:48:41对C++初学者来说,对于值传递和地址传递的使用都停留在“用而不懂”的状态,以至于在实际应用经常会发生各种错误,今天我从内存的角度分析一下,希望帮助初学者从根本来理解两者之间的区别,这样才能在学习C++的道路... -
深刻理解形参和实参的三种传递方式(值传递,地址传递,引用传递)
2021-05-29 10:36:34文章目录前言一、值传递二、地址传递三、引用传递总结 前言 在主函数实现了解传递的本质。 提示:以下是本篇文章正文内容,下面案例可供参考 一、值传递 在主函数中 #include <iostream> using namespace ... -
值传递和引用传递(地址传递)的区别
2019-08-07 10:38:05值传递和引用传递(地址传递)的区别 也许大家对于被值传递和引用传递(看了些别人的博客也有人说只有值传递)弄得傻傻分不清楚,我个人之前也是这样过来的,自己也思考了一番,后来才弄清楚了,结合大多数人的想法... -
使用指针变量作为函数参数|地址传递与指针传递实例总结
2021-02-10 16:09:11使用指针变量作为函数参数|地址传递与指针传递实例总结地址传递值传递错误写法1错误写法2 地址传递 指针类型可以作为函数参数的类型,这时视为把变量的地址传入函数。如果在函数中对这个地址的元素进行改变,原先的... -
Golang 中直接赋值,是值传递还是地址传递?
2022-01-29 18:40:31普通变量都是值传递 a := 1 b := a fmt.Printf("%p\n%p", &a, &b) // 0xc0000160a8 // 0xc0000160c0 a := 1.0 b := a fmt.Printf("%p\n%p", &a, &b) // 0xc0000160a8 // 0xc0000160c0 ... -
c语言中结构体的值传递和地址传递的区别
2020-07-05 01:06:46而地址传递,是把变量的地址传入子函数中,子函数中对于参数的改变,是通过传入的地址参数去内存中修改该变量存储的值,所以主函数中的变量值也会同步改变。 下面来演示一下c语言中如何改变结构体中的变量值: #... -
java的参数传递是值传递还是地址传递?
2018-09-17 16:38:46java的参数传递是值传递还是地址传递结论: 1、基本类型作为参数传递时,是传递值的拷贝,无论你怎么改变这个拷贝,原值是不会改变的 2、对象作为参数传递时,是把对象在内存中的地址拷贝了一份传给了参数。 ... -
C语言中的值传递,地址传递与引用传递
2018-12-14 09:27:14在定义函数时函数括号中的变量名是形式参数,简称形参,在主调函数中调用时,该函数中的参数为...1.按值传递 实参a将值拷贝给形参a,形参a此时也在内存中拥有地址,地址= xxxx,值为3,在所有的函数体内的操作,都是... -
【❗划重点!C语言函数参数传递只有两种方式(值传递,地址传递),不支持“引用传递”!❗】
2021-08-31 22:11:13上篇文章《c语言函数传参の结构体数组篇》提到了C语言的函数传参方式,百度了一一一大圈,有说两种的,也有说三种的,简直把我搞晕了,其中有争议的地方就是“引用传递”方式。我看好多写三种方式的都把源代码代码贴... -
浅谈C++值传递、地址传递、引用传递
2018-10-25 17:22:04浅谈C/C++值传递、地址传递、引用传递共同的困惑什么是函数形式参数和实体参数功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个... -
值传递 和 地址传递 的区别(好多句话才可以说清)
2020-02-23 11:34:41要知道什么是**值传递**和**地址传递**,首先要知道什么是**基本数据类型**和**引用类型**。 Java的基本数据类型就八种(除了这八种之外都是引用类型): ◆整型:byte(8位) short(16位) int(32位) long(64位); ... -
结构体的值传递和地址传递
2019-06-28 15:47:51结构体的值传递和地址传递 代码为: #include<stdio.h> #include<string.h> struct Student { int age; char name[50]; int score; }; void chstrStu1(struct Student st1) { st1.age = 20; ...