C#中栈和堆怎么定义

看了好多概念性的东西还是不懂,求帮忙,说的通俗易懂点
2024-11-25 06:25:12
推荐回答(3个)
回答(1):

栈当中存放的是值类型,如int,decimal,double,enum等

堆当中存放的是引用类型,如string,类等

如图,如果定义一个int类型的变量i:

int i = 5;

那么在内存中的实际情况是:直接在栈中存放i的值5.

如果顶一个string类型的变量s:

string s = "A string.";

那么在内存中的实际情况是:在堆中存放s的变量名(即地址),在栈中存放s的值"A string.",然后让堆中的变量名s(即地址)指向栈中的值,这也是为什么,保存在堆中的变量被称为引用类型,因为当你访问一个引用类型的变量时,首先是访问它的地址,然后通过引用才能访问到该变量的值。

回答(2):

1、堆(heap):
定义:内存中存储的是固定长度的数据区域。

堆是从下往上分配,所以已用的空间在自由空间下面,C#中所有引用类型的对象分配在托管堆上,托管堆在内存上是连续分配的,并且内存对象的释放受垃圾收集机制的管理,效率相对于栈来说要低的多。

2、栈(stack):
定义:内存中存储的是可变长度的数据区域。

栈是自上向下进行填充,即由高内存地址指向低内存地址,并且内存分配是连续的,C#中所有的值类型和引用类型的引用都分配在栈上,栈根据后进先出的原则,依次对分配和释放内存对象。
3、相关说明:
1)栈区(stack)—由编译器自动分配释放,存放函数的参数值,局部变量的值等。其
操作方式类似于数据结构中的栈。
2)堆区(heap) —一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表。

回答(3):

首先请参考数据结构  知道栈和堆是什么 以及干啥用的...

.net框架已经内置堆栈数据结构 通常情况下我们使用System.Collections.Generic命名空间下的泛型结构

下面是一段演示代码

Queue q = new Queue();
q.Enqueue(1);
q.Enqueue(2);
while (q.Count>0) Console.WriteLine(q.Dequeue());

Stack s = new Stack();
s.Push(1);
s.Push(2);
while (s.Count>0) Console.WriteLine(s.Pop());


如果要求你自己定义的话  数据结构可知 栈和堆都是线性结构 实际上可以理解为限制了读取写入方式线性表

所以如果无视效率的话 你可以在List的基础上进行改造 以实现堆栈的定义

无非就是先进先出 后进先出而已

class MyQueue
{
private List list = new List();
public int Count
{
get{ return this.list.Count; }
}
public void Enqueue(T item)
{
list.Add(item); //放到最后一个
}
public T Dequeue()
{
T item = list[0]; //每次都取第一个
list.RemoveAt(0); //然后移位 就像站排一样 前面的走了后面跟上
return item;
}
}

class MyStack
{
private List list = new List();
public int Count
{
get{ return this.list.Count; }
}
public void Push(T item)
{
list.Add(item); //还是放到最后一个
}
public T Pop()
{
T item = list[list.Count-1]; //每次都取最后一个
list.RemoveAt(list.Count-1); //然后直接移除它 所以实现了后进先出
return item;
}
}

然后测试  结果应该和上面用内置的堆栈实现效果一致

MyQueue q = new MyQueue();
q.Enqueue(1);
q.Enqueue(2);
while (q.Count>0) Console.WriteLine(q.Dequeue());
MyStack s = new MyStack();
s.Push(1);
s.Push(2);
while (s.Count>0) Console.WriteLine(s.Pop());

当然这只是最简单版本的实现

想合理提高效率的话 需要构造循环队列 使dequeue操作复杂度降低到O(1) (上面实现为O(n))

想适应并发和线程安全的话 需要改造成链表来实现