gweber

每一缕清新的阳光都值得珍惜,每一首歌都有最美丽的旋律,每一个生命都应该受到尊重。

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

叙远试题收集:

1.

请详细解释下面的代码
(如果能编译通过,请描述输出结果;
如果无法编译通过,请解释原因)
using System;

namespace param
{
 class Class1
 {
  static int k;
  [STAThread]
  static void Main(string[] args)
  {
   int i;
   int j = 1;
   Console.WriteLine(j);
   Console.WriteLine(k);
   Console.WriteLine(i);
  }
 }
}

2.

看到昨天post的一道笔试题还比较受大家欢迎,
我准备把这个东西做成一个系列,
难度都不大,
算是对基础知识的一个回顾,
有兴趣的话大家就瞧两眼,
希望看明白之前不要用编译器调试


请指出下面代码的运行结果,并阐述原因

using System;
using System.Collections;
namespace param
{
 class Class1
 {
  [STAThread]
  static void Main(string[] args)
  {
   Hashtable ht = new Hashtable();
   for(int i = 0; i < 5;)
    ht.Add(new cusKey(i++),i);

   if(ht.ContainsKey(new cusKey(3)))
   {
    Console.WriteLine("find!");
   }
   else
   {
    Console.WriteLine("can't find!");
   }
   Console.Read();
  }

  public class cusKey
  {
   int keyNumber;
   public cusKey(int n) { keyNumber = n; }
  }

 }
}

3。

请指出下面代码的运行结果,
老规矩,不许用编译器
using System;
namespace param

  class Class1 
  {
    [STAThread]
    static void Main(string[] args)
    {
      Console.WriteLine(new Class1());
    }
    public override string ToString()
    {
        return string.Format("my name is {0}",this);
    }
  }
}

4.

请指出下面代码的运行结果并解释原理,
老规矩,不许用编译器
using System;
namespace param
{
  class Class1
  {
    static int i = getNum();
    int j = getNum();
    static int num = 1;
    static int getNum()
    {
      return num;
    }
    [STAThread]
    static void Main(string[] args)
    {
      Console.WriteLine(string.Format("i={0}",i));
      Console.WriteLine(string.Format("j={0}",new Class1().j));
      Console.Read();
    }
  }
}

说明:

1.

c# 真是太呆痴了 C# 编译器不允许使用未初始化的变量。如果编译器检测到使用了可能未初始化的变量
-622668(2972852) 12:24:14
就会生成 CS0165。
-622668(2972852) 12:24:26
// CS0165.cs
using System;

class MyClass
{
public int i;
}

class MyClass2
{
public static void Main(string [] args)
{
int i, j;
if (args[0] == "test")
{
i = 0;
}

/*
// to resolve, either initialize the variables when declared
// or provide for logic to initialize them, as follows:
else
{
i = 1;
}
*/

j = i; // CS0165, i might be uninitialized

MyClass x;
x.i = 0; // CS0165
// use new as follows
// MyClass x = new MyClass();
// x.i = 0;
}
}

2.

can't find!
因为类cusKey 没有比较的依据,需要重写Equals方法才能比较.我把程序改了一下,这样就可以了.

using System;
using System.Collections;
namespace param
{
class Class1
{
[STAThread]
static void Main(string[] args)
{
Hashtable ht = new Hashtable();
for(int i = 0; i < 5;)
ht.Add(new cusKey(i++),i);

if(ht.ContainsKey(new cusKey(3)))
{
Console.WriteLine("find!");
}
else
{
Console.WriteLine("can't find!");
}
Console.Read();
}

public class cusKey
{
int keyNumber;
public cusKey(int n) { keyNumber = n; }
public override bool Equals(Object obj)
{
// Check for null values and compare run-time types.
if (obj == null || GetType() != obj.GetType())
return false;
cusKey p = (cusKey)obj;
return (keyNumber == p.keyNumber);
}
public override int GetHashCode()
{
return keyNumber.GetHashCode();
}

}
}
}

3.

不是this惹的祸,而是缺省调用了this.ToString造成了死循环.
改为:
return string.Format("my name is {0}",this.GetType());

--------

//这是个递归函数,自己调用自己,永远无法返回,就如上面的跟踪信息所得到的一样!楼主果然强,以前从来没有思考过这么古怪的问题。
public override string ToString()
{
return string.Format("my name is {0}",this.ToString());
}

4.

自己功力不行,惭愧,做不出来,我师傅给出了比较完善的解释,转贴一下
结果是i=0,j=1
“下面我解释一下为什么是后一种结果
对一个类来说,static变量是与对象无关的,那么它们什么时候被初始化呢?就是在第一次引用的时候。当类生成对象的时候,可以简单分成3步
1,为所有static变量分配内存,这个时候内存里面的值是该变量类型的缺省值。关于不同值类型的缺省值大家可以去查相关资料,注意值类型和引用类型是不同的。
2,为static变量赋值,同样要注意值类型和引用类型是不同的。
3,生成对象,调用构造函数,先调用这个类的父类的构造函数,然后调用类本身的构造函数,生成对象。
现在分析上面的代码:
Console.WriteLine(string.Format("i={0}",i));这里i是static变量,而且类class1是第一次被引用,按照上面说的三步,要先为class1里面所有的static变量分配内存。尽管现在有超线程技术,但是指令在逻辑还是一条一条的按顺序执行的,所以先为static int i分配内存,并且在该内存中保持int的缺省值0,接着再为static int num 变量分配内存,值当然也为0。
然后执行第二步,为变量赋值:先为static int i变量赋值,i=getNum(),看getNum里面的代码,就是return num,这个时候num的值是0,于是i就为0了。然后对变量num赋值,num=1;这行代码执行后,num就为1了。分析到这里我就不继续分析了,大家很容易看出结果是什么。”

-------------

如果我看到这样的笔试题,大概会在试卷上写:不建议写出这样的代码...

编译器为了行为的确定性,必然会做很多硬性的规定,这些规定与写出好的程序无关的。

就好象上次讨论的 x += x++ 的结果一样。做为智力测试可以,但做为笔试题则不是很妥当。

笔试题中的每个题都应该是为了揭示应试者是否具有某种能力,而出题时应该想想 我们是否需要这种能力。

posted on 2005-06-21 19:57  Gweber.NET  阅读(2982)  评论(1编辑  收藏  举报