精华内容
下载资源
问答
  • 实际上引用类型就是指针类型,只不过它用于存放地址的内存空间对使用者而言隐藏的,而且对引用的任何操作都会被重定向到其指向的变量。  一句话,引用一种特殊指针。 参数传递:参数传递时候,必然会发生从...

    第六章 总结

    引用,实际上是C++为了简化指针操作,对指针的操作进行了封装,产生了引用类型。实际上引用类型就是指针类型,只不过它用于存放地址的内存空间对使用者而言是隐藏的,而且对引用的任何操作都会被重定向到其指向的变量。

        一句话,引用是一种特殊指针。

    参数传递:参数传递时候,必然会发生从实参到形参的拷贝。其中:

    ·普通值做参数时,直接拷贝值从实参到栈上作为形参;

    ·指针做参数时,拷贝的是指针变量中的值,也就是其指向的变量的地址;

    ·引用做参数时,拷贝的是其指向的变量的地址;

    ·浮点数做参数时,拷贝其值到栈上,中间采用浮点指令完成;

    ·数组做参数时,拷贝的是数组首地址,也是作地址用;

    ·结构体和类做参数时,若无自定义拷贝构造函数,则依次拷贝对象域内的数据到形参(默认拷贝构造),若有自定义的拷贝构造函数,则调用构造函数在栈上构造形参。

    返回值:

    ·普通值做返回值时,直接用eax返回;

    ·指针做返回值时,用eax返回指针值;

    ·引用做返回值时,用eax返回其指向的变量的地址,同指针;

    ·浮点数做返回值时,将返回值存储到浮点数栈的栈顶,也就是ST0做返回值;

    ·数组做返回值时,用eax返回其数组的首地址,同指针;

    ·结构体和类做返回对象时,

             若无自定义的拷贝构造函数,

    1.对象大小不大于(<=)4字节,直接用eax返回;

                       2.对象大小大于(>)4字节,且不大于(<=)8字节,用eax和edx返回;

    若存在自定义的拷贝构造函数或赋值操作符重载,或者无自定义的拷贝构造函数和赋值操作符重载但对象大小大于(>)8字节时,则隐含传入一个返回对象(可能是临时对象或者接收对象)的地址,在函数内部,对该临时对象的各成员依次赋值(默认拷贝构造),eax返回临时对象的地址。

             当返回对象被用作拷贝构造的参数去构造新对象时,直接把新对象的地址做返回对象;

    当返回对象被用作assignment操作时,需要生成一个临时对象去过渡,该临时对象会被作为返回对象。


    本系列结尾:

    本系列文章中的重要分析部分都在反汇编代码后面的注释上,而且重点的理解也要结合代码调试去完成。

    总之,实践才是检验真理的唯一标准。

    作者署名:cr09philip

    参考文献:钱林松《C++反汇编与逆向分析技术揭秘》


    展开全文
  • 2数组的名字函数参数时,这时函数的形参和实参必须都是数组类型,而且数组名字函数参数时传递的是地址,把数组元素的首地址传递给形参,然后一一对应进行赋值,因此实参数组的元素个数不能少于形参数组的元素个...

    数组可以做函数的参数(形参和实参)。

    1数组的元素做函数参数时,使用和普通类型的数据变量的使用一样。

    2数组的名字做函数参数时,这时函数的形参和实参必须都是数组类型,而且数组名字做函数参数时传递的是地址,把数组元素的首地址传递给形参,然后一一对应进行赋值,因此实参数组的元素个数不能少于形参数组的元素个数。还有一点要注意:形参数组的元素改变的时候,主调函数中的实参数组的元素也会相应的改变。

    以上就是我对于数组做函数参数的一些认识。

    展开全文
  • 因为我们知道,Go语言中结构体值传递,所以要想改变其中成员操作的方法和函数参数,必然要做地址传递。 * ``` package main import "fmt" //实现单链队列,队尾入队,队头出队 //定义队列每个节点属性...
  • 而Java不允许这样,因为Java对普通类型变量不支持引用传递Java的方法传递只有值传递一种,即将实际的参数值的副本传入方法,而参数不受影响 所以我们写一个测试代码来试验一下: package tes...

    Java中的值传递和引用传递

    C和Java使用参数传值是用其实参值来进行初始化形参的值。对于基本变量,C和C++允许显式传递变量的地址(引用传递),在scanf函数中的参数前面的&地址符可以见得。而Java不允许这样做,因为Java对普通类型变量不支持引用传递Java的方法传递只有值传递一种,即将实际的参数值的副本传入方法,而参数不受影响

    所以我们写一个测试代码来试验一下:

    package test;
    class testObj{
        private int m = 1;
        private String s = "测试obj";
        void setM(int m) {
            this.m = m;
        }
        void setS(String s){
            this.s = s;
        }
        String getS(){
            return s;
        }
    }
    public class test {
        private static void inttest(int n){
            System.out.println(n++);
        }
        private static void testobj(testObj n){
            n.setS("testobj");
        }
        private static void teststring(String[] s){
            s[0] = "teststring";
    }
        public static void main(String[] args){
            int n = 0;
            test t = new test();
            testObj to = new testObj();
            to.setS("mainobj");
            to.setM(10);
            String[] str = new String[]{"mainstring"};
            test.inttest(n);
            test.testobj(to);
            test.teststring(str);
            System.out.println(n);
            System.out.println(to.getS());
            System.out.println(str[0]);
        }
    }
    

    可以看到结果是普通的int值传递没有改变,而实例化对象和特殊类型String(数组)都发生了改变。因此可以得出结论:变量进行值传递相当于复制一个副本,当然彼此之间没有关系;而引用传递相当于指向的同一个内存地址,任意一个操作都将影响实际对象。对于String这些特殊的不可操作类要特殊对待作为引用类型操作。
    在这里插入图片描述

    Java中Swap交换函数

    在C/C++里面交换值的方法:

    void swap(int&a ,int&b)
    {
        int temp;
        temp = a;
        a = b;
        b = temp;
    }
    

    而Java中交换:使用C中的引用参数进行的上述交换在Java中不起作用,因为Java没有这些类型的参数。

    通过数组交换

    但是通常应用程序实际上只需要交换数组中的两个值。在这种情况下,可以传递数组和两个索引以交换为三个参数。这种方法用在算法中比较多如冒泡算法。

    private static void swap(int[] Arr,int a, int b){
            int temp = Arr[a];
            Arr[a] = Arr[b];
            Arr[b] = temp;
        }
    public static void main(String[] args){
            int[] Arr = new int[]{1,2,3,4,5};
            int a = 0;
            int b = 1;
            swap(Arr,a,b);
            System.out.println(Arr[0]);
            System.out.println(Arr[1]);
        }
    

    利用类变量传值

    Java对于引用类型的参数传递一样采用了值传递。

        private static void swap(DataWrap dw){
            int temp = dw.a;
            dw.a = dw.b;
            dw.b = temp;
            System.out.println("swap中的顺序: " + " a: " + dw.a + " b: " + dw.b);
        }
    
        public static void main(String[] args){
            DataWrap dw = new DataWrap();
            dw.a = 1;
            dw.b = 2;
            System.out.println("之前的顺序: " + " a: " + dw.a + " b: " + dw.b);
            swap(dw);
            System.out.println("之后的顺序: " + " a: " + dw.a + " b: " + dw.b);
        }
    

    利用包装器类

    static class MyInteger {
        private int x;                   // single data member
        public MyInteger(int xIn) { x = xIn; } // constructor
        public int getValue() { return x; }  // retrieve value
        public void insertValue(int xIn) { x = xIn;} // insert
    }
    
        public static class Swapping {
            // swap: pass references to objects
            static void swap(MyInteger rWrap, MyInteger sWrap) {
                // interchange values inside objects
                int t = rWrap.getValue();
                rWrap.insertValue(sWrap.getValue());
                sWrap.insertValue(t);
            }
    
            public static void main(String[] args) {
                int a = 23, b = 47;
                System.out.println("Before. a:" + a + ", b: " + b);
                MyInteger aWrap = new MyInteger(a);
                MyInteger bWrap = new MyInteger(b);
                swap(aWrap, bWrap);
                a = aWrap.getValue();
                b = bWrap.getValue();
                System.out.println("After.  a:" + a + ", b: " + b);
            }
        }
    
    

    利用外部内联的方式

    class Exchange{ 
    	int i , j; 
    	Exchange(int i, int j){ 
    	this.i = i; 
    	this.j = j; 
    	}
    	public void swap(Exchange exc)
    	{ 
    		int temp = exc.i; 
    		exc.i = exc.j;
    		exc.j = temp; 
    	} 
     }
    public class TestSwap { 
    	static int a = 3; 
    	static int b = 2;
    	public static void main(String[] args){ 
    		Exchange exc = new Exchange(a,b); 
    		System.out.println("before swap "+"a的值="+a+" b的值="+b); 
    		exc.swap(exc); 
    		a=exc.i;
    		b=exc.j;
    		System.out.println("after swap "+"a的值="+a+" b的值="+b);
    	} 
    } 
    
    
    
    展开全文
  • 2. 引用做参数传递是变量地址; 实质上传递是变量的指针; 引用作为参数的好处减少了临时变量对内存的开销,因此常用于对大对象的操作; 而常引用做参数就是保护参数不被修改; 附:堆和栈的知识一个由c/C++...
  • 引用参数和传值参数的区别

    千次阅读 2012-08-16 11:12:05
    1. 我们都知道,普通的传值参数是由行参传给实参; 编译器在函数内部为每一个参数产生一个临时变量,将每一个参数压入栈(stack)中,将实参的数值...2. 引用做参数传递的是变量地址; 实质上传递的是变量的指针;

    1. 我们都知道,普通的传值参数是由行参传给实参;

    编译器在函数内部为每一个参数产生一个临时变量,将每一个参数压入栈(stack)中,将实参的数值保存到临时变量中。

    所以才有在低端8位机中,对参数的数量有比较严格的限制,因为栈的深度非常有限;当然,在通用机上也有同样的问题,参数过多不合适,但通用机的栈的深度比低端机大多了;

    2. 引用做参数传递的是变量的地址;

    实质上传递的是变量的指针;

    引用作为参数的好处是减少了临时变量对内存的开销,因此常用于对大对象的操作;

    而常引用做参数就是保护参数不被修改;


    附:堆和栈的知识

    一个由c/C++编译的程序占用的内存分为以下几个部分

    1、栈区(stack)―   由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。

    2、堆区(heap) ―   一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵呵。

    3、全局区(静态区)(static)―,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。 - 程序结束后有系统释放

    4、文字常量区  ―常量字符串就是放在这里的。 程序结束后由系统释放

    5、程序代码区―存放函数体的二进制代码。


    展开全文
  • 普通变量作为函数形参 (1)形参额外申请内存,实参传过来的值,函数执行结束之后,形参的内存会自动释放。 数组作为函数形参 (1)函数名作为形参传参时,实际传递不是整个数组,而是数组的首元素的首地址,所以在子...
  • 关于指针的各类事项

    2020-07-11 00:00:20
    指针 “ &...指正做参数时可以通过指针访问更改其变量地址传递)。 “ * ” 操作符 “ * ”一个单目运算符,用来访问指针的值所表示的地址上变量,可以做右值也可以做左值。 int k = *p; *p =
  • c语言函数传参详解

    2017-10-22 12:50:00
    24.1.普通变量作为函数形参 (1)普通变量作为参数在函数传参时,形参和实参名字可以相同也可以不同,实际上都用实参来替代相应的形参的。 (2)在字函数内部,形参的值等于实参。原因函数调用时把实参的值赋值给了...
  • C与指针

    2018-04-09 14:46:54
    #endif数组作为参数的时候传递数组首地址,也就是实参和形参共享一个地址,数组的下标量做参数时,情况和普通变量一样,这个时候形参和实参各自有各自的内存空间,互不干扰。C中只有4种基本类型,整型,浮点,...
  • 分析吃药CALL的时候发现参数是一个结构,从物品指针+14C传递过来,通过这个物品指针我们找到了背包结构,分析发现+8是物品横坐标+C是物品纵坐标,+4是物品的ID,我们又发现更改物品的ID会导致鼠标放在物品上显示信息的...
  • C++ 对象内存布局及其大小

    千次阅读 2009-10-24 08:51:00
    (1)空类的大小为1字节,这一个占位符。(2)普通成员函数,静态成员函数,及静态成员变量皆不会影响对象的大小。普通成员函数,静态成员函数,及静态成员...为第一个参数传递普通成员函数,以此来进行关联。
  • 易语言 茶凉专用模块

    2010-05-04 12:26:36
    参数 临时透明度, 字节型, 可空, 设置整个窗口的透明度 取值范围[0,255] 可空为不设定此参数 .参数 临时透明色, 整数型, 可空, (#颜色)指定某颜色为完全透明(完全透明处不属于该窗口) 可空为不指定 .参数 鼠标穿透...
  • javascript入门笔记

    2018-05-15 15:01:07
    Javascript Basic 1、Javascript 概述(了解) ... 调用函数时,所传递参数列表,称之为"实参(实际参数)" 3、练习 1、定义一个函数 change ,该函数中接收两个参数(a,b) 2、在函数体中,如果 a 大于 b的话...
  • 零起点学通C++多媒体范例教学代码

    热门讨论 2010-11-30 09:35:13
    8.1 什么是地址 8.2 用指针来保存地址 8.2.1 空指针 8.2.2 指针与变量类型 8.2.3 用指针来访问值 8.2.4 指针地址、指针保存的地址和 该地址的值 8.2.5 指针对数值的操作 8.2.6 更换指针保存的地址 8.3 为什么使用...
  • 8.1 什么是地址 8.2 用指针来保存地址 8.2.1 空指针 8.2.2 指针与变量类型 8.2.3 用指针来访问值 8.2.4 指针地址、指针保存的地址和 该地址的值 8.2.5 指针对数值的操作 8.2.6 更换指针保存的地址 8.3 为...
  • 8.1 什么是地址 91 8.2 用指针来保存地址 92 8.2.1 空指针 92 8.2.2 指针与变量类型 93 8.2.3 用指针来访问值 93 8.2.4 指针地址、指针保存的地址和该地址的值 94 8.2.5 指针对数值的操作 95 8.2.6 更换指针...
  • Excel_VBA程序设计.pdf

    热门讨论 2009-08-31 23:05:20
    8.按地址和按值传递参数 104 9.使用可选的参数 105 10.定位内置函数 106 11.使用MsgBox函数 107 12.MsgBox函数的运行值 111 13.使用InputBox函数 111 14.数据类型转变 113 15.使用InputBox方法 114 16.使用主过程和...
  • Excel VBA程序设计.doc

    2009-07-06 22:16:12
    8.按地址和按值传递参数 104 9.使用可选的参数 105 10.定位内置函数 106 11.使用MsgBox函数 107 12.MsgBox函数的运行值 111 13.使用InputBox函数 111 14.数据类型转变 113 15.使用InputBox方法 114 16.使用主过程和...
  • 8.按地址和按值传递参数 92 9.使用可选的参数 93 10.定位内置函数 94 11.使用MsgBox函数 95 12.MsgBox函数的运行值 98 13.使用InputBox函数 99 14.数据类型转变 100 15.使用InputBox方法 101 16.使用主过程和子过程 ...
  • 9.4 在把数组作为参数传递给函数时,可以通过sizeof运算符告诉函数数组的大小吗? 9.5 通过指针或带下标的数组名都可以访问数组中的元素,哪一种方式更好呢? 9.6 可以把另外一个地址赋给一个数组名吗? 9.7 ...
  • C语言编程要点

    2017-09-18 00:10:37
    9.4. 在把数组作为参数传递给函数时,可以通过sizeof运算符告诉函数数组的大小吗? 140 9.5. 通过指针或带下标的数组名都可以访问数组中的元素,哪一种方式更好呢? 141 9.6. 可以把另外一个地址赋给一个数组名吗? 143...
  • 新手学习C++入门资料

    2008-12-28 23:58:50
    主体:(一)与C语言的区别> ...而且C++允许重复定义变量,C语言也是做不到这一点的。看下面的程序: #include iostream.h int a; int main() { cin>>a; for(int i=1;i;i++) //C语言中,不允许在这里定义变量...
  • Excel_VBA教程

    2014-09-22 11:36:34
    8.按地址和按值传递参数 97 9.使用可选的参数 97 10.定位内置函数 98 11.使用MSGBOX函数 99 12.MSGBOX函数的运行值 103 13.使用INPUTBOX函数 104 14.数据类型转变 105 15.使用INPUTBOX方法 106 16.使用主过程和子...
  • ExcelVBA程序设计.doc

    2011-04-05 21:32:51
    8.按地址和按值传递参数 97 9.使用可选的参数 97 10.定位内置函数 98 11.使用MSGBOX函数 99 12.MSGBOX函数的运行值 103 13.使用INPUTBOX函数 104 14.数据类型转变 105 15.使用INPUTBOX方法 106 16.使用主过程和子...
  • php高级开发教程说明

    2008-11-27 11:39:22
    选择变量名可能程序员最常、但却想得最少的。如果你已建立了这些在大项目中出现 的变量名字、类型、定义位置的清单,那么你就创建了一个类似于小电话簿的东西,你想让你 的清单成为什么样子呢?不同的命名方案已...
  • 7.6.1 超车方法:使用类实例做参数 172 7.6.2 调用这个方法 173 7.6.3 发生了什么 174 7.7 加餐:局部变量和实例变量 175 7.7.1 什么局部变量(Local Variable) 175 7.7.2 什么实例变量(Instance ...
  • 7.6.1 超车方法:使用类实例做参数 172 7.6.2 调用这个方法 173 7.6.3 发生了什么 174 7.7 加餐:局部变量和实例变量 175 7.7.1 什么局部变量(Local Variable) 175 7.7.2 什么实例变量(Instance ...

空空如也

空空如也

1 2 3 4
收藏数 74
精华内容 29
关键字:

普通变量做参数是地址传递