• C++面试题3


    第3课 - 外企笔试题精选一

    1. 下面的代码输出是什么?为什么?

    #include<iostream>

    #include<malloc.h>

    using namespace std;

    class A

    {

    private:

             static int c_count;

    public:

             A()

             {

                       c_count++;

    }

    ~A()

             {

                       c_count--;

    }

             static void Count()

             {

                       cout<<c_count<<endl;

    }

    };

    Int A::c_count = 0;

    int main()

    {

             A* a=static_cast<A*>(malloc(sizeof(A)));

             a->Count();

             delete a;

             a->Count();

             return 0;

    }

    运行结果:

    0

    -1

    分析:

             本题考查静态成员的使用和构造函数的使用。在使用中构造函数没用被调用,malloc只会在内存中申请一段内存,不会对这段内存做任何解释,也就是a只是指向堆空间中的一段内存但是并没有指向堆空间的对象,构造函数没有被调用。理论上我们使用new()才是正确。delete a;会调用析构函数,使得最后结构是-1。但是由于a没有明确指向一段对象,a就是一个野指针,c++中的静态成员在使用的时候可以看成只是引用了类型而忽略了对象,a->count();等价为A::Count();即使a是野指针也不会耽误程序的使用。

             这里也强调在c++中,我们要尽可能的使用new,delete函数,少使用malloc,free函数。它们的区别在于new在堆空间申请内存时会主动调用构造函数,delete在堆空间释放内存时会主动调用析构函数。

    1. 下面的代码输出是什么?为什么?

    class A

    {

    public:

             virtual void test(int i)

             {

             cout<<”A::test”<<i<<endl;

    }

    void test()

    {

             cout<<”A::test”<<endl;

    }

    };

    class B:public A

    {

    public:

             void test(double i)

             {

                       cout<<”B::test”<<i<<endl;

    }

    };

    int main()

    {

             A* a = new B();

             B* b = new B();

             a->test(5);

             a->test(5);

             return 0;

    }

    运行结果:

             A::test5

             B::test5

             多态发生在子类和基类之间,函数声明必须完全一样。重载必须发生在同一个作用域之间。本题中子类和基类之间的函数参数值一个是int一个是double,是不一样的,不能发生多态。不发生多态,就发生了隐藏和覆盖。

    1. 下面描述正确的是()
    2. 面向对象编程需要面向对象语言的支持,如Java和C++等。
    3. 封装,继承和多态是面向对象的基本特征。
    4. 继承是面向对象中代码复用的唯一方式
    5. 多态的工作方式与重载相同

    选择:B

             面向对象是一种思想,是一种编程的方法学,与编程语言没有关系,Java和C++只是增加了对面向对象的支持,面向程序C语言同样可以支持面向对象编程;继承是面向对象中代码复用的方式之一,包括组合;多态发成在子类与父类之间,重载发生在同一个作用域之间。

    1. 下面的代码输出是什么?为什么?

    class A

    {

    private:

             int i;

    public:

             virtual void test()

             {

                       cout<<”A::test”<<endl;

    }

    };

    class B:public A

    {

    private:

             int i;

    public:

             void test()

             {

                       cout<<”B::test”<<endl;

    }

    };

    void f(A* p, int len)

    {

             for(int i = 0;i<len;i++)

             {

                       p[i].test();

    }

    }

    int main()

    {

             B b[3];

             f(b,3);

             return 0;

    }

    运行;B::test之后卡死,段错误。

    分析:

             t[i]是等价于*(t+i)的,指针运算就是地址的运算,是在编译的时候进行地址寻找的,t+i等价于 (unsigned int)t + i*sizeof(Type)。B是继承A的,也就是说sizeof(B)肯定是大于sizeof(A)的。p[i].test()等价于(p+i).test(),void f(A* p, int len)是按A的格式进行输入的,只有第一个位置是合理的,指针在移动的过程中无法指引B的整数位置,发生段错误。

             在数组上不要使用多态的使用,数组就是指针,也就是指针和多态不要一起使用。

    1. 下面描述正确的是()
    2. 一个应用程序启动后成为一个进程
    3. 进程是操作系统分配资源的基本单位
    4. 一个进程中可以创建多个线程,每个线程都共享进程的资源
    5. 操作系统可以在创建进程的时候不创建任何一个线程

    答案选:ABC,每一个进程至少包含一个线程,线程就是我们C语言中的main()函数,main()函数在运行的过程中可以调用其他的线程。

    1. 下面程序的输出是什么?为什么?

    class A

    {

    private:

             static int i;

    public:

             A()

             {

             i++;

    }

    A(const A&)

             {

             i++;

    }

    static void output()

    {

             cout<<i<<endl;

    }

    };

    A f(A& a)

    {

             A aa = a;

             return a;

    }

    int A::I = 0;

    int main()

    {

             A a;

             f(a).output();

             return 0;

    }

    运行结果:3

    分析:

    静态成员在使用的时候可以看成只是引用了类型而忽略了对象。A a;调用一次构造函数,f(a)将a地址传入,在函数内部A aa = a;调用第二次构造函数,return a;将a赋值给返回值对象,也就是临时对象,第三次使用构造函数。

             这里涉及在C语言中,函数是如何调用的。

    1. 下面程序输出是什么?为什么?

    #include<iostream>

    using namespace std;

    #define FUNC(a,b) a = a+b;

                                         b = a-b;

                                         a = a-b

    int main()

    {

             int a = 3;

             int b = 4;

             if(a>b) FUNC(a,b);

             cout<<a<<” ”<<bendl;

    }

    运行结果:4  -1

    分析:宏是直接的文本替换,没有括号,执行b = a-b; a = a-b,a=4, b=-1;

    为了及时改错,可以改成:

    #define FUNC(a,b) do{

    a = a+b;

    b = a-b;

    a = a-b;

    while(0)

    1. Telnet协议是基于下面哪种协议开发而来的()
    2. TCP
    3. UDP
    4. TCP and UDP
    5. none of above

    答案选:A

    1. Please choose the correct options for the ISR below:()

    interrupt double service(double p)

    {

             Return p*p;

    }

    1. ISR function should not return any value, service() cannot be used as a ISR.
    2. ISR function should not accept any parameter, service() annot be used as a ISR.
    3. service() is a valid ISR
    4. none of above

    答案选:AB

    中断服务程序不能有返回值;中断服务程序不能有参数;中断服务程序中不能有浮点运算;中断服务程序里面不能有printf函数。

    1. 有一组整型数,其中除了2个数字以外的其他数字都是两两成对出现的,编写程序找出这2个不成对出现的数字。

    函数原型: 

    void search_diff(int array[],int len,int* pa,int* pb);

    示例:

    void search_diff(int array[],int len,int* pa,int* pb);

    int a = 0;

    int b = 0;

    int array[]={3,4,5,5,3,4,1,6,6,7,2,8,7,8};

    search_diff(array,sizeof(a)/sizeof(*a),&a,&b);//调用后a,b为1,2或者a,b为2,1

    #include <iostream>

    #include <malloc.h>

    using namespace std;

    int first_one_bit(unsigned int v)

    {

        int ret = 0;

       

        while( (v != 0) && ((v & 1) == 0) )

        {

            v = v >> 1;

            ret++;

        }

       

        return ret;

    }

    void search_diff(int array[], int len, int* pa, int* pb)

    {

        if( (array != NULL) && (pa != NULL) && (pb != NULL) )

        {

            int r = 0;

            int flag = 0;

           

            for(int i=0; i<len; i++)

            {

                r = r ^ array[i];

            }

           

            flag = 1 << first_one_bit(r);

           

            *pa = 0;

            *pb = 0;

           

            for(int i=0; i<len; i++)

            {

                if( array[i] & flag )

                {

                    *pa = *pa ^ array[i];

                }

                else

                {

                    *pb = *pb ^ array[i];

                }

            }

        }

    }

    int main()

    {

             int a = 0;

             int b = 0;

             int array[] = {3, 4, 5, 5, 3, 4, 1, 6, 6, 7, 2, 8, 7, 8};

        search_diff(array, sizeof(array)/sizeof(*array), &a, &b);

            

             cout<<a<<" "<<b<<endl;

    }

    1. 打印一个N*N的矩阵,从首坐标(0,0)开始顺时针依次增大。

    示例:5*5矩阵,其中数字1的坐标为(0,0)

    1 2 3 4 5

    16 17 18 19 6

    15 24 25 20 7

    14 23 22 21 8

    13 12 11 10 9

    程序:#include <iostream>

    #include <malloc.h>

    using namespace std;

    template <int N>

    class SpinMatrix

    {

    private:

        int m_matrix[N][N];

       

        struct Offset

        {

            int dx;

            int dy;

        };

       

        bool valid(int x, int y);

    public:

        SpinMatrix();

        void run();

        void println();

        int scale();

    };

    template <int N>

    SpinMatrix<N>::SpinMatrix()

    {

        for(int i=0; i<N; i++)

        {

            for(int j=0; j<N; j++)

            {

                m_matrix[i][j] = 0;

            }

        }

    }

    template <int N>

    bool SpinMatrix<N>::valid(int x, int y)

    {

        bool ret = true;

       

        ret = ret && ((0 <= x) && (x < N));

        ret = ret && ((0 <= y) && (y < N));

        ret = ret && (m_matrix[x][y] == 0);

       

        return ret;

    }

    template <int N>

    void SpinMatrix<N>::run()

    {

        const Offset OFFSET[] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};

        const int OSLEN = sizeof(OFFSET) / sizeof(*OFFSET);

        int cx = 0;

        int cy = 0;

        int cd = 0;

        int i = 1;

       

        do

        {

            m_matrix[cx][cy] = i;

           

            if( !valid(cx + OFFSET[cd].dx, cy + OFFSET[cd].dy) )

            {

                cd = (cd + 1) % OSLEN;

            }

           

            cx += OFFSET[cd].dx;

            cy += OFFSET[cd].dy;

           

            i++;

        } while ( i <= N*N );

    }

    template <int N>

    void SpinMatrix<N>::println()

    {

        for(int i=0; i<N; i++)

        {

            for(int j=0; j<N; j++)

            {

                cout<<m_matrix[i][j]<<' ';

            }

           

            cout<<endl;

        }

       

        cout<<endl;

    }

    template <int N>

    int SpinMatrix<N>::scale()

    {

        return N;

    }

    int main()

    {

        SpinMatrix<3> sm1;

        SpinMatrix<4> sm2;

       

        cout<<"3 * 3: "<<endl;

       

        sm1.run();

        sm1.println();

       

        cout<<"4 * 4: "<<endl;

       

        sm2.run();

        sm2.println();

    }

  • 相关阅读:
    qs.stringify() 和JSON.stringify()的区别 飞鸟和蝉
    js随机数, 范围随机数 飞鸟和蝉
    VUECLI 4的跨域解决方案
    vue3elementadmin
    English dedicate 致力 题献
    解决java web项目导入后出现的问题 cannot be read or is not a valid ZIP file
    SQL 优化原则(转)
    Java Spring Error : Bean property '*****' is not writable or has an invalid setter method.
    c++面试题:#define MIN(A,B) ( (A) <= (B) ? (A) : (B) )
    freemark list 循环变量类型错误问题
  • 原文地址:https://www.cnblogs.com/free-1122/p/11341956.html
Copyright © 2020-2023  润新知