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

来源:互联网 发布:数据库管理员前景 编辑:程序博客网 时间:2024/05/29 08:25
一、整理来自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的值,会是相同的

 

 

 

 

原创粉丝点击