声明一个变量时,C#是否为他分配了内存空间?

Scarroot 2006-04-22 05:41:10
如:

public int a;
public int a=5;

局部
int a;
int a=5;

public string s;
public stirng s="";
public string s=null;

局部
string s;
stirng s="";
string s=null;

System.Web.UI.Page page;
System.Web.UI.Page page = new System.Web.UI.Page();

网上查了一下,还是不太明白.
...全文
963 14 点赞 打赏 收藏 举报
写回复
14 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
Scarroot 2006-04-24
呵,
谢谢各位大侠回复.
  • 打赏
  • 举报
回复
wraith1234 2006-04-23
在.net framework里面,clr中存在2个内存管理的区域,一个是堆栈,一个就是托管堆,
如果是值类型,clr会在堆栈里面分配一个内存给它,
如 int x =5; //注意这里是在堆栈,因为int是值类型

而如果是引用类型,如string,object等等,clr会在堆栈里面分配一个引用的地址,而new 一个对象时候会在托管堆里面分配一块内存给这个引用,
如 string s ="abc";
这里可以分成2步
1 string s; //面分配一个string的引用,并且并不指向任何托管堆的对象
2 s = "abc"; //在托管堆里面分配一块string类型的对象实例的内存,并让s指向这块内存

如果还不清楚,可以去看Jeffrey Ritcher的.net框架程序设计这本书~~~~~
  • 打赏
  • 举报
回复 1
IkusaHime 2006-04-22
good, 忽略了 IL.
  • 打赏
  • 举报
回复
Ivony 2006-04-22
刚刚在研究的时候,发现一个很有意思的情况:

for( int i = 0; i < 10; i ++ )
{

}
这个时候,i仅存在于for块内。但是在IL中,它却是在函数的开始处定义的。

如果情况复杂一些:

for ( int i = 0; i < 10; i ++ );

for ( int 1 = 2; i < 5; i --);

这是符合C#语法的,但是如果两个i都在函数开始处定义的话,肯定是不行的。

所以这个时候,第二个i在IL中变成了V_n(n是一个数字)的形式。
  • 打赏
  • 举报
回复
Ivony 2006-04-22
C#的编译器基本上可以捕捉到所有的变量未被赋初值的情况,即使是这样也通不过编译:

int i;

try
{
i = 0;
}
finally
{
Console.Write( i );
}
  • 打赏
  • 举报
回复
Ivony 2006-04-22
局部变量是这样的。

如果局部变量除赋值外再未被使用,则它们根本就不会被创建(编译警告)。

如果局部变量未被赋值就被使用,则是编译错误。

即使是放在for( int i = 0; i < 5; i ++ )的循环中赋值。
但是有几个例外。

在while( true )循环中赋值可以。
do...while循环中赋值可以。
在for(;;)中可以
在if中可以,如果if块和else块都有赋值。
其他的情况大多数不可识别。


如果局部变量按照正常的流程走,在使用前赋值,从IL上看,这个时候它们是在函数开始处被定义的。至于是不是在这里分配空间,则因为堆栈复杂的操作,我不好下结论。
  • 打赏
  • 举报
回复
IkusaHime 2006-04-22
解释得很详细啊. 请教这些比较根基的 .NET 原理不知通过什么教材可以了解 ?
  • 打赏
  • 举报
回复
Ivony 2006-04-22
静态字段在第一次引用类时分配空间。
  • 打赏
  • 举报
回复
Ivony 2006-04-22
最关键搞清楚局部变量、值类型实例、引用类型实例和字段的概念。

值类型实例就是值类型的实例,如1,值类型变量i,只是储存值类型实例的容器。

引用类型实例就是引用来性的实例,如"123",其在托管堆上分配,引用类型变量s只是储存托管堆的地址。

字段就是隶属于类型的变量,也就是类型的成员变量。如果是实例字段,则在创建实例时分配内存空间,根据实例是引用类型还是值类型分配在托管堆或堆栈上。与其本身是值类型还是引用类型无关。但如果其是值类型,则直接保存值,如果其是引用类型,则还是保存引用。


局部变量比较复杂,待会儿说……
  • 打赏
  • 举报
回复
Ivony 2006-04-22
局部变量在定义时就已经分配空间,不过值类型的变量是直接分配默认值,引用类型的分配默认引用null。
引用类型变量的实例在new时在托管堆上分配内存。

类实例成员变量在类实例在实例被创建时分配一次,类实例杯创建多少次它就分配多少次。同样是分配默认值。

类静态成员变量在类第一次被引用时分配。
  • 打赏
  • 举报
回复
补充两个例子(假设xyz是任意类型的自定义对象):

object O1;
O1=xyz;
object O2=new object(); //这里分配了空间。
O1=xyz;
  • 打赏
  • 举报
回复
copico 2006-04-22
变量的声明占一个指针的空间
如果确定分配大小了,再加上大小的空间
但变量的指的实际空间的首地址
  • 打赏
  • 举报
回复
huzy 2006-04-22
变量的声明并没有分配空间。引用他所分配的也只是一个指针,他所指的是变量名的地址。
一旦变量通过编译,系统会为他自动初始化,那样也就分配了空间。初始化值一般为零。
  • 打赏
  • 举报
回复
zCheng 2006-04-22
public int a;
public int a=5;

局部
int a;
int a=5;

public string s; // 未分配
public stirng s="";
public string s=null; // 未分配

局部
string s; // 未分配
stirng s="";
string s=null; //未分配

System.Web.UI.Page page; // 未分配
System.Web.UI.Page page = new System.Web.UI.Page();

除了标注了的,都已经分配。
不过引用类型的变量分配的是地址
  • 打赏
  • 举报
回复
相关推荐
发帖
C#
加入

10.6w+

社区成员

.NET技术 C#
申请成为版主
帖子事件
创建了帖子
2006-04-22 05:41
社区公告

让您成为最强悍的C#开发者