C语言-传值,传地址(指针),传引用区别和联系

很多编程老手对传值,传地址,传引用的区别搞的也不会很清楚,今天我就花一点时间再次介绍一下这些概念的本质。

其实,不用分为三类,只有两类即可。传值和传引用。为什么会出现传地址(即传指针)呢?本质就是大家一致对传值和传地址概念的理解错误导致,也是对指针的概念的理解错误导致。

指针:(简单补充一下)其实很简单,指针就是一个变量,如果非要说是一个特殊的变量也不为过,因为指针的初始化和解引用等不同的操作方式而已。就内存的分布来说,指针和一个变量在内存中存放是没有任何区别的,无非指针存放的是变量的地址,就是这么简单。

定义:

传值:可能很多人都听说,传值无非就是实参拷贝传递给形参。这句话没有错,但是理解起来还是有点抽象。一句话,传值就是把实参赋值给形参,赋值完毕后实参就和形参没有任何联系,对形参的修改就不会影响到实参。

传地址:为什么说传地址也是一种传值呢?因为传地址是把实参地址的拷贝传递给形参。还是一句话,传地址就是把实参的地址复制给形参。复制完毕后实参的地址和形参的地址没有任何联系,对实参形参地址的修改不会影响到实参, 但是对形参地址所指向对象的修改却直接反应在实参中,因为形参指向的对象就是形参的对象。

传引用:传引用本质没有任何实参的拷贝,一句话,就是让另外一个变量也执行该实参。就是两个变量指向同一个对象。这是对形参的修改,必然反映到实参上。

区别:

(1):传递引用给函数与传递指针的效果是一样的。这时,被调函数的形参就成为原来主调函数中的实参变量或对象的一个别名来使用,所以在被调函数中对形参变量的操作就是对其相应的目标对象(在主调函数中)的操作。

(2):使用引用传递函数的参数,在内存中并没有产生实参的副本,它是直接对实参操作;而使用一般变量传递函数的参数,当发生函数调用时,需要给形参分配存储单元,形参变量是实参变量的副本;如果传递的是对象,还将调用拷贝构造函数。因此,当参数传递的数据较大时,用引用比用一般变量传递参数的效率和所占空间都好。

(3):使用指针作为函数的参数虽然也能达到与使用引用的效果,但是,在被调函数中同样要给形参分配存储单元,且需要重复使用"*指针变量名"的形式进行运算,这很容易产生错误且程序的阅读性较差;另一方面,在主调函数的调用点处,必须用变量的地址作为实参。而引用更容易使用,更清晰。

本质: 传值和传指针都是传值方式,除了传引用之外

时间: 2024-10-28 16:21:38

C语言-传值,传地址(指针),传引用区别和联系的相关文章

C语言结构体,C语言结构体指针,java对象引用,传值,传地址,传引用

C语言结构体,C语言结构体指针,java对象引用,传值,传地址,传引用 传值 把实参的值赋值给行参 那么对行参的修改,不会影响实参的值 传地址 传值的一种特殊方式,只是他传递的是地址,不是普通的如int 那么传地址以后,实参和行参都指向同一个对象 传引用 真正的以地址的方式传递参数 传递以后,行参和实参都是同一个对象,只是他们名字不同而已 对行参的修改将影响实参的值 所谓变量是内存地址的一个抽象名字,在静态编译的程序中,所有变量名都会在编译时转换成内存地址,机器不知道变量名,只知道地址. C 语

引用传参与指针传参的区别

Reference: https://blog.csdn.net/u013130743/article/details/80806179 概念: 引用传参:引用是变量的别名.引用传参传递进形参列表的是实参的别名,在函数的执行中也会在栈空间上开辟存储空间,存储形参的地址 (也就是实参的地址).对形参的任何操作都会间接寻址到实参.也就是在函数中对形参变量做的任何改变都会影响到实参变量. 指针传参:指针传参本质上是值传参.指针在形参列表中传递的是实参的地址.也就是说,指针的值的实参的地址.在函数的执行

不通过传值传指针传引用而实现形参修改实参的值

1.首先了解一下堆栈帧的创建步骤(来自<32位汇编语言程序设计>钱晓捷一书): 1)主程序把传递的参数压入堆栈: 2)调用子程序时,返回地址压入堆栈: 3)子程序中,EBP压入堆栈:设置EBP等于ESP,通过EBP访问参数和局部变量: 4)子程序有局部变量,ESP减去一个数值,在堆栈预留局部变量使用的空间: 5)子程序要保护的寄存器压入堆栈. 如下图: 2.了解了堆栈帧之后,就可以得出以下程序: 1)嵌入汇编实现 #include<iostream> using namespace

C/C++中传值和传地址(引用)

C/C++中参数传递有两种方式,传值或传地址(传引用),通常我们要在被调用函数中改变一个变量的值就需要传地址调用方式,例如: void swap_by_value(int a, int b) { int temp; temp = a; a = b; b = temp; } void swap_by_ptr(int* pa, int* pb) { int temp; temp = *pa; *pa = *pb; *pb = temp; } int main(int argc, char* argv

go语言---传值和传引用

go语言---传值和传引用 https://blog.csdn.net/cyk2396/article/details/78893828 1.定义: b = a; b.modify(); 如果b的修改不会改变a的值,那么是传值:否则,是传引用 2.golang中大多数是传值的,有: 基本类型:byte,int,bool,string 复合类型:数组,数组切片,结构体,map,channnel 3.数组: 3.1 传值 func main() { var array = [3]int{0, 1,

C语言:传值,传地址

形参:形式参数实参:实际参数 传值: 把实参的值复制给形参, 修改函数内的形参,不会影响实参. 传地址: 指针传值,形参为指向实参地址的指针 当对形参的指向操作时,相当于对实参本身进行的操作 #include <iostream> // 交换位置 // “值调用” void swap_value(int x, int y) { int temp = x; x = y; y = temp; } // “引用调用1”,形参:传的是地址,取得是值(*) void swap_p(int *x, int

PHP传值和传引用、传地址的区别

传值,   是把实参的值赋值给行参   那么对行参的修改,不会影响实参的值 传地址   是传值的一种特殊方式,只是他传递的是地址,不是普通的如int   那么传地址以后,实参和行参都指向同一个对象 传引用   真正的以地址的方式传递参数   传递以后,行参和实参都是同一个对象,只是他们名字不同而已   对行参的修改将影响实参的值 仅讨论一下值传递和引用:   所谓值传递,就是说仅将对象的值传递给目标对象,就相当于copy:系统将为目标对象重新开辟一个完全相同的内存空间.   所谓引用,就是说将对

Go语言的传参和传引用[转]

目录[-] 传参和传引用的问题 传slice不是传引用! 什么叫传引用? 为什么传slice不是传引用? 为什么很多人误以为slice是传引用呢? 传指针和传引用是等价的吗? 所有类型的函数参数都是传值的! 那Go语言有传引用的说法吗? 什么是引用类型, 和指针有何区别/联系 ? 总结 传参和传引用的问题 很多非官方的文档和教材(包括一些已经出版的图书), 对Go语言的传参和引用的讲解 都有很多问题. 导致众多Go语言新手对Go的函数参数传参有很多误解. 而传参和传引用是编程语言的根本问题, 如

函数参数的传值和传指针有什么区别?

前言 我们可能听过C语言中的传值和传指针,在其他语言中,也有传引用一说,那么他们到底有什么区别呢?如果你还不能准确地分辨,就该好好了解一下了. 传值 我们在初学C语言的时候就被老师教过,下面的方式是无法交换a和b的值的: #include<stdio.h> void swap(int a,int b) { int temp = a; a = b; b = temp; printf("swap a = %d,b = %d\n",a,b); } int main(void) {