首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > C# >

C#面试题,并散分解决方法

2012-02-14 
C#面试题,并散分出了一个面试题,如下:请写出下面代码的运行结果,并解释为什么?C# codeusing Systempublic

C#面试题,并散分
出了一个面试题,如下:
请写出下面代码的运行结果,并解释为什么?

C# code
using System;public class Test1{    public static void Main()    {        int num = 0;        Person p = new Person("Li");        A1(p, num);        Console.WriteLine("{0},{1}", p.name, num);    }    static void A1(Person p, int num)    {        p = new Person("Wang");        num = 1;    }}public class Person{    public string name;    public Person(string name)    {        this.name = name;    }}


10个人面试,10个人都回答错误,难道这题很难?
这是我在实际开发中遇到过的问题,所以列入了面试题中
你也来回答看看
并说说有没有必要面试这种题目

[解决办法]
Li和0啊,两个都不会变
[解决办法]
Person p = new Person("Li"); int num = 0;
输出的是这两个..

不可能10个人都回答错误.

[解决办法]
调用A1的时候
两个p都引用Li那个对象,后来,第二个p引用了Wang,这对第一个p不会影响
两个num存储在不同位置,更不会相互影响了
所以,Li 0
[解决办法]
这个不难吧?
Li,0

关键是分析这个函数:A1(Person p, int num)
P是以引用形式传进来的,num是以值形式传进来的,所以在Al()中对num的修改不会返回到调用Al()的函数中;
Al()函数中的p是引用,所以对P的修改会影响p的值,但引用也是复制后传到Al()函数中的,所以对P的副本重新赋值不会影响到p,但对p副本的属性赋值会影响到p,这大概就是引用;
[解决办法]
10人都答错?不可能吧。
[解决办法]
看来还是没有理解引用传递及值传递
[解决办法]
怎么可能呢?LZ是哪个公司的?还招人不。
[解决办法]
Li 0
[解决办法]
int num = 0;
Person p = new Person("Li");
A1(p, num);

这句话打印的变量是局部的,更上面A1(p,num)没有关系。
 Console.WriteLine("{0},{1}", p.name, num);


[解决办法]
探讨
看来还是没有理解引用传递及值传递

[解决办法]

[解决办法]
C# code
using System;public class Test1{    public static void Main()    {        int num = 0;        Person p = new Person("Li");        A1(p, num);        Console.WriteLine("{0},{1}", p.name, num);    }    static void A1(Person p, int num)    {        p.name = "Wang";        num = 1;    }}public class Person{    public string name;    public Person(string name)    {        this.name = name;    }}
[解决办法]
学习+接分
[解决办法]
好多人学习都不注重基础的,都是拿来就用,不知就里
[解决办法]
jf来的
[解决办法]
亡灵
[解决办法]
up
[解决办法]
悄悄的路过

顺便bs一下c#

既然学java,就干脆学到底,偏偏关键字改个大小写,这不是吃饱了撑的嘛。。。。。。。。

Main:main
string:String
------解决方案--------------------


using System;
public class Test1
{
public static void Main()
{
int num = 0;
Person p = new Person("Li");
A1(p, num);
Console.WriteLine("{0},{1}", p.name, num);
}
static void A1(Person p, int num)
{
p.name = "Wang";
num = 1;
}
}
public class Person
{
public string name;
public Person(string name)
{
this.name = name;
}
}
如果改成这样,输出Wang, 0
此时,A1中引用的是p的地址,所以当p值改变后,Main中的p也变。
[解决办法]
靠,我居然错了。深刻反醒!!!

我的天啊!
[解决办法]
mark
[解决办法]
Li 0
这个以前我也遇到过
[解决办法]
学习一下。
[解决办法]

探讨
这个不难吧?
Li,0

关键是分析这个函数:A1(Person p, int num)
P是以引用形式传进来的,num是以值形式传进来的,所以在Al()中对num的修改不会返回到调用Al()的函数中;
Al()函数中的p是引用,所以对P的修改会影响p的值,但引用也是复制后传到Al()函数中的,所以对P的副本重新赋值不会影响到p,但对p副本的属性赋值会影响到p,这大概就是引用;

[解决办法]
前几天看过一道这种类似的题,才算有点明白。

[解决办法]
li 0

你说十个人都打错,吓得我不敢回答了,呵呵
[解决办法]
结果是Li,0,因为在main方法里重新赋值了,将原来的wang和1覆盖了
[解决办法]
就java角度来讲,只有传值,就是将值拷贝一份传给函数。

那么,修改拷贝的东西,对原来的东西当然没影响。

btw:我的意思是,既然什么都学java,为啥要改main的大小写呢?害得我代码考过去还要修改。。。。。。。。。
[解决办法]
哎,还是自己太菜了,经不住考验啊,呵呵
[解决办法]
jf
[解决办法]
经过五分钟多才理顺。天那!有些沮丧~本来很容易的问题。

这个根本不是理解引用传递和值传递的问题。实际上主要是变量作用域问题。


[解决办法]
jf
[解决办法]
A1(Person p, int num)
{
p = new Person("Wang"); //这里的p指向的是一个新开辟的内存块。呼~其实就这么简单。

[解决办法]
结果是Li,0,接分!
[解决办法]
探讨
结果是Li,0,因为在main方法里重新赋值了,将原来的wang和1覆盖了

[解决办法]
这代码 写这代码的人该拉出去枪毙了
[解决办法]
同意楼上的。
[解决办法]
引用类型变量: p形参是实参引用的复制,开始是指向li。 后来指向新的wang。 没有采用p.Name方式修改,而是开了一个新对象。
 因为是复制的引用,所以没有影响到原来的p (没有采用p.Name方式修改)。所以结果还是第一个对象li。
[解决办法]
探讨
看来还是没有理解引用传递及值传递

[解决办法]
探讨
实际上就是引用:
经过五分钟多才理顺。天那!有些沮丧~本来很容易的问题。

这个根本不是理解引用传递和值传递的问题。实际上主要是变量作用域问题。


------解决方案--------------------


jf
[解决办法]

探讨
为什么?
你在开发中,永远不会写出这种代码?

引用:
这代码 写这代码的人该拉出去枪毙了


[解决办法]
不会吧!10跟人都错了!不可思议,这可是很基础的题目啊!那些人我会以学了没有啊!汗啊!!!
待明年我出去的时候要能碰上这样的面试题 太好了!
[解决办法]
结果 Wang,0
对象方法中的对象类型按引用传递,值对象按值传递.
所以int按值传递,方法中的修改不影响变量本身的值.
Person p是对象,按引用传递,方法中的操作会影响对象.就这样.

[解决办法]
探讨
为什么?
你在开发中,永远不会写出这种代码?

引用:
这代码 写这代码的人该拉出去枪毙了

[解决办法]
大不上了就是没系统的学习过C#,分不清值类型和引用类型.呵呵!
[解决办法]
对了刚忘了说答案了 很明显吗!是:li 0 吗!
[解决办法]
有没有搞错?
[解决办法]
探讨
结果 Wang,0
对象方法中的对象类型按引用传递,值对象按值传递.
所以int按值传递,方法中的修改不影响变量本身的值.
Person p是对象,按引用传递,方法中的操作会影响对象.就这样.


[解决办法]
探讨
引用:
为什么?
你在开发中,永远不会写出这种代码?

引用:
这代码 写这代码的人该拉出去枪毙了


其实"写这代码的人该拉出去枪毙了"这话还是有点道理。

正常情况下,我们很自然的,习惯性的就不会这样使用传过来的引用变量,难道不是吗?


[解决办法]
探讨
实际上就是引用:
经过五分钟多才理顺。天那!有些沮丧~本来很容易的问题。

这个根本不是理解引用传递和值传递的问题。实际上主要是变量作用域问题。

[解决办法]
探讨
引用:
实际上就是引用:
经过五分钟多才理顺。天那!有些沮丧~本来很容易的问题。

这个根本不是理解引用传递和值传递的问题。实际上主要是变量作用域问题。


[解决办法]
探讨
为什么?
你在开发中,永远不会写出这种代码?

[解决办法]
服从多数
[code=C#][/code]Li 0
[解决办法]
li 0
[解决办法]
方法里都new Person()了,
就不是原来的实例的引用了,构造器会重新分配内存空间存放新实例
基础知识啊
[解决办法]
探讨
服从多数
Li 0

[解决办法]
探讨
引用:
结果 Wang,0
对象方法中的对象类型按引用传递,值对象按值传递.
所以int按值传递,方法中的修改不影响变量本身的值.
Person p是对象,按引用传递,方法中的操作会影响对象.就这样.


。。。。。。。。

老大啊,你真强大。。。。。。。

人家都说了是Li 0.。。。。。。

[解决办法]
要么就是懂点的
要么就是完全不懂的
这个要是考虑复杂了或许会弄错吧

[解决办法]
我认为答案是wang,1。
经过A1(P,num)调用后,原p赋值"Li"将更改为"Wang",同时num也会更改为1。
[解决办法]
探讨
实际上就是引用:
经过五分钟多才理顺。天那!有些沮丧~本来很容易的问题。

这个根本不是理解引用传递和值传递的问题。实际上主要是变量作用域问题。


[解决办法]
li 1
[解决办法]
亡灵,上机试试.
[解决办法]
学习了
[解决办法]

探讨
亡灵,上机试试.

[解决办法]
学习了啊
一开始还真的没有注意啊
[解决办法]
探讨
我认为答案是wang,1。
经过A1(P,num)调用后,原p赋值"Li"将更改为"Wang",同时num也会更改为1。

[解决办法]
不管是什么语言,如果你作为这个语言的设计者,当对象作为参数时,把传递对象实体拷贝作为缺省方式是低效率的设计,因此任何一款语言都不会这么设计。

这就像去餐馆吃饭,一般都是你先点菜(接口),然后服务员给你上菜(实例)一样。
[解决办法]
li ,0五楼高手
[解决办法]
探讨
悄悄的路过

顺便bs一下c#

既然学java,就干脆学到底,偏偏关键字改个大小写,这不是吃饱了撑的嘛。。。。。。。。

Main:main
string:String

[解决办法]
靠,我也错了。
反省去...

[解决办法]
学习了
[解决办法]
形参同样是在栈上开辟临时空间对实参进行拷贝,值类型的是拷贝的值,而引用类型是拷贝的地址,被调用的方法中操作的是形参
如果引用类型得成员被重新赋值了,那么实参的成员也会改变,因为他们操作的是同一个地址,如果形参被new了,那么形参和实参没有了任何关系了
值类型形参和实参本来就没有关系,当然以上情况强制引用除外
[解决办法]
探讨
cj205: 其实这不是答题人的问题 是阁下自己都不知道为什么

namhyuk其实是理解了意思 但是说法可能欠妥当或者说准确

愿闻其详,请大虾指点

[解决办法]
LI 0
传递 引用的知识
[解决办法]
前面的大牛们都说了.
其实可以这样理解咯:
对一个引用对象,引用的指针(p1)放在栈,指针所指向的是对象内容放在堆.
调用一个函数,
这时,会在栈上把p1复制一份(值复制),形成p2,同样,p2和p1一样也是指向堆中同一个地址的.
即在
static void A1(Person p, int num)
{
p = new Person("Wang");
num = 1;
}
中,参数Person p,即为p2,
 p2 = new Person("Wang");
使p2指针指向了一个新申请的堆中的位置.
结果,p2的值变了.p1的值没有变.
所以,主函数:
Console.WriteLine("{0},{1}", p.name, num);
时,p.name,即为p1所指向的内容.所以是
li


不知我理解得对不对?

[解决办法]
好题,学习!
[解决办法]
学习
[解决办法]
Li 0 

是值传递

加ref就传地址
[解决办法]
其实这两个参数都是值传递,num就不用说了,它是值类型,所以传递到方法中的是它的副本,而p是引用类型,但是它没有加ref或者out,所以它是以值传递引用类型,引用类型的变量不直接包含其数据;它包含的是对其数据的引用。当通过值传递引用类型的参数时,有可能更改引用所指向的数据,如某类成员的值。但是无法更改引用本身的值;也就是说,不能使用相同的引用为新类分配内存并使之在块外保持。
在楼主的示例中,p为引用类型,在未使用 ref 参数的情况下传递给方法A1。在此情况下,将向方法传递指向p的引用的一个副本。但是在A1方法中使用 new 运算符来分配新的内存部分,将使A1中的p引用新的Person,因此,这之后的任何更改都不会影响原始Person p(它是在 Main 内创建的)。实际上,本示例中创建了两个Person对象,一个在 Main 内,一个在 A1 方法内
[解决办法]


这里传不传那个引用有什么区别啊,关键就在这儿!

有区别吗?所以说这个问题主要不是理解什么引用型,值类型传值的问题!


------解决方案--------------------




这里传不传那个引用有什么区别啊,关键就在这儿!

有区别吗?所以说这个问题主要不是理解什么引用型,值类型传值的问题!


[解决办法]
看看这个呢

C# code
 using System;    public class Test1    {        public static void Main()        {            int num = 0;            Person p = new Person("Li");            A1(ref p, num);            Console.WriteLine("{0},{1}", p.name, num);            Console.Read();        }        static void A1(ref Person p, int num)        {            p = new Person("Wang");            num = 1;        }    }    public class Person    {        public string name;        public Person(string name)        {            this.name = name;        }    }
[解决办法]
还在这纠缠不清...

探讨
lz的理解是错误的,这里哪里来的引用传递?以错考错,都是错...
这里当然不是引用传递,但是一般我们称值类型以外的都是引用类型

[解决办法]
void fun(int i)
fun(ival);
编译器会把ival复制到栈上,作为参数。这样,i实际上是在栈上,你修改i,只修改了栈上的内容,等到退出函数,栈回滚,i的内容也就消失了
void fun(int* i)
fun(&ival)
此时的参数类型是指针,编译器会把ival的地址作为参数的值压到栈里,这样,参数i实际上就是指向ival的指针,修改这个指针指向的内容可以修改对象(*i=...),但如果只修改i,就是修改了指针的内容,对ival的值没有影响

这是从C++上面来理解的 不知道是不是我误会了阁下的说法了
[解决办法]
這個代碼寫得很無聊。。

热点排行