zoukankan      html  css  js  c++  java
  • C# 形参 实参 调用时在托管栈和托管堆中的分配情况

    每每看到别人写的文章,总觉得冗长,不够简练,作为1个开发我们要力求简洁明了,当然人非圣贤孰能无过,我写的也不是尽善尽美,我尽我所能保证每一句随笔的正确性,期间我会参考很多来源的资料,当然也会在文章最后列出原博客地址,如果你觉得我写的不够清楚,那么你可以参考这些地址做详细阅读。

    作者本身也是很愿意和大家一起交流技术,如果你看了我的文章中间有不同的论断和见解,那么你可以在下方留言,作者看到留言都会回复,一起探讨.NET技术。

    以下内容来源于网络加自己的认同的理解,和自己认为一些重要的东西。

    CLR数据类型: 值类型(Value Type)和引用类型(Reference Type)

    值类型:int、char、float、long、bool、double、structenum、short、byte、decimal、sbyte、uint、ulong、ushort等

    引用类型:stringclass、interface、delegate、object等

    对于如下代码:

    int myAge = 19;

    Student myStu = new Student("唐马儒", 20);

    public void test(int age, Student stu);

    test(myAge, myStu);

    函数定义了形参,当真正调用函数的时候,传递的参数就是实参。

    对于基本值类型,默认情况下是传递值的拷贝,在栈中会开辟一块内存,拷贝myAge的值到为栈中名称为age的地址中去,对于Student类的实例,内存只需要在栈中创建了1个指针。放在名称为stu的地址空间中,指向heap中的学生对象,栈中名称为myStu内的Pointer也指向heap中的学生对象。

    思考:1. 如果形参和实参的名称相同,那么在栈中重新开辟内存空间的时候,新空间的名称叫什么?

    但是C#提供了ref和out修饰符来修饰函数参数,如果遇到了这2种情况(ref一般是加在值类型前面,因为加在引用类型前面没有意义),调用函数就不会再栈中重新开辟一块内存来存放age这个值,而是把myAge的地址传递给调用内部,这样在调用内部对变量的修改就会反映到外部代码,这个过程中没有装箱(boxing)和拆箱(unboxing)。

    附加1个知识点:

    1. C#对于引用类型实例对象的值类型成员与对象一起存放在heap中

    2. 对于值类型(比如结构体)中的引用类型的创建的对象是保存在heap中,stack中仅保留这个对象成员的引用(也叫指针 Pointer)

    C#有1条黄金规则:

    1. 所有引用类型都是放在heap中

    2. 值类型和指针总是放在它们被声明的地方

    参考资料:

    1. 百度知道-C#中的引用类型和值类型有哪些

    2. C#中的ref, out, params修饰符+引用类型和值类型说明

    3. 图解C#中的实参和形参是怎么分配内存的

    4. AnyTao-你必须知道的.NET之内存剖析

    5. 栈,堆,静态区,常量区的内存分配图解

    6. IL代码怎么看懂

  • 相关阅读:
    第六周进度条
    团队开发需求分析视频连接
    敏捷开发综述
    数组2--数组首尾相接,求最大子数组
    数组1--求一个数的最大子数组
    第四周进度条
    四则运算3
    第三周进度条
    第二周进度条
    单元测试
  • 原文地址:https://www.cnblogs.com/learnmoredaybyday/p/3647862.html
Copyright © 2011-2022 走看看