下面的代码输出什么?为什么?
#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

说明:

A* a = static_cast<A*>(malloc(sizeof(A)));  // a 仅指向堆空间中A对象大小的内存, malloc 仅负责内存申请,不会触发构造函数的调用
a->Count();                                 // 输出 0
delete a;                                   // 析构函数被调用 , 此时 a 成为野指针
a->Count();                                 // 但是这里为什么没有运行崩溃呢?
 
因为,在C++中调用静态成员时,只使用对象类型,而不使用具体的对象
a->Count(); ==> A::Count() 

参考:
关于 new malloc free delete 的疑问


下面的程序输出什么?为什么?
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);
    b->test(5);
    
    return 0;
}

输出:

cout<<"A::test"<<5<<endl;  // 注意这里的输出,没有发生多态行为
cout<<"B::test"<<5<<endl;

说明:

多态发生的条件:发生在派生类与基类之间;函数签名必须完全一致;

题目中派生类与基类的同名成员函数参数列表不同,仅发生同名隐藏

参考:
父子间的冲突


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

答案: 【B】
说明:

A. 面向对象是软件设计思想,与编程语言无关。面向对象语言仅是加入了对面向对象概念的原生支持
C. 继承,组合
D. 重载,静态联编,编译器确定调用关系,发生在同一作用域中; 多态,动态联编,运行时确定调用关系,发生在有继承关系的类之间

下面的代码输出什么?为什么?
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;
}

输出:

cout<<"B::test"<<endl;
断错误

说明:

1 .void test(); 将发生多态行为,第一次打印正常输出

2. 在题目的函数调用中,void f(A* p, int len);p 将指向子类对象

3. 指针运算时(编译期确定):
    Type t[N]
    t[i]  <==> *(t + i)  
    t + i <==> (unsigned int)t + i * sizeof(Type)
    
4. 指针 p 指向的类型为 A,指针运算时的步长为 sizeof(A)

5. class A 与 class B 为继承关系, 因此 sizeof(B) > Sizeof(A)

clipboard.png


下面描述正确的是?
A. 一个应用程序启动后成为一个进程
B. 进程是操作系统资源分配的基本单位
C. 一个进程可以创建多个线程,每个线程都共享进程的资源
D. 操作系统可以在创建进程的时候不创建任何一个线程

答案:【A B C】


下面程序输出什么?为什么?
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;
}

输出:

i = 3 

说明:

第一次 i++ : A a;
第二次 i++ : A aa = a;
第三次 i++ : return a; // a 初始化一个临时对象用于返回

下面的程序输出什么?为什么?
#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<<" "<<b<<endl;
}

输出:

4 -1

说明:

宏的副作用之一,仅进行简单的文本替换

if(a > b) FUNC(a, b); ==>
if(a > b)
    a = a + b; 
    
    b = a - b;
    a = a - b

Telnet 协议是基于下面哪种协议开发而来的?
A. TCP
B. UDP
C. TCP and UDP
D. None of above

答案:【A】


Please choose the correct option for the ISR below:()
interrupt double service(double p)
{
    return p*p;
}
A. ISR function should not return any value, service() cannot be used as a ISR
B. ISR function should not accept any parameter, service() cannot be used as a ISR
C. Servica() is a valid ISR
D. None of above

答案:【A B】
说明:

中断服务程序需要遵循的规则:
1. 中断服务程序不能有返回值
2. 中断服务程序不能有参数
3. 中断服务程序里面不要有浮点运算
4. 中断服务程序中不应有 printf 等不可重入的函数

有一组整型数,其中除了 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(array)/sizeof(*array), &a, &b); //调用后 a,b 为 1,2 或者 a,b 为
2,1
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];
            }
        }
    }
}

打印一个 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
template <int N>
class SpinMatrix
{
private:
    int m_matrix[N][N];

    struct Offset
    {
        int dx;
        int dy;
    };

    bool isValid(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>::isValid(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( !isValid(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] << '\t';
        }
        cout << endl;
    }
    cout << endl;
}

template <int N>
int SpinMatrix<N>::scale()
{
   return N;
}

TianSong
734 声望138 粉丝

阿里山神木的种子在3000年前已经埋下,今天不过是看到当年注定的结果,为了未来的自己,今天就埋下一颗好种子吧