T 笔试题精选 (一)

笔试题精选一

该笔试题对于C/C++的基础细节比较重视。

1、 32 位机上根据下面的代码,问哪些说法是正确的? ( )
signed char a = 0xe0;
unsigned int b = a;
unsigned char c = a;
A. a>0 && c>0 为真
B. a == c 为真
C. b 的十六进制表示是:0xffffffe0
D. 上面都不对

解析:答案:C。变量a为有符号字符型变量,最高位为符号位,符号位为1,所以a<0。用a为c赋值,c为无符号字符型变量,最高位不是符号位,c>0,a为-32,c为224,因此a不等于c,AB选项都不对。用a为b赋值,b为无符号整形变量,使用a的符号位补充b中的高位3个字节,用带符号字符型给无符号整型赋值,高位补符号位,因此C选项正确。数据类型的

2、 下面哪些选项能编译通过? ( )
int i;
char a[10];
string f();
string g(string & str);
A. if(!!i){f();}
B. g(f());
C. a=a+1;
D. g(“abc”);

解析:答案:A。在BCD三个选项中,B中在C++中只有const引用才能被临时变量或临时对象所初始化,函数的返回值都是临时变量,f()函数的返回值为临时变量,只能赋值给const引用,B错误,如果有一个已定义的string变量a,令a = f(); 然后g(a); 这样就对了。C肯定不对,C中a为数组名,a可以加1,但是不能直接给数组这样赋值,数组名不可以做左值,C错误。D**参数为char*的字符指针类型**,string为类库中的字符类,指针到类无法进行转换,D错误。

临时变量:由编译器在程序需要的时候自动生成的临时性变量,它们并不在代码中出现,但是它们又是确实存在的,而临时变量的生成时机通常是在函数参数传递时发生类型转换,以及函数返回值时被创建。临时变量不能初始化非const引用。

3、 int a[10]; 问下面哪些不可以表示 a[1] 的地址? ( )
A. a+sizeof(int)
B. &a[0]+1
C. (int*)&a+1
D. (int* ) ((char*)&a+sizeof(int))

解析:答案:A。A选项中中首地址加4,为首地址加上16个字节之后的地址,即a[4]的地址。BCD选项都可以表示a[1]的地址。考察点:“&a 表示整个数组的地址,在进行地址计算时,以整个数组的大小为单位进行计算。而 a 则表示数组首元素的地址,以首元素的类型int的大小为单位进行计算。
指针运算:a+n=(unsigned int)a + n * sizeof(Type)

4、 问下面的数据都存放在哪些存储区? ( )
int main()
{
char *p = “hello,world”;
return 0;
}
A. 代码段
B. 栈
C. 常量区
D. 堆

解析:答案:BC注意审题,题目中问的是数据存放的位置,数据包括了指针p,字符串常量,和0。指针p存放在中,其他的放在常量区。本程序还有代码如main函数,函数体存放在代码段中。

5、 下面哪些函数调用必须进入内核才能完成? ( )
A. fopen
B. exit
C. memcpy
D. strlen

解析:答案:AB。A选项,fopen打开一个文件,打开文件必然使用它的驱动,驱动在内核之中。B选项,exit结束当前调用该函数的进程,只有操作系统才能决定进程的结束,必然进入内核。C为内存拷贝函数,D为获取字符串长度,都是在内存之中,都不会进入内核。
系统内核的调用类型:进程控制、文件管理、设备管理、信息维护、通信。
本题考察:C语言、操作系统以及看答题者是否有编写应用程序的经历。

6、 死锁发生的必要条件? ( )
A. 互斥条件
B. 请求和保持
C. 不可剥夺
D. 循环等待

解析:答案:ABCD。A,一个资源一次只能被一个任务或线程占有。B,D,资源已经被占有,其他线程进行请求,请求不到就要保持和等待。C,资源被一个线程占用后不可剥夺,其他线程必须等待。
考的是操作系统原理的知识。死锁的四个必要条件:互斥、请求和保持、不可抢占(剥夺)、循环等待。

7、 有两个线程,最初 n=0,一个线程执行 n++; n++; 另一个执行 n+=2; 问,最后可能的 n
值? ( )
A. 1
B. 2
C. 3
D. 4

解析:答案:BCD,同一个进程的线程共享内存数据,2,3,4都有可能得到。CPU交替处理两个线程,n每进行一次计算就被写回内存。每个线程都会加上2,因此不能选A。

考的是操作系统原理中的多线程编程的知识。同时还考察了一点编译原理,++操作不是原子操作,加法也不是原子操作,即++指令被分解成多行汇编指令:取n值、加1、写n值,中间会被打断,cpu被交替使用。

8、 下面哪些说法正确? ( )
A. 数组和链表都可以随机访问
B. 数组的插入和删除可以达到 O(1)
C. 哈希表无法法进行范围检查
D. 二叉树无法进行线性访问

解析:答案:C。数组可以实现随机访问,链表不能实现随机访问。数组在插入和删除时,需要搬移其他元素,不能达到O(1)。二叉树可以通过线索化二叉树进行线性访问。哈希表是一个键和值的关系,如果一个键没有值对应,则会返回空值,不会进行范围检查。
考察是否学习过数据结构。大公司的笔试题一定会考数据结构。

9、 基于比较的排序的时间复杂度下限是多少? ( )
A. O(n)
B. O(n^2)
C. O(nlogn)
D. O(logn)

解析:答案:C
以下6种排序都是基于比较的排序。
选择排序,插入排序以及冒泡排序的算法思想简单,且算法的时间复杂度同为O(n^2)量级。希尔排序,快速排序和归并排序将排序算法的时间复杂度提高到了O(n*logn)

10、 对于下列程序,在一个 big endian 的 32 位的计算机上,b 的结果是? ( )
unsigned int a = 0x1234;
char b = * ((char*)&a);
A. 0x12
B. 0x34
C. 0x00
D. 程序崩溃

解析:答案:C
big endian:大端模式,高位字节保存在低位地址处。与阅读习惯移植。
little endian:小端模式,高位字节保存在高位地址处。
大小字节序与网络编程有关。说明考题对网络编程的要求比较高。
本题中,a的存放位置如下所示:
这里写图片描述
指针指向首地址,即低地址。因此,答案为C。

11、 编写函数求两个整数 a 和 b 之间的较大值。要求不能使用 if, while, switch, for, ?: 以及任何的比较语句。

解析:不能使用比较语句,可以采用减法和得到的差的正负来进行比较。判断差的正负不能用if,计算机中表示正负数要看符号位,符号位的0和1,可以通过数组的下标来找到相应的数据。

答案如下:

#include <iostream>
using namespace std;
//找到 a 和 b 中大的数。 要求不能使用 if, while, switch, for, ?: 以
//及任何的比较语句。

int max(int a, int b)
{
    int d = a - b;
    int flag = ((unsigned int)d) >> 31; 
    int array[] = {a , b};

    return array[flag];
}

int main()
{
    cout<<max(1,2)<<endl;
    cout<<max(100,10000)<<endl;
    cout<<max(2000,1000)<<endl;

    cout<<"Press the enter key..."<<endl;
    cin.get();
    return 0;
}

另一种解法:但是该方法可能会扣分,因为abs取绝对值函数内部可能会用到判断语句和分支语句。

#include <iostream>
#include <cmath>
using namespace std;

int max(int a, int b)
{
    int c = abs(a-b);
    return (a+b+c)/2;
}

int main()
{
    cout<<max(1000,200)<<endl;
    cout<<max(-5,10)<<endl;

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值