您的位置:首页 > 编程语言 > C语言/C++

C/C++/C#面试题精选

2011-09-25 21:35 288 查看
问题(21):C#是一门托管语言,那么是不是说明只要用C#,就能保证不会出现内存泄露和其他资源泄漏?如果不是,在哪些情况下可能会出现泄漏?

答案:C#不能保证没有资源泄漏。比如如下几种情况可能会造成资源泄漏:(1) 调用Nativecode,比如用P/Invoke或者调用COM;(2) 读写文件时的,没有及时closestream, 或者ADO.NET连数据库时,没有及时关闭连接,也算资源泄漏?(3)注册事件后没有remove,导致publisher和subscriber的强依 赖,垃圾回收可能会被推迟;(4).NET还定义了一些方法直接申请非托管内存,比如Marshal.AllocHGlobal和Marshal.AllocCoTaskMem。通过这种方式得到的内存,如果没有及时释放,也会造成内存泄露。

问题(22):下面的两段C#有哪些不同?

view plaincopy to clipboardprint?

static void CatchException1()
{
try
{
Function();
}
catch
{
throw;
}
}

static void CatchException2()
{
try
{
Function();
}
catch (Exception e)
{
throw e;

}
}

view plaincopy to clipboardprint?

bool Fun1(char* str)
{
printf("%s\n",str);

return false;
}

bool Fun2(char* str)
{
printf("%s\n",str);

return true;
}

int _tmain(int argc, _TCHAR* argv[])
{
bool res1,res2;

res1 = (Fun1("a")&& Fun2("b")) || (Fun1("c") || Fun2("d"));
res2 = (Fun1("a")&& Fun2("b")) &&(Fun1("c") || Fun2("d"));

return res1|| res2;
}

bool Fun1(char* str)
{
printf("%s\n",str);
return false;
}

bool Fun2(char* str)
{
printf("%s\n",str);
return true;
}

int _tmain(int argc, _TCHAR* argv[])
{
bool res1,res2;
res1 = (Fun1("a")&& Fun2("b")) || (Fun1("c") || Fun2("d"));
res2 = (Fun1("a")&& Fun2("b")) &&(Fun1("c") || Fun2("d"));

return res1|| res2;
}
答案:打印出4行,分别是a、c、d、a。

在C/C++中,与、或运算是从左到右的顺序执行的。在计算rest1时,先计算Fun1(“a”)&& Func2(“b”)。首先Func1(“a”)打印出内容为a的一行。由于Fun1(“a”)返回的是false,无论Func2(“b”)的返回值是true还是false,Fun1(“a”)&& Func2(“b”)的结果都是false。由于Func2(“b”)的结果无关重要,因此Func2(“b”)会略去而不做计算。接下来计算Fun1(“c”)|| Func2(“d”),分别打印出内容c和d的两行。

在计算rest2时,首先Func1(“a”)打印出内容为a的一行。由于Func1(“a”)返回false,和前面一样的道理,Func2(“b”)会略去不做计算。由于Fun1(“a”)&& Func2(“b”)的结果是false,不管Fun1(“c”)&& Func2(“d”)的结果是什么,整个表达式得到的结果都是false,因此Fun1(“c”) || Func2(“d”)都将被忽略。

问题(24):运行下面的C#代码,打印出来的结果是什么?

view plaincopy to clipboardprint?

struct Person
{
public string Name;

public overridestring ToString()

{
return Name;

}
}

class Program
{
static void Main(string[]args)
{
ArrayListarray = new ArrayList();
Personjim = new Person(){Name ="Jim"};

array.Add(jim);

Personfirst = (Person)array[0];
first.Name = "Peter";

Console.WriteLine(array[0].ToString());
}
}

view plaincopy to clipboardprint?

class Base
{
public:
voidprint() { doPrint();}

private:
virtual void doPrint() {cout <<"Base::doPrint" << endl;}

};

class Derived : public Base
{
private:
virtual void doPrint() {cout <<"Derived::doPrint" << endl;}

};

int _tmain(int argc, _TCHAR* argv[])
{
Base b;
b.print();

Derived d;
d.print();

return 0;
}

class Base
{
public:
voidprint() { doPrint();}

private:
virtual void doPrint() {cout << "Base::doPrint" << endl;}
};

class Derived : public Base
{
private:
virtual void doPrint() {cout << "Derived::doPrint" << endl;}
};

int _tmain(int argc, _TCHAR* argv[])
{
Base b;
b.print();

Derived d;
d.print();

return 0;
}

答案:输出两行,分别是Base::doPrint和Derived::doPrint。在print中调用doPrint时,doPrint()的写法和this->doPrint()是等价的,因此将根据实际的类型调用对应的doPrint。所以结果是分别调用的是Base::doPrint和Derived::doPrint2。如果感兴趣,可以查看一下汇编代码,就能看出来调用doPrint是从虚函数表中得到函数地址的。

博主何海涛对本博客文章享有版权。网络转载请注明出处http://blog.csdn.net/cadcisdhht。整理出版物请和作者联系。有任何建议或意见,欢迎在评论中告知,或者加我微博http://weibo.com/zhedahht与我交流。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: