【C#】实验二 值类型、引用类型内存分配

1. 先填空再验证:

struct SomeVal { public int x; }
class SomeRef { public int x; }
class SomeRef2 { public SomeVal val; }
class SomeVal3 { public SomeRef rf; }
public static void Main()
{
	/*声明结构体,因为是值类型,所以在栈中分配内存*/
    SomeVal v1; //有没有分配空间?分配在哪里(堆/栈)?  栈    
    
    /*没有初始化,不能运行*/ 
    Console.WriteLine(v1.x); //能运行吗?   不能   

 	/*由于结构体是值类型,所以结构体的实例化可以不使用new运算符。
 	结构体的new操作不执行分配内存操作,只是执行初始化数据操作
 	v1还是原来的v1,可尝试输出地址,两者相同*/
    v1 = new SomeVal();//有没有分配空间?分配在哪里(堆/栈)?  没有分配空间

	/*new SomeVal()不是创造一个对象,而是运行它的默认构造函数,
	而构造函数给v1.x赋了初始值,为0*/     
    Console.WriteLine(v1.x); //输出:   0  

	/*这里就是正常的变量赋值*/  
    v1.x = 5;
    Console.WriteLine(v1.x); //输出:   5    
	
	/*声明类的实例,没有指明内存地址*/
    SomeRef r1;//有没有分配空间?分配在哪里(堆/栈)?   没有分配空间 

	/*这里是因为r1地址不明确*/   
    Console.WriteLine(r1.x); //能运行吗?     不能

	/*动态分配内存,类是引用类型变量,则对象r1分配到堆*/   
    r1 = new SomeRef();//有没有分配空间?分配在哪里(堆/栈)?  堆

	/*默认值是0*/     
    Console.WriteLine(r1.x); // 输出:    0
      
    /*正常的变量赋值*/   
    r1.x = 5;
    Console.WriteLine(r1.x); // 输出:  5     

	/*值类型,赋值相当于拷贝一份,在栈区分配了内存*/
    SomeVal v2 = v1;  

	/*引用类型,在栈区分配了内存存放地址,对象仍然指向同一个*/
    SomeRef r2 = r1;

	/*只改变v1的值,因为v1和v2的对象是不同的*/
    v1.x = 9;

	/*r1和r2的x都变为了8*/
    r1.x = 8;
    
    Console.WriteLine(r1.x); // 输出:   8    
    Console.WriteLine(r2.x); // 输出:   8   
    Console.WriteLine(v1.x); // 输出:   9    
    Console.WriteLine(v2.x); // 输出:   5   
	
	/*动态分配内存,类是引用类型变量,则对象sf2_1分配到堆*/ 
    SomeRef2 sf2_1 = new SomeRef2();//sf2_1空间分配在哪里(堆/栈)?   堆

	/*值类型作为类的成员变量时,在堆中分配*/    
    SomeVal sv2_1 = sf2_1.val;//sv2_1空间分配在哪里(堆/栈)?   堆 

	/*同上*/   
    SomeRef2 sf2_2 = new SomeRef2();
    SomeVal sv2_2 = sf2_2.val;

	/*
	Equals()方法使用如下:
	1) 系统类一般已经覆盖了Equals(),比较的是内容。
	值类型和引用类型,Equals()比较的都是内容。
	2) 用户自定义类如果没有覆盖Equals(),将调用
	父类的Equals (比如是Object),而Object的Equals的比较
	是地址(return (this == obj);)
	要想让他能够比较两个变量的内容是否相同,那就应该重写Equals方法
	但是类SomeRef2中没有重写,且是引用类型。
	sf2_1和sf2_2两个地址不同,则输出False
	SomeVal是值类型,比较内容,且都是默认值0,则输出True
	*/
    Console.WriteLine($"两个类实例相等吗?{sf2_1.Equals(sf2_2)}");// 输出: False    
    Console.WriteLine($"两个结构实例相等吗?{sv2_1.Equals(sv2_2)}");// 输出: True     

    SomeVal3 sv3_1 = new SomeVal3();
    SomeVal3 sv3_2 = new SomeVal3();
    
    /*rf为默认初始值,null*/
    Console.WriteLine($"{sv3_1.rf == null} {sv3_2.rf == null}");// 输出: True True 
    
    /*引用类型,地址不同,False*/    
    Console.WriteLine($"两个结构实例相等吗?{sv3_1.Equals(sv3_2)}");// 输出: False      
    sv3_1.rf = new SomeRef();
    sv3_2.rf = new SomeRef();
    
    /*rf是SomeRef类型,依然是引用类型,地址不同,False*/
    Console.WriteLine($"两个类实例相等吗?{sv3_1.rf.Equals(sv3_2.rf)}");// 输出: False     
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值