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

1、首先了解一下堆栈帧的创建步骤(来自《32位汇编语言程序设计》钱晓捷一书):

1)主程序把传递的参数压入堆栈;

2)调用子程序时,返回地址压入堆栈;

3)子程序中,EBP压入堆栈;设置EBP等于ESP,通过EBP访问参数和局部变量;

4)子程序有局部变量,ESP减去一个数值,在堆栈预留局部变量使用的空间;

5)子程序要保护的寄存器压入堆栈。

如下图:

2、了解了堆栈帧之后,就可以得出以下程序:

1)嵌入汇编实现

#include<iostream>
using namespace std;

void fun(int val=0)
{
	val=1005;

	//----------------
	__asm
	{
		lea eax,val
		mov ebx,[eax-8]
		mov eax,val
		mov [ebx-4],eax
	}
}

int main()
{
	int a=0;

	fun();
	cout<<a<<endl;
	return 0;
}

2)

#include<iostream>
using namespace std;

void fun(int val=0)
{
	*((int*)(*(&val-2))-1)=1005;
}

int main()
{
	int a=0;

	fun();
	cout<<a<<endl;
	return 0;
}
时间: 2024-11-05 12:24:31

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

通过指针形参修改实参的值1

注意:图示使用的地址只是假设的,并不是真正的内存地址,只是说明原理 先说说修改基本类型变量的值,比如说int类型,可以直接修改,也可以通过函数修改,看下代码 #include <stdio.h> void change(int *a) { int temp = 555; a = &temp; } int main() { int i = 5; int j = 55; int *p = &i; i = 10;//第一种修改方法 printf("%d\n", i

通过指针形参修改实参的值2

注意:图示使用的地址只是假设的,并不是真正的内存地址,只是说明原理 上次说到的是修改基本类型的变量,这次来说修改指针变量的值 #include <stdio.h> void change(int *a) { int temp = 555; a = &temp; } int main() { int i = 5; int *p = &i; printf("%p\n", p); change(p);//并没有修改成功p的值 printf("%p\n&q

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

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

C#形参,实参,值传递参数,引用传递参数,输出参数,参数数组的学习

1)形参 形参顾名思义就是形式上的参数,不是实际的参数,它代替实际传入方法的值.在方法体代码中代表了值本身参与运算.形参定义于参数中,它不同于方法体内局部变量,因为是一个变量,在它的作用域内不允许存在一个同名的局部变量,不管他们的类型是否相同,都是不允许出现同名的. 看下面的代码示例: 1 //这其中的strName就是一个形参也是一个变量,不允许出现同名的局部变量 2 public void SayHelloTo(string strName) 3 { 4 Console.WriteLine(

c/c++不能返回局部对象和局部变量的指针或引用解释

在编写c/c++代码时,调用函数的书写让程序变得整洁易读,但是调用函数的返回值(局部变量的返回值,变量,结构体,数组等)也有注意事项.c/c++严禁返回局部变量的指针或引用. 其实函数的返回值的规则非常好记: 函数的返回值可以是数值和全局变量的指针或引用. 函数的返回值不能是局部对象或者是局部变量的指针或引用!!! 原因: 调用函数的局部变量是存在于栈中的,在执行完调用函数之后会将局部变量的空间释放,也就是调用函数执行后局部变量将不存在与内存中.如果返回的是局部变量的指针或者是引用.返回给接收对

深入理解指针和引用的区别及引用与原值的区别

用法上的基本区别(包括sizeof和typeid)就不多说了,相信大家都了然于心,不清楚随便google一下也有一大堆. 下面从对象模型的角度去深入的谈谈指针和引用的区别,亦我们有了指针,为什么还要用引用. 1) 形式 这里所说的形式指的是运算符重载时的形式一致,事实上,在c++中,只有运算符有形式上确定的规定,因此,在重载[]运算符时,为了保持形式的一致性,就必须使用引用. 2) 临时变量 可以用const A&来引用一个临时变量(这同时证明了临时变量是有地址的,只不过该地址不能通过&取

浅谈指针和引用

我们知道用指针和引用来定义函数形参的时候,都可以直接改变参的值.那么指针和引用有哪些区别呢? 我们先根据引用和指针的定义展开:引用是某个变量或者对象的别名,而指针则存储的是一个机器码地址,这个地址是某个具体变量或者对象的地址.因此区别有: 1)指针可以为空,但是引用不行 2)声明指针可以不指向任何对象,因此使用指针之前必须做判空操作,而引用则不必 3)引用一旦声明后,就不可以改变指向:但是指针可以,如++操作符,指针则指向下一个对象,而引用则改变的是指向对象的内容 4)引用的大小是所指变量的大小

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

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

参数传递:传值参数,指针形参,传引用参数,const形参和实参,数组形参,main:处理命令行选项,含有可变形参的函数

重点: 1.每次调用函数时都会重新创建它的形参,并用传入的实参对形参进行初始化. NOTE: 形参初始化的机理与变量初始化一样. 2.形参的类型决定了形参和实参交互的方式. (引用->绑定,非引用->拷贝) 3.实参分为:被引用传递(引用形参是实参的别名),被值传递(实参形参是两个相互独立的对象). 4.传值参数:函数对形参做的所有操作都不会影响实参. 5.指针形参:指针的行为和其他非引用类型一样,当执行指针拷贝操作时,拷贝的是指针的值.拷贝后,两个指针是不同的指针. NOTE: C程序员常常