1.
typedef struct list_t{
struct list_t *next;
struct list_t *prev;
char data[0];
}list_t;
请问在32位系统中,sizeof(list_t)的值为?
答案【8byte】
解析:用作定义时char[0]是空数组,是不占空间的。
2.C++是不是类型安全的?
答案【不是】
解析:如果规定两种不同类型之间必须通过显示转换则是安全的。
3.代码可以通过编译吗?如果不能应该如何修改?
template<class T> class Foo{
T tVar;
public:
Foo(T t) : tVar(t) { }
};
template<class T> class FooDerived:public Foo<T>
{
};
int main()
{
FooDerived<int> d(5);
return 0;
}
- A 代码可以正确通过编译。
- B 编译错误,FooDerived是一个继承模板类的非模板类,它的类型不能改变。
- C 编译错误,tVal变量是一个不确定的类型。
D 编译错误,可以在FooDerived类中添加一个构造函数解决问题。
答案【D】
解析:父类定义了带参数的构造函数,如果子类没有显示调用父类的构造方法,则默认调用父类的默认构造函数,于是这里默认构造函数消失了,子类需要显示调用父类的构造方法。
4.观察下面一段代码:
class ClassA
{
public:
virtual ~ ClassA(){};
virtual void FunctionA(){};
};
class ClassB
{
public:
virtual void FunctionB(){};
};
class ClassC : public ClassA,public ClassB
{
public:
};
ClassC aObject;
ClassA* pA=&aObject;
ClassB* pB=&aObject;
ClassC* pC=&aObject;
关于pA,pB,pC的取值,下面的描述中正确的是:
- A pA,pB,pC的取值相同
- B pC=pA+pB
- C pA和pB不相同
D pC不等于pA也不等于pB
答案【C】
解析 :aObject的地址从A的虚函数表开始,然后到B的虚函数表,再到C自身的成员
5.随着装填因子a的增大,用闭哈希法解决冲突,其平均搜索长度比用开哈希法解决冲突时的平均搜索长度增长得慢()【错】
- 开哈希表——-链式地址法
- 闭哈希表——-开放地址法
开哈希只会和相同值发生冲突,而闭哈希除了与相同值发生冲突,还会与不同值发生冲突 ;开哈希不受密度影响,而闭哈希受密度影响 。
6.下列叙述中错误的是( )
- A 二叉链表是二叉树的存储结构
- B 循环链表是循环队列的存储结构
- C 栈是线性结构
D 循环队列是队列的存储结构
答案【B】
BD.队列两种存储方式:循环队列和链队列
C.栈是一种特殊存取方式的线性表。
7.下面程序会输出什么:
static int a=1; //静态全局变量
void fun1(void)
{
a=2; //访问全局变量,改变值
}
void fun2(void)
{
int a=3; //定义一个局部变量,函数结束销毁
}
void fun3(void)
{
static int a=4; //静态局部变量,函数结束仍存在,但别的函数不能引用它
}
int main()
{
printf(“%d”,a); //首次输出,a = 1
fun1( ); //修改a的值
printf(“%d”,a); //输出2
fun2( ); //没有改变全局变量a的值
printf(“%d”,a); //输出2
fun3( ); //一个新的变量,a,与printf的a并不是一个东西
printf(“%d”,a); //输出2
}
答案【1 2 2 2】
解析见注释部分
8.下面代码的输出结果是()
int main(){
int pid;
int num=1;
pid=fork();
if(pid>0){
num++;
printf("in parent:num:%d addr:%x\n",num,&num);
}
else if(pid==0){
printf("in child:num:%d addr:%x\n",num,&num);
}
}
答案【父子进程中输出的num不同,num地址相同】
解析:num不同比较好理解,num地址相同指的是虚拟地址相同,Linux中的资源分配都是虚拟机制,也就是说,他们还是会共用一个虚拟的地址,但是映射到物理内存就可能会不一样。
其实刚刚fork出来不止虚拟地址一样,物理地址也一样。当进程发生分歧时,即修改此变量时,才会分配不同的物理地址,也就是copy-on-write,写时复制。
9.线索化二叉树:左指针为空->指前驱;右指针为空->指后继
10.下列代码的输出结果是
int i = -1;
unsigned j = 1;
if (j > i)
printf(" (j>i)成立\n");
else
printf(" (j>i)不成立\n");
if (i < j)
printf(" (i<j)成立\n");
else
printf(" (i<j)不成立\n");
答案【(j>i)不成立,(i\<\j)不成立】
表达式会包含隐式类型转换,它由编译器自动执行,不需程序员介入。
转换规则见小海豹的解析
转换之后 signed int 被转换为unsigned int,以8字节为例,-1是11111111,比1大
11.如下语句通过算术运算和逻辑运算之后 i 和 j 的结果是()
【短路原则】
int i=0;
int j=0;
if((++i>0)||(++j>0))
{
/打印出i和j的值。
}
答案【i = 1;j = 0】
解析:先执行++i,此时i变为1,然后判断i>0为真。短路原则(||)不会计算后面的条件,因此++j不执行,j==0
12.关键字
【待补充】
13.下列代码编译时会产生错误的是()
#include <iostream>
using namespace std;
struct Foo {
Foo() {}
Foo(int) {}
void fun() {}
};
int main(void) {
Foo a(10); //语句1
a.fun(); //语句2
Foo b(); //语句3
b.fun(); //语句4
return 0;
16.
}
答案【语句4】
解析:语句4出错来自语句3,Foo b()会被编译器认为声明了一个函数,正确的构造函数应该是Foo b;