A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 申延超 于 2012-11-2 23:40 编辑

类和结构有什么区别?堆和栈分别是啥?

评分

参与人数 1技术分 +1 收起 理由
宋天琪 + 1

查看全部评分

5 个回复

正序浏览
结构是值类型:值类型在堆栈上分配地址,所有的基类型都是结构类型,例如:int 对应System.int32 结构,string 对应 system.string 结构 ,通过使用结构可以创建更多的值类型

类是引用类型:引用类型在堆上分配地址

堆栈的执行效率要比堆的执行效率高,可是堆栈的资源有限,不适合处理大的逻辑复杂的对象。所以结构处理作为基类型对待的小对象,而类处理某个商业逻辑

因为结构是值类型所以结构之间的赋值可以创建新的结构,而类是引用类型,类之间的赋值只是复制引用

回复 使用道具 举报

栈(stack)是一种特殊的线性表。如洗碗,在通常情况下,最先冼净的碗总是放在最底下,后冼净的碗总是摞在最顶上。而在使用时,却是从顶上拿取,也就是说,后冼的先取用,后摞上的先取用。好比我们把冼净的碗“摞上”称为进栈,把“取用碗”称为出栈,那么,上例的特点是:后进栈的先出栈。然而,摞起来的碗实际上是一个表,只不过“进栈”和“出栈”,或者说,元素的插入和删除是在表的一端进行而已。
队列(Queue)也是线性表的一种特殊情况,但它与栈不同,其所有的插入均限定在表的一端进行,而所有

的删除则限定在表的另一端进行。允许插入的一端称队尾(Rear),允许删除的一端称队头(Front)。队列

的结构特点是先进队的元素先出队。假设有队列Q=(a1, a2,a3,…,an),则队列Q中的元素是按a1,

a2,a3,…,an的次序进队,而第一个出队的应该是a1,第二个出队的应该是 a2,只有在ai-1出队以后

,ai才可以出队(1≤i≤n)。因此,通常又把队列叫做先进先出(FIFI—First In First Out)表。再

一句话总结:
栈(数据结构):后进先出
队列:先进先出
回复 使用道具 举报
吴愿涛 发表于 2012-11-2 07:23
类和结构的区别:
类:
类是引用类型在堆上分配,类的实例进行赋值只是复制了引用,都指向同一段实际对象分 ...

总结的不错
回复 使用道具 举报
本帖最后由 吴愿涛 于 2012-11-2 07:29 编辑

类和结构的区别:
类:
类是引用类型在堆上分配,类的实例进行赋值只是复制了引用,都指向同一段实际对象分配的内存
类有构造和析构函数
类可以继承和被继承
结构:
结构是值类型在栈上分配(虽然栈的访问速度比较堆要快,但栈的资源有限放),结构的赋值将分配产生一个新的对象。
结构没有构造函数,但可以添加。结构没有析构函数
结构不可以继承自另一个结构或被继承,但和类一样可以继承自接口
示例:
根据以上比较,我们可以得出一些轻量级的对象最好使用结构,但数据量大或有复杂处理逻辑对象最好使用类。
如:Geoemtry(GIS 里的一个概论,在 OGC 标准里有定义) 最好使用类,而 Geometry 中点的成员最好使用结构
using System;
using System.Collections.Generic;
using System.Text;
namespace Example16
{
    interface IPoint
     {
        double X
         {
             get;
             set;
         }
        double Y
         {
             get;
             set;
         }
        double Z
         {
             get;
             set;
         }
     }
    //结构也可以从接口继承
    struct Point: IPoint
     {
        private double x, y, z;
        //结构也可以增加构造函数
        public Point(double X, double Y, double Z)
         {
            this.x = X;
            this.y = Y;
            this.z = Z;
         }
        public double X
         {
             get { return x; }
             set { x = value; }
         }
        public double Y
         {
             get { return x; }
             set { x = value; }
         }
        public double Z
         {
             get { return x; }
             set { x = value; }
         }
     }
    //在此简化了点状Geometry的设计,实际产品中还包含Project(坐标变换)等复杂操作
    class PointGeometry
     {
        private Point value;
        
        public PointGeometry(double X, double Y, double Z)
         {
            value = new Point(X, Y, Z);
         }
        public PointGeometry(Point value)
         {
            //结构的赋值将分配新的内存
            this.value = value;
         }
        public double X
         {
             get { return value.X; }
             set { this.value.X = value; }
         }
        public double Y
         {
             get { return value.Y; }
             set { this.value.Y = value; }
         }
        public double Z
        {
             get { return value.Z; }
             set { this.value.Z = value; }
         }
        public static PointGeometry operator +(PointGeometry Left, PointGeometry Rigth)
         {
            return new PointGeometry(Left.X + Rigth.X, Left.Y + Rigth.Y, Left.Z + Rigth.Z);
         }
        public override string ToString()
         {
            return string.Format("X: {0}, Y: {1}, Z: {2}", value.X, value.Y, value.Z);
         }
     }
    class Program
     {
        static void Main(string[] args)
         {
             Point tmpPoint = new Point(1, 2, 3);

             PointGeometry tmpPG1 = new PointGeometry(tmpPoint);
             PointGeometry tmpPG2 = new PointGeometry(tmpPoint);
             tmpPG2.X = 4;
             tmpPG2.Y = 5;
             tmpPG2.Z = 6;

            //由于结构是值类型,tmpPG1 和 tmpPG2 的坐标并不一样
             Console.WriteLine(tmpPG1);
             Console.WriteLine(tmpPG2);

            //由于类是引用类型,对tmpPG1坐标修改后影响到了tmpPG3
             PointGeometry tmpPG3 = tmpPG1;
             tmpPG1.X = 7;
             tmpPG1.Y = 8;
             tmpPG1.Z = 9;
             Console.WriteLine(tmpPG1);
             Console.WriteLine(tmpPG3);

             Console.ReadLine();
         }
     }
}

结果:
X: 1, Y: 2, Z: 3
X: 4, Y: 5, Z: 6
X: 7, Y: 8, Z: 9
X: 7, Y: 8, Z: 9


堆和栈是什么?
堆(heap area)存放程序的动态数据
栈(stack area)存放程序的局部数据

1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。地址是由高向低减少的
2、堆区(heap) — 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵呵。地址是由低向高增长的


堆和栈的区别可以用如下的比喻来看出:

使用栈就象我们去饭馆里吃饭,只管点菜(发出申请)、付钱、和吃(使用),吃饱了就走,不必理会切菜、洗菜等准备工作和洗碗、刷锅等扫尾工作,他的好处是快捷,但是自由度小。

使用堆就象是自己动手做喜欢吃的菜肴,比较麻烦,但是比较符合自己的口味,而且自由度大。

评分

参与人数 1技术分 +1 收起 理由
宋天琪 + 1

查看全部评分

回复 使用道具 举报
1. 栈是编译期间就分配好的内存空间,因此你的代码中必须就栈的大小有明确的定义;局部值类型变量,值类型参数等都在栈内存中。
2.堆是程序运行期间动态分配的内存空间,你可以根据程序的运行情况确定要分配的堆内存的大小。
3.Class可以被实例化,属于引用类型,是分配在内存的堆上的。类是引用传递的。
4.Struct属于值类型,是分配在内存的栈上的。结构体是复制传递的。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马