乐趣区

【笔试题精选】_3

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

下面描述正确的是?
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;
}

退出移动版