下面这段代码输出什么结果?为什么这样输出?[b]using System;[/b]
大家看看吧............
using System.Collections.Generic;
using System.Text;namespace ConsoleApplication1
{
class Value
{
public int i = 15;
}
class Program
{
static void Main(string[] args)
{
Program t = new Program();
t.first();
}
public void first()
{
int i = 5;
Value v = new Value();
v.i = 25;
second(v, i);
Console.WriteLine(v.i);
}
public void second(Value v, int i)
{
i = 0;
v.i = 20;
Value val = new Value();
v = val;
Console.WriteLine(v.i+" "+i+" ");
}
}
}
大家看看吧............
using System.Collections.Generic;
using System.Text;namespace ConsoleApplication1
{
class Value
{
public int i = 15;
}
class Program
{
static void Main(string[] args)
{
Program t = new Program();
t.first();
}
public void first()
{
int i = 5;
Value v = new Value();
v.i = 25;
second(v, i);
Console.WriteLine(v.i);
}
public void second(Value v, int i)
{
i = 0;
v.i = 20;
Value val = new Value();
v = val;
Console.WriteLine(v.i+" "+i+" ");
}
}
}
解决方案 »
- 一个关于图片保存的错误。
- VC#2005中用serialport控件,DataReceived的事件响应怎么不起作用?请各位前辈指教!
- 如何在窗体load的时候关闭窗体?
- 我有一个问题要提问,有截图才能说明白一点,自己截取了一张.png的图但不知道要怎样贴上来?
- 怎么控件上传图片时的大小
- 问一个比较菜的问题???
- 求助!怎么把图片转换为BYTE[]并添加到数据库IMG列中去?
- 大家推荐几个国外的学习C#的或者ASP.NET好的网站!!!!
- C#写的window应用程序,或者是asp.net,编译时候,报错:创建.PDB文件发生意外错误,为什么?
- TextBox中回车换行符是什么??
- 如何把textbox的值保存到数组中
- 一次输入两次数据
using System.Text;
using System;namespace ConsoleApplication1
{
class Value
{
public int i = 15;
}
class Program
{
static void Main(string[] args)
{
Program t = new Program();
t.first();
}
public void first()
{
int i = 5;
Value v = new Value();
v.i = 25;
second(v, i);
Console.WriteLine(v.i);//20 ?????看不懂 郁闷的问题
}
public void second(Value v, int i)
{
i = 0;
v.i = 20;
Value val = new Value();
v = val;
Console.WriteLine(v.i + " " + i + " ");//15,0 可以理解
}
}
}
没看到引用呢!!!! 不是ref吗!! 请讲讲 !我也奇怪
在方法first中, 实例v的值在second中已经被改变.简单的话, 类是引用类型, 所以是地址传递
using System.Collections.Generic;
using System.Text;
using System;namespace ConsoleApplication1
{
class Value
{
public int i = 15;
}
class Program
{
static void Main(string[] args)
{
Program t = new Program();
t.first();
}
public void first()
{
int i = 5;
Value v = new Value();
v.i = 25;
second(v, i);
Console.WriteLine(v.i);//20 ?????看不懂 郁闷的问题
//因为在second里,v.i的值被赋为20
//之后再second中,v=val;v的引用变成了val,但是此方法中的v还是原来的那个
}
public void second(Value v, int i)
{
i = 0;
v.i = 20;
Value val = new Value();
v = val;
Console.WriteLine(v.i + " " + i + " ");//15,0 可以理解
}
}
}
using System.Text;
using System;namespace ConsoleApplication1
{
class Value
{
public int i = 15;
}
class Program
{
static void Main(string[] args)
{
Program t = new Program();
t.first();
}
public void first()
{
int i = 5;
Value v = new Value(); 此时v.i=15,i=5
v.i = 25; 此时v.i=25
second(v, i); 另起一个副本,不影响此v实例
Console.WriteLine(v.i);//20
}
public void second(Value v, int i)
{
i = 0; 此时v.i=25
v.i = 20;
Value val = new Value();
v = val;到此处是一个全新的value实例,val.i=v.i=15
Console.WriteLine(v.i + " " + i + " ");//15,0 可以理解
}
}
}
20 Main方法中已经写的很清楚了 执行first()
其中 second(v,i) 返回结果输出 15 0
而 frist()方法中Console.WriteLine(v.i) 的v.i 已经是 second() 中定义的v.i。
传的是引用,可以对引用的对象进行操作
比如,传一个人进来,你可以打他一顿,可以请他喝酒,但只能是对这个特定的人人操作
使用ref,传的是引用的引用,可以改变这个引用,指向别的引用
使用ref传一个人进来,相当于一个人所在的位置,你可以把这个人赶走,换成另外一个人
在这里我要谢谢楼主,没有楼主我也不可能知道,难怪我前些天提关于Array的某些方法的时候,没看到ref关键字!!
原来是这样
20 这个是引用的问题 没有ref 等 second v还是原来的哪个 但你可以修改v里的内容.不能改变对V的引用..,
{
public int i = 15;
}
static void Main(string[] args)
{
Program t = new Program();
t.first();
}
public void first()
{
int i = 5;
Value v = new Value();
v.i = 25;
second(ref v, i);
Console.WriteLine(v.i);
}
public void second(ref Value v, int i)
{
i = 0;
v.i = 20;
Value val = new Value();
v = val;
Console.WriteLine(v.i + " " + i + " ");
} 改成上面这样对比一下就好理解了,单步调试下
正确答案是这样:(楼主要给分的)
发表于:2009-03-06 16:21:1410楼 得分:0
大致是这样吧,刚学几天,不太懂 C# code
using System.Collections.Generic;
using System.Text;
using System;namespace ConsoleApplication1
{
class Value
{
public int i = 15;
}
class Program
{
static void Main(string[] args)
{
Program t = new Program();
t.first();
}
public void first()
{
int i = 5;
Value v = new Value(); 此时v.i=15,i=5
v.i = 25; 此时v.i=25是正确的
second(v, i); 另起一个副本,不影响此v实例
Console.WriteLine(v.i);//20
}
public void second(Value v, int i)
{
i = 0; 没看到下面?
v.i = 20; 此时v.1被设置成20了 还没有副本
Value val = new Value();//这里下面这里才是副本才跟first方法里的对象v无关
v = val;//val.i=v.i=15
Console.WriteLine(v.i + " " + i + " ");//15,0
}
}
}
两个v不同的东西指向当然不同不要搞混
Value是一个类,类是引用类型。
{
public int i = 15;
}
static void Main(string[] args)
{
Program t = new Program();
t.first();
}
public void first()
{
int i = 5;
Value v = new Value();
v.i = 25;
second(ref v, i);
Console.WriteLine(v.i);
}
public void second(ref Value v, int i)
{
i = 0;
v.i = 20;
Value val = new Value();
v = val;请问这里v指向了新的内存以后,为什么first方法中的最后一句仍然使用原来的V的地址?
Console.WriteLine(v.i + " " + i + " ");
}
{
class Value
{
public int i = 15;
}
class Program
{
static void Main(string[] args)
{
Program t = new Program();
t.first();
}
public void first()
{
int i = 5;
Value v = new Value();
v.i = 25;
//由于v对象是class类型(.net中的引用类型),
//所以下面在进行参数传递时实际传递的是Value对象的一个引用v;
//其实相当于传递C++中对象的指针;
second(v, i);
Console.WriteLine(v.i);
}
public void second(Value v, int i)
{
i = 0;
//此处是对v所引用的对象的属性进行赋值;
//相当于C++中v指针所指向的对象的属性赋值;
v.i = 20;
Value val = new Value();
v = val;
//此处将v和val引用同一个对象(上面新创建出的)
//相当于C++中v指针指向了val指针所指的对象;
Console.WriteLine(v.i+" "+i+" ");
}
}
}
{
i = 0;
v.i = 20;
Value val = new Value();
v = val;请问这里v指向了新的内存以后,为什么first方法中的最后一句仍然使用原来的V的地址?,
这是个局部变量,用完后就释放了吧..
Console.WriteLine(v.i + " " + i + " ");
}
不是局部变量的问题,改成下面的程序结果也是一样,说到底就是个值传递<引用传递> 值类型<引用类型> 的区别。
namespace ConsoleApplication1
{ class Value
{
public int i = 15;
}
class Program
{
Value val2 = new Value(); static void Main(string[] args)
{
Program t = new Program();
t.first();
}
public void first()
{
int i = 5;
Value v = new Value();
v.i = 25;
second(v, i);
Console.WriteLine(v.i);
}
public void second(Value v, int i)
{
i = 0;
v.i = 20;
v = val2;
Console.WriteLine(v.i + " " + i + " ");
}
}
这里的方法签名已经修改成了public void second(ref Value v, int i)
有个“ref”关键字在,所以:
v = val;语句之后v已经变为新对象的引用了。
单步调试一下就清楚了。
{
public int i = 15;
}
class Program
{
static void Main(string[] args)
{
Program t = new Program();
t.first();
}
public void first()
{
int i = 5;
Value v = new Value();
v.i = 25;
second(v, i); //此处v对象传递给方法的是引用地址,所以second中v.i=20 就修改了托管堆中的数据 所以此处v.i = 20
Console.WriteLine(v.i);
}
public void second(Value v, int i)
{
//此处的v是原始v引用地址的一个副本 但引用还是指向托管堆中的对象,所以此处v.i=20修改了原对象v.i的值
i = 0;
v.i = 20;
Value val = new Value();
v = val; //这里创建了VALUE的新实例并分配了行的引用地址,对把引用地址传给了次方法中的v(这个原对象v引用地址的一个副本),所以v的引用指向新创建的val对象,即:v.i = 15
Console.WriteLine(v.i+" "+i+" ");
}
}
}
using System.Collections.Generic;
using System.Text; namespace ConsoleApplication1
{
class Value
{
public int i = 15;
}
class Program
{
static void Main(string[] args)
{
Program t = new Program();
t.first();
}
public void first()
{
int i = 5;
Value v = new Value();
v.i = 25;
second(v, i);
Console.WriteLine(v.i);
}
public void second(Value t, int i) //改了下参数v为t
{
i = 0;
t.i = 20;
Value val = new Value();
t = val; //此处t被指向了val的地址,和原先的v断开了联系
Console.WriteLine(t.i+" "+i+" ");
}
}
}
再说个相似的例子:
int[] a = new int[] { 1, 2, 3 };
int[] b = new int[] { 7, 8, 9 };int[] c = a;
c[1] = 200;//改变了a[1]的值
c = b;//c指向了b,和a没关系了Console.WriteLine(c[1].ToString());
20如果楼主看过 你必须知道的.NET 就明白了ref 引用类型 是改变引用类型的地址 也就是指针
没有ref 就是没改变而 value对象的内部值(好比给v开辟的一个内存块的里的i的值变了)修改了v的内部 并没有修改v
只要里面有两个V拿来弄晕人的,感觉这题其实是脑筋急转弯.看上面强人的解释还不明白的看这里. class Value
{
public int i = 15;
}
class Program
{
static void Main(string[] args)
{
Program t = new Program();
t.first();
Console.Read();
}
public void first()
{
int i = 5;
Value v = new Value();
v.i = 25;
second(v, i);
Console.WriteLine(v.i);
}
public void second(Value v, int i)
{
i = 0;
v.i = 20;//这里的V其实是first()里面的Value v = new Value();实例化后的.改变后first()输出的当然v.i是20.
Value val = new Value();
v = val; //这里的V是second(Value v, int i)里的V,新的Value val = new Value();实例化.V =VAL后,V.I等于15是理所当然的.
Console.WriteLine(v.i + " " + i + " ");
}
}
public void first()
{
int i = 5;
Value v = new Value();
v.i = 25;
second(v, i);
Console.WriteLine(v.i);
}
public void second(Value t, int i) //改了下参数v为t
{
i = 0;
t.i = 20;
Value val = new Value();
t = val;
Console.WriteLine(t.i+" "+i+" ");
}
second 里面可以对参数t 内部的东西做改变,但是改变不了t本身的引用,也就是说first 函数里面的v去second 里面去转了一下,本身的性质可能改变但是本身的引用没有改变 性质也就是v.i变成了20 .sccond 里面的t引用 的是val的值
20引用和值传递:
Value的构造函数用引用传递类的对象实验证明也事如此(上机试过了)
:)
20
这道题不是很难啊!
LZ应该对C#中的两个数据类型——值类型和引用类型再熟悉熟悉!
比如Main中的v,指向实例,暂时叫做x实例.
传入second的v,其实是v的一个引用copy,不过这个v copy也是指向的x实例,所以你修改v copy的值,其实就是修改了x实例的值,Main中的v,是指向x实例的,所以v实例的值也变了
但是v自身,是个引用,所以当second中的v=val后,只是v copy指向val了,Main中的v还是指向的x实例
20
把public void second(ref Value v, int i)
{
i = 0;
v.i = 20;
Value val = new Value();
v = val;
Console.WriteLine(v.i + " " + i + " ");
}
中的Value val = new Value();
v = val;
去掉得到为
20 0
20
这样就比较容易理解了
15 0
15
引用数据类型 在方法里面进行值传递时都会保留在方法里面的值修改
public void first()
{
int i = 5;
Value v = new Value();
v.i = 25;
second(v, i); //这里面时候v的最后被val 这个实列赋值了 Console.WriteLine(v.i);//v.i也就是val.i 所以 =15
}
public void second(Value v, int i)
{
i = 0;
v.i = 20;
Value val = new Value();
v = val; //此时v我指像 val这个地址的
Console.WriteLine(v.i + " " + i + " ");//15,0 可以理解
}
Module Module1 Class Value
Public i As Integer = 15
End Class Public Sub Main(ByVal args As String())
Call first()
End Sub Public Sub first()
Dim i As Integer = 5
Dim v As New Value()
v.i = 25
second(v, i)
Console.WriteLine(v.i) '15
Console.ReadLine()
End Sub Public Sub second(ByRef v As Value, ByRef i As Integer)
i = 0
v.i = 20
Dim val As New Value()
v = val
Console.WriteLine(v.i & " " & i & " ") '15 0
End Sub
End ModuleModule Module1 Class Value
Public i As Integer = 15
End Class Public Sub Main(ByVal args As String())
Call first()
End Sub Public Sub first()
Dim i As Integer = 5
Dim v As New Value()
v.i = 25
second(v, i)
Console.WriteLine(v.i) '20
Console.ReadLine()
End Sub Public Sub second(ByVal v As Value, ByVal i As Integer)
i = 0
v.i = 20
Dim val As New Value()
v = val
Console.WriteLine(v.i & " " & i & " ") '15 0
End Sub
End Module看看上面两段代码,谁给解释解释?
Public Sub second(ByVal v As Value, ByVal i As Integer)