我最近在一次采访中被问到了实际存储变量的位置。 我回答了值类型变量存储在堆栈上,参考类型变量存储在堆上,但是面试官让我给我一个程序中的实时场景。请检查下面的程序并帮助我存储值类型的位置以及谁将会以参考类型存储。如果您可以通过程序给出示例,它将非常有用,或者让我知道任何可以在VS中检查这些存储的工具
class Program
{
int i = 5;
bool a;
string str = "Stack Overflow";
object obj = "object";
string employeeName;
int employeeCode;
public int Add(int x,int y)
{
float a = 7.0F;
return x + y;
}
static void Main(string[] args)
{
Program obj = new Program();
obj.employeeCode = 1000;
obj.employeeName = "John";
int result = obj.Add(10, 15);
}
}
请让我知道这些变量存储在哪里的原因。给出一些值类型和引用类型的例子
答案 0 :(得分:3)
以下是对幕后内容的概述。我能提供的最好的例子是一系列具有堆栈和堆表示的数字。
首先,我们假设我们有两个班级:士兵和军官。军官延伸士兵。另外,我们在method1中有一些逻辑。当method1的执行开始时,我们有一些堆栈和堆的状态。 Stack有一些先前执行的东西,现在并不重要,Heap有我们的类定义。
1)在method1的开头,我们有几个声明语句,因此两个变量将被推送到堆栈 s 和年龄。现在 s 无需指出,年龄 == 0。
2) s = new Officer()语句在堆中创建新对象,此对象的地址现已分配给 s
3)让我们假设 Soldier.Lookup(名称)是Soldier类中的静态方法。例如,它查询数据库并生成新的Officer对象。因此, s 指针将指向一个新对象,而前一个对象是垃圾收集的候选对象。
4)下一个语句只是一个值赋值。 年龄现在是31(31是GetSoldierAge()操作的结果。)
5) s.CurrentStatusReport()有一些副作用(打印报告)并且不影响我们的记忆,所以我们将忽略它。下一个语句是调用 sendOutForTraining(age,s)方法,这里有很多乐趣:)
6)当执行进入 sendOutForTraining(age,s)时,会发生以下情况:
指向 sendOutForTraining 的指针被压入堆栈(用于返回目的)。
创建变量 a 并将其推送到堆栈。 年龄的值会立即复制到 a 。
创建变量 sldr 并将其推送到堆栈。来自 s 的指针被复制到 sldr ,现在 s 和 sldr 指向同一个对象。
输入sendOutForTraining
7)计算+ = 2的结果并将其存储在堆栈中。如您所见,年龄和 a 是不同的变量,包含不同的值。
8)好的, sldr.age = a 。应该清楚的是,此操作的结果将影响 s 和 sldr 指向的共享对象。因此,在这种方法之外,年龄应该等于33。
9)另一项任务。 sldr = new Soldier(); 结果是一个全新的对象,其地址现在存储在 sldr 中。来自方法外部的 s 变量不知道它并且绝对不关心。
10)最终语句只会改变 sldr 地址下对象的实例字段。
11)方法执行结束,作业完成后应清理每个工件。未使用的变量将被销毁,对象将被垃圾收集。
12)正如我们所看到的, sedOutForTraining 已经过了标记。 Officer对象的实例变量的年龄为33岁。