注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

微软、Google等面试题

剑指Offer:名企面试官精讲典型编程题

 
 
 

日志

 
 

程序员面试题精选100题(54)-C++/C#面试题(3)  

2011-02-16 21:59:02|  分类: C/C++ |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

写在前面的话:本次选用的5道题,是我微博(http://weibo.com/zhedahhthttp://t.163.com/zhedahht)中#面试每日一题#系列的第11题到第15题。有合适的题目,我会继续收集C/C++/C#的面试题,并不定期发表到博客和大家分享。

题目(11运行下图中的C#代码,输出是什么?

namespace StringValueOrReference

{

    class Program

    {

        internal static void ValueOrReference(Type type)

        {

            String result = "The type " + type.Name;

 

            if (type.IsValueType)

                Console.WriteLine(result + " is a value type.");

            else

                Console.WriteLine(result + " is a reference type.");

        }

 

        internal static void ModifyString(String text)

        {

            text = "world";

        }

 

        static void Main(string[] args)

        {

            String text = "hello";

 

            ValueOrReference(text.GetType());

            ModifyString(text);

 

            Console.WriteLine(text);

        }

    }

}

答案:输出两行。第一行是The type String is reference type. 第二行是hello。类型String的定义是public sealed class String {...},既然是class,那么String就是引用类型

在方法ModifyString里,对text赋值一个新的字符串,此时改变的不是原来text的内容,而是把text指向一个新的字符串"world"。由于参数text没有加ref或者out,出了方法之后,text还是指向原来的字符串,因此输出仍然是"hello".

题目(12:运行下图中的C++代码,输出是什么

#include <iostream>

 

class A

{

private:

        int n1;

        int n2;

public:

        A(): n2(0), n1(n2 + 2)

        {

        }

 

        void Print()

        {

                std::cout << "n1: " << n1 << ", n2: " << n2 << std::endl;

        }

};

 

int _tmain(int argc, _TCHAR* argv[])

{

        A a;

        a.Print();

 

        return 0;

}

答案:输出n1是一个随机的数字,n20。在C++中,成员变量的初始化顺序与变量在类型中的申明顺序相同,而与它们在构造函数的初始化列表中的顺序无关。因此在这道题中,会首先初始化n1,而初始n1的参数n2还没有初始化,是一个随机值,因此n1就是一个随机值。初始化n2时,根据参数0对其初始化,故n2=0

题目(13编译运行下图中的C++代码,结果是什么?(A)编译错误;(B)编译成功,运行时程序崩溃;(C)编译运行正常,输出10。请选择正确答案并分析原因

#include <iostream>

 

class A

{

private:

        int value;

 

public:

        A(int n)

        {

                value = n;

        }

 

        A(A other)

        {

                value = other.value;

        }

 

        void Print()

        {

                std::cout << value << std::endl;

        }

};

 

int _tmain(int argc, _TCHAR* argv[])

{

        A a = 10;

        A b = a;

        b.Print();

 

        return 0;

}

答案:编译错误。在复制构造函数中传入的参数是A的一个实例。由于是传值,把形参拷贝到实参会调用复制构造函数。因此如果允许复制构造函数传值,那么会形成永无休止的递归并造成栈溢出。因此C++的标准不允许复制构造函数传值参数,而必须是传引用或者常量引用。在Visual StudioGCC中,都将编译出错。

题目(14运行下图中的C++代码,输出是什么

int SizeOf(char pString[])

{

        return sizeof(pString);

}

 

int _tmain(int argc, _TCHAR* argv[])

{

        char* pString1 = "google";

        int size1 = sizeof(pString1);

        int size2 = sizeof(*pString1);

 

        char pString2[100] = "google";

        int size3 = sizeof(pString2);

        int size4 = SizeOf(pString2);

 

        printf("%d, %d, %d, %d", size1, size2, size3, size4);

 

        return 0;

}

答案4, 1, 100, 4pString1是一个指针。在32位机器上,任意指针都占4个字节的空间。*pString1是字符串pString1的第一个字符。一个字符占一个字节。pString2是一个数组,sizeof(pString2)是求数组的大小。这个数组包含100个字符,因此大小是100个字节。而在函数SizeOf中,虽然传入的参数是一个字符数组,当数组作为函数的参数进行传递时,数组就自动退化为同类型的指针。因此size4也是一个指针的大小,为4.

题目(15:运行下图中代码,输出的结果是什么?这段代码有什么问题

#include <iostream>

 

class A

{

public:

        A()

        {

                std::cout << "A is created." << std::endl;

        }

 

        ~A()

        {

                std::cout << "A is deleted." << std::endl;

        }

};

 

class B : public A

{

public:

        B()

        {

                std::cout << "B is created." << std::endl;

        }

 

        ~B()

        {

                std::cout << "B is deleted." << std::endl;

        }

};

 

int _tmain(int argc, _TCHAR* argv[])

{

        A* pA = new B();

        delete pA;

 

        return 0;

}

答案:输出三行,分别是:A is created. B is created. A is deleted。用new创建B时,回调用B的构造函数。在调用B的构造函数的时候,会先调用A的构造函数。因此先输出A is created. B is created.

接下来运行delete语句时,会调用析构函数。由于pA被声明成类型A的指针,同时基类A的析构函数没有标上virtual,因此只有A的析构函数被调用到,而不会调用B的析构函数。

由于pA实际上是指向一个B的实例的指针,但在析构的时候只调用了基类A的析构函数,却没有调用B的析构函数。这就是一个问题。如果在类型B中创建了一些资源,比如文件句柄、内存等,在这种情况下都得不到释放,从而导致资源泄漏。

 

博主何海涛对本博客文章享有著作权。网络转载请注明出处http://zhedahht.blog.163.com/。整理出版物请和作者联系。

  评论这张
 
阅读(33674)| 评论(18)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017