自己可能用到的笔试面试题(整理C/C++)

一、整理来自http://zhedahht.blog.163.com/

1、运行下图中的C++代码,打印出的结果是什么?

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”)都将被忽略。

2、运行下面的C++代码,打印的结果是什么?

class Base
{
public:
    void print() { 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是从虚函数表中得到函数地址的。

 

3、运行如下的C++代码,输出是什么?

class A
{
public:
    virtual void Fun(int number = 10)
    {
        std::cout << "A::Fun with number " << number;
    }
};
class B: public A
{
public:
    virtual void Fun(int number = 20)
    {
        std::cout << "B::Fun with number " << number;
    }
};
int main()

{   B b;
    A &a = b;
    a.Fun();
}


 

答案输出B::Fun with number 10。由于a是一个指向B实例的引用,因此在运行的时候会调用B::Fun。但缺省参数是在编译期决定的。在编译的时候,编译器只知道a是一个类型a的引用,具体指向什么类型在编译期是不能确定的,因此会按照A::Fun的声明把缺省参数number设为10

            这一题的关键在于理解确定缺省参数的值是在编译的时候,但确定引用、指针的虚函数调用哪个类型的函数是在运行的时候。

4、运行如下的C代码,输出是什么?

char* GetString1()
{
    char p[] = "Hello World";
    return p;
}
 
char* GetString2()
{
    char *p = "Hello World";
    return p;
}
int _tmain(int argc, _TCHAR* argv[])
{
    printf("GetString1 returns: %s. \n", GetString1());
    printf("GetString2 returns: %s. \n", GetString2());
    return 0;
}


 

答案输出两行,第一行GetString1 returns: 后面跟的是一串随机的内容,而第二行GetString2 returns: Hello World. 两个函数的区别在于GetString1中是一个数组,而GetString2中是一个指针

当运行到GetString1时,p是一个数组,会开辟一块内存,并拷贝"Hello World"初始化该数组。接着返回数组的首地址并退出该函数。由于pGetString1内的一个局部变量,当运行到这个函数外面的时候,这个数组的内存会被释放掉。因此在_tmain函数里再去访问这个数组的内容时,结果是随机的

当运行到GetString2时,p是一个指针,它指向的是字符串常量区的一个常量字符串。该常量字符串是一个全局的,并不会因为退出函数GetString2而被释放掉。因此在_tmain中仍然根据GetString2返回的地址得到字符串"Hello World"

5、运行下图中C代码,输出的结果是什么

int _tmain(int argc, _TCHAR* argv[])
{
    char str1[] = "hello world";
    char str2[] = "hello world";
    char* str3 = "hello world";
    char* str4 = "hello world";
    if(str1 == str2)
        printf("str1 and str2 are same.\n");
    else
        printf("str1 and str2 are not same.\n");
    if(str3 == str4)
        printf("str3 and str4 are same.\n");
    else
        printf("str3 and str4 are not same.\n");
    return 0;
}


 

答案输出两行。第一行是str1 and str2 are not same,第二行是str3 and str4 are same

str1str2是两个字符串数组。我们会为它们分配两个长度为12个字节的空间,并把"hello world"的内容分别拷贝到数组中去。这是两个初始地址不同的数组,因此比较str1str2的值,会不相同str3str4是两个指针,我们无需为它们分配内存以存储字符串的内容,而只需要把它们指向"hello world“在内存中的地址就可以了。由于"hello world”是常量字符串,它在内存中只有一个拷贝,因此str3str4指向的是同一个地址。因此比较str3str4的值,会是相同的

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值