C#(一)——堆和栈

本文详细解读了C#中栈与堆的概念及其在内存管理中的作用,包括操作系统与数据结构中的栈定义,数据结构与操作系统中的堆区别,以及C#中栈与堆存储数据的具体方式,并通过代码示例展示了引用类型和基本类型在栈与堆中的存储差异。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

             学习到C#的时候估计大家都遇到过这两个词语:栈和堆,下面就它们来讨论一下。

数据结构和操作系统中的栈

       我们首先要知道的是,计算机中的栈和数据结构中的栈是不同的。那么有什么不同呢?

先看一下操作系统中栈的定义:计算机操作系统中的栈是指一块内存区域,该区域的管理(内存空间的分配与回收)采用类似数据结构中的“栈”的特点进行操作。操作系统中的栈是物理存在的。

那么在数据结构中栈的定义是什么呢?栈是允许在同一端进行插入和删除操作的特殊线性表.允许进行插入和删除操作的一端称为栈顶(top),另一端为栈底(bottom);栈底固定,而栈顶浮动;栈中元素个数为零时称为空栈.插入一般称为进栈(PUSH),删除则称为退栈(POP)。栈也称为后进先出表。数据结构中的“栈”是一个概念,是逻辑存在的。

 

但是由于操作系统中的栈是由数据结构中的栈引申定义的,所以其具有很相似的性质:无论哪一种栈,都遵循“后进先出”的特点。

数据结构和操作系统中的堆

然后我们再来看一下堆。

 数据结构中的堆:堆是一种特殊的树形数据结构,每个结点都有一个值,通常我们所说的堆的数据结构,是指二叉堆。堆的特点是根结点的值最小(或最大),且根结点的两个子树也是一个堆。

 数据结构中的堆,要了解的话推荐一本书:严蔚敏的数据结构。

 操作系统中的堆:堆是属于内存分配方式的一种:动态分配内存。实现的方式更接近于链表。堆内存中有很多块内存,可能不是连续的。所有需要用链表来组织。在分配的时候,有多种策略。首先查找是否有空闲的并且满足大小的堆内存,然后把最大的那块给需求者。

 最后为大家展示一下在C#中栈和堆是如果存储数据的。

首先说栈中的数据,包括结构体(数值类型,Bool类型,用户定义的结构体),枚举,可空类型。例如定义一个int类型的变量i:

int i=5

它在栈中是直接存放的。如图:


然后定义一个string类型的变量s:

string s="a string"

它在堆中的存储情况为:在堆中存放变量名“s”,并且指向栈中的“a string”。如图:

代码示范

堆和栈的存储方式大家了解了,就可以很好的解释这样一个问题,例如:

<span style="font-size:18px;">using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            ReferenceAndValue.Demonstration();
            Console.ReadLine();
        }
    }
    public class stamp
    {
        public string Name { get; set; }
        public int Age { get; set; }
    }
    public static class ReferenceAndValue
    {
        public static void Demonstration()
        {
            stamp Stamp_1=new stamp {Name ="Premiere",Age =25};
            stamp Stamp_2=new stamp {Name ="Again",Age =47};
            int age=Stamp_1 .Age ;
            Stamp_1.Age = 22;
            stamp guru=Stamp_2 ;
            Stamp_2 .Name ="Again Amend";
            Console .WriteLine ("Stamp_1's age:{0}",Stamp_1 .Age );
            Console .WriteLine ("age's value:{0}",age );
            Console .WriteLine ("Stamp_2's name:{0}",Stamp_2 .Name );
            Console .WriteLine ("guru's name:{0}",guru.Name );
        }
    }
}</span>

  

stamp实例化stamp_1之后在栈里面创建一个Age存储空间,存放25,而之后在声明age变量时又在栈中开辟另外一空间存放22,两者时互不影响的。而引用类型在声明guru之后把stamp_2赋值给它,其实就是把Stamp_2中存放的地址给了guru,因此他们指向同一区域,所以值时一样的。堆中存放的其实类似指针,是一个地址,指向被调用的值。

通过自己原有的知识来理解现在的堆和栈感觉要比书上说的一大段文字更加的深刻,这就是编织知识网带给我们的好处,当然我的理解还加入了专业课上栈和堆的一些内容,而不同人则可以用自己原有的生活阅历或者专业知识来参考着理解现有的知识这样我们的学习将会越来越轻松。

评论 19
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值