Class A;
Class B;
void F() {
A a;
B b;
}
在函数F中,本地变量a和b的构造函数(constructor)和析构函数(destructor)的调用顺序是:
A b构造 a构造 a析构 b析构
B a构造 a析构 b构造 b析构
C b构造 a构造 b析构 a析构
D a构造 b构造 b析构 a析构
D
按变量声明顺序构造对象,然后入栈
按相反顺序出栈,析构对象。
假定指针变量p定义为“int *p=new int(100);”,要释放p所指向的动态内存,应使用语句( )
A delete p;
B delete *p;
C delete &p;
D delete []p;
A
选择填空:
#include
void test(void *data) {
unsigned int value = (此处应填入)
printf("%u", value);
}
using namespace std;
int main() {
unsigned int value = 10;
test(&value);
return 0;
}
A *data
B (unsigned int)(*data)
C (unsigned*)data
D *((unsigned int *)data)
D
解释:
<span class="kwd" style="color: rgb(0, 0, 136);">void<span class="pln" style="color: rgb(0, 0, 0);">
注意,参数类型是void, 所以先要进行指针转换:(unsigned int *)然后再取值。
在C++, 下列哪一个可以做为对象继承之间的转换
A static_cast
B dynamic_cast
C const_cast
D reinterpret_cast
B
dynamic_cast 动态转换
如果进栈序列为e1,e2,e3,e4,则不可能的出栈序列是( )
A e2,e4,e3,e1
B e4,e3,e2,e1
C e1,e2,e3,e4
D e3,e1,e4,e2
D
如果e3第一个出栈,拿下一个应该是e4或者e2,但绝不可能是e1
若某二叉树的前序遍历访问顺序是abdgcefh,中序遍历访问顺序是dgbaechf,则其后序遍历的结点访问顺序是( )
A gdbehfca
B hcdeabf
C fdcehgba
D gdbehcfa
A
根据前序和中序序列画出二叉树的结构,写出其后序序列即可。
用二分法查找长度为10的、排好序的线性表,查找不成功时,最多需要比较多少次?
A 3
B 4
C 5
D 6
B
8<10<16,而log16=4
以下程序是用辗转相除法来计算两个非负数之间的最大公约数:
long long gcd(long long x, long long y) {
if (y == 0)
return x;
else
return gcd(y, x % y);
}
我们假设x,y中最大的那个数的长度为n,x>y,基本运算时间复杂度为O(1),那么该程序的时间复杂度为( )
A O(1)
B O(logy)
C O(n)
D O(x)
求最大公约数的最常用的算法是欧几里得算法,也称为辗转相除法.
问题定义为求i和j的最大公约数gcd(i,j),其中i和j是整数,不妨设i>j.
算法可以递归的表示:
1.如果j能整除i,那么gcd(i,j)=j;
2.j不能整除i,令r=i%j,那么gcd(i,j)=gcd(j,r).
使用C语言实现:
int gcd(int i, int j)
{
int r = i % j;
return r == 0 ? j : gcd(j, r);
}
正确性分析:
算法的步骤1,显然成立(最大公约数定义).关键是要证明步骤2.
设d是i和j的最大公约数,
那么i=md,j=nd,m和n互质(否则d不是最大公约数).
由r=i%j可以得到i=kj+r,k=⌊m/n⌋,k≥1(我们前面假设过i>j).
把i=md,j=nd代入得到
md=knd+r
那么
r=(m-kn)d
m-kn和m也是互质的.
所以得到d是j和r的最大公约数.
时间复杂度分析:
逆着看该算法,最后的余数是0,倒数第二次余数是d,倒数第三次是kd,k>1…
由于组成了一个数列,{0,d,kd,nkd+d,…}
数列的n项加上n+1项,比n+2项要小,所以比斐波纳契数列增长的要快.
我们已知斐波纳契数列增长速度是指数,那么待分析的数列也是指数增长.
设欧几里得算法需要k次,那么j=O(2^k),则k=O(lg j).
所以欧几里得算法求最大公约数的时间复杂度是对数量级的,速度非常快.
一棵有124个叶节点的完全二叉树,最多有( )个节点。
A 247
B 248
C 249
D 250
B
n0 = n2 + 1,于是度为2的结点个数123个 完全二叉树中度为1结点个数最多1个 因此该完全二叉树中结点最多有123 + 1 + 124 = 248个
链表不具备的特点是( )
A 可随机访问任何一个元素
B 插入、删除操作不需要移动元素
C 无需事先估计存储空间大小
D 所需存储空间与线性表长度成正比
A
不同于寻秩访问的数组,链表无法实现随机访问任何一个元素O(1), 访问时需要遍历链表直到访问到该元素。
下列排序算法中,在待排序数据有序的情况下,花费时间最多的是( )
A 快速排序
B 希尔排序
C 冒泡排序
D 堆排序
A
待排序数据有序就是快排的最差情况,此时的时间复杂度是O(n 2 )
有 1000 个无序的整数,希望使用最快的方式找出前 50 个最大的,最佳的选择是( )
A 冒泡排序
B 基数排序
C 堆排序
D 快速排序
C
找出若干个数中最大/最小的前K个数,用堆排序是最好的
找最大数,用小根堆
找最小数,用大根堆
下面哪个不是用来解决哈希表冲突的开放地址法?
A 线性探测法
B 线性补偿探测法
C 拉链探测法
D 随机探测法
C
拉链探测法,开放定址法区分为线性探查法、线性补偿探测法、随机探测等。
下列数最大的是( )。括号内为数字,括号外为进制。
A (10010101)2
B (227)8
C (96)16
D (143)10
B
在CPU和内存之间增加cache的作用是( )
A 提高内存稳定性
B 解决内存速度低于CPU的性能问题
C 增加内存容量
D 增加内存容量且加快存取速度
B
这是存储器分层部分的内容,可以参考《深入理解计算机系统》
假设整数0x12345678 存放在内存地址0x0开始的连续四个字节中 (即地址0x0到 0x3). 那么在以Little Endian字节序存储的memory中,地址0x3的地方存放的字节是:
A 0x12
B 0x34
C 0x56
D 0x78
A
a) Little-Endian就是低位字节排放在内存的低地址端, 高位字节排放在内存的高地址端。
b) Big-Endian就是高位字节排放在内存的低地址端,低位字节排放在内存的高地址端。
c) 网络字节序:TCP/IP各层协议将字节序定义为Big-Endian,因此TCP/IP协议中使用的字节序通常称之为网络字节序。
如果是 Little-Endian:0x0-0x3内存分别存放的是:0x78、0x56、0x34、0x12;
如果是 Big-Endian :0x0-0x3内存分别存放的是:0x12、0x34、0x56、0x78;
将逻辑代码:
if (x % 2) {
return x - 1;
} else {
return x;
}
用表达式:return x & -2; 替代,以下说法中不正确的是( )
A 计算机的补码表示使得两段代码等价
B 用第二段代码执行起来会更快一些
C 这段代码只适用于x为正数的情况
D 第一段代码更适合阅读
C
代码生成阶段的主要任务是( )
A 把高级语言翻译成汇编语言
B 把高级语言翻译成机器语言
C 把中间代码变换成依赖具体机器的目标代码
D 把汇编语言翻译成机器语言
C
编译程序的工作过程一般划分为五个阶段:词法分析、语法分析、语义分析与中间代码产生、优化、目标代码生成。所以选C 。
后缀式 ab+cd+/可用表达式( )来表示
A a+b/c+d
B (a+b)/c+d
C a+b/(c+d)
D (a+b)/(c+d)
D
后缀表达式不包含括号,运算符放在两个运算对象的后面,所有的计算按运算符出现的顺序,严格从左向右进行,不再考虑运算符的优先规则。
最后一个操作是'/',而且前面是一个+操作,后面没有操作,可知/操作最后进行,由此可得,另外两个操作数是a+b和c+d,因此表达式为D (a+b)/(c+d)
以下关于函数调用的说法哪个是正确的?
A 传值后对形参的修改会改变实参的值
B 传地址后实参和形参指向不同的对象
C 传引用后形参和实参是不同的对象
D 以上都不对
D
解释:传地址和传引用,形参,实参指向同一对象,修改形参会影响实参
传值则相反,修改形参不会影响实参