浙江大华2012届校园招聘研发类试卷B

一、程序编写题

1.函数checkstr判断一个字符串是不是对称的,如:“abccba”是对称的,"abccbaa"则不是对称的。函数声明如下,其中msg为输入的字符串,对称返回0,不对称返回-1,请实现该函数。
int checkstr(const char *msg);

答:

int checkstr(const char *msg)
{
	int i = 0, len;
	while(msg[i] != '\0')i++;
	len = i;
	for(i = 0; i < len/2; i++)
		if(msg[i] != msg[len-i-1])
			return -1;
	return 0;
}

2.给出一个单向链表的头指针,输出该链表中倒数第k个节点的指针。链表的倒数第0个节点为链表的尾结点(尾结点的next成员为NULL)。

函数findnode实现上述功能,链表节点定义及函数声明如下,请实现函数findnode。

typedef struct Node
{
	struct Node *next;
}Node;
Node* findnode(Node *head, unsigned int k);
答:
Node* findnode(Node *head, unsigned int k)
{
	int cnt = 0;
	Node *p = head;
	while(p)
	{
		cnt++;
		p = p->next;
	}
	if(cnt < k)
		return NULL;
	cnt = cnt - k - 1;
	p = head;
	while(cnt--)
		p = p->next;
	return p;
}


二、程序填空题

1.请写出下面程序的运行结果
int count = 3;
int main()
{
	int i, sum, count = 2;
	for(i = 0, sum = 0; i < count; i += 2,count++)
	{
		static int count = 4;
		count++;
		if(i % 2 == 0)
		{
			extern int count;
			count++;
			sum += count;
		}
		sum += count;
	}
	cout<<count<<' '<<sum<<endl;
	return 0;
}
请问其运行结束时的打印信息是                 
答:4 20
extern是引用全局的count,定义为static的count只初始化一次,见static总结
for循环里的count指的是main()里的,static =4这句只执行一次,count++是static这个count,最后输出的是main()里的count

2.请写出下面程序的运行结果
void func(char str[50])
{
	cout<<sizeof(str)<<' '<<strlen(str)<<endl;
}
int main()
{
	char stra[] = "HelloWorld";
	char *strb = stra;
	cout<<sizeof(stra)<<' '<<sizeof(strb++)<<endl;
	func(++strb);
	cout<<strlen(stra)<<' '<<strlen(strb++)<<endl;
	return 0;
}
请问其运行结束时的打印信息是                 
答:
11 4
4 9
10 9
sizeof(stra) = 11:char数组的大小=数组元素的个数=字符个数+1
sizeof(strb++) = 4:strb是一个指针,在32位系统中,指针的大小是4。注意sizeof有一个特性:编译的时候就把strb替换成类型了,所以里面任何加减操作都是无效的,事实上++没有执行
sizeof(str) = 4:不管数组作为参数怎么表示,数组还是以地址来传递的。str是一个指向stra[1]的指针,所以大小是4,与后面的[50]没有关系
strlen(str) = 9:strlen是指不包括'\0'的字符的个数,与[50]没有关系
strlen(stra) = 10:strlen不包括'\0'
strlen(strb++) = 9:strb指向stra[1],再计算长度,再更改strb为stra[2]

3.请写出下面程序的运行结果
int func(int n)
{
	int k = 1;
	if(n > 0)
	{
		k += func(--n);
		cout<<n;
		k += func(--n);
	}
	return k;
}
int main()
{
	int a = 3;
	cout<<func(a)<<endl;
	return 0;
}
请问其运行结束时的打印信息是                 
答:01209

4.请写出下面程序的运行结果
struct SC{int a,b,c;};
struct SD{int a,b,c,d;};
int main()
{
	struct SC c1[] = {{3}, {4}, {5}, {6}};
	struct SD *c2 = (struct SD*)c1 + 1;
	cout<<c2->a<<c2->b<<c2->c<<c2->d<<endl;
	return 0;
}
请问其运行结束时的打印信息是                 
答:0050
c1的存储方式是这样的:
3 0 0 | 4 0 0 | 5 0 0 | 6 0 0
c1[0] | c1[2] | c1[3] | c1[4]
c1转换为CD结构后是这样的:
3 0 0 4 | 0 0 5 0 | 0 6 0 0
  c1[0]  |  c1[1]   |    c1[2]
c2 = c1 + 1,因此c2指向转换后的c1[1],即0050

5.请写出下面程序的运行结果
class Base
{
public:

	int m_a;
	Base(int a = 2):m_a(a){cout<<'A'<<m_a;}
	virtual ~Base(){cout<<'B'<<m_a;}
};
class Derived:public Base
{
public:
	Derived(int a = 4):Base(a){cout<<'C'<<m_a;}
	~Derived(){cout<<'D'<<m_a;}
};
int main()
{
	Base *aa, bb;
	aa = new Derived;
	delete aa;
	return 0;
}
请问其运行结束时的打印信息是                 
答:A2A4C4D4B4B2
L17:生成一个基类对象,调用一次基类的构造函数
L18:生成一个子类的对象,先调用基类构造函数,再调用子类构造函数
L19:由于析构函数是虚函数,根据待释放对象的类型来调用析构函数。aa指向的是子类对象,先调用子类析构函数,再调用基类析构函数
L21:bb是栈内对象,自动释放,调用一次基类的析构函数

6.请写出下面程序的运行结果
class Base
{
public:
	int m_a, m_b;
	Base(int a = 3, int b = 5):m_a(a), m_b(b){}
	int func_a(){return m_a - m_b;}
	virtual int func_b(){return m_a + m_b;}
};
class Derived:public Base
{
public:
	Derived(int a = 4, int b = 7):Base(a, b){}
	virtual int func_a(){return m_b + m_a;}
	int func_b(){return m_b - m_a;}
};
int main()
{
	Base *aa, *bb;
	aa = new Base(4, 7);
	bb = new Derived(3, 5);
	cout<<aa->func_a()<<' '<<aa->func_b()<<' '<<bb->func_a()<<' '<<bb->func_b()<<endl;
	delete aa;delete bb;
	return 0;
}
请问其运行结束时的打印信息是                 
答:-3 11 -2 2

7.请写出下面程序的运行结果
#include <vector>
int func(std::vector<int> vec)
{
	static int k = 2;
	std::vector<int>::reverse_iterator it;
	for(it = vec.rbegin(); it != vec.rend(); ++it)
	{
		k += *it % 2 == 0 ? ++*it : (*it)++;
	}
	return k;
}
int main()
{
	std::vector<int> vec;
	for(int i = 0; i < 4; ++i)
	{
		vec.push_back(i);
		cout<<func(vec)<<endl;
	}
	return 0;
}
请问其运行结束时的打印信息是                 
答:3 5 10 18

8.以下程序输入10个整数到a数组,找到并输出其中最大的整数及其下标。
如输入:80 290 150 520 330 -160 -99 0 200 9
则输出:a[3] = 520
请填写空出的语句
#define N 10
int get_max_index(int a[], int n)
{
	int i, k = 0;
	for(i = 1; i < n; i++)
		if ( ________ )
			k = i;
	return ________ ;
}
void main()
{
	int i, k, a[N];
	for(i = 0; i < N; i++)
		cout<<a[i];
	k = ________ ;
	cout<<k<<" = "<<a[k]<<endl;
}
答:
a[i] > a[k]
k
get_max_index(a, N)

三、程序改错题

指出下列代码行是否有编译错误或运行错误,请用“正确”,“错误”填空。假定必须的标准头文件已经包含。
int main()
{
	int v1[] = {0, 1, 2, 3};                     //________
	int v2[5, 2] = {0};                          //________
	char v3[8] = {"a", "b", 0};                  //________
	char v4[6] = "string";v4 = "new string";     //________
	extern int x1; x1++;                         //________
	const int x2; x2++;                          //________
	static int x3 = 0; x3++;                     //________
	int& x4 = 0; x4++;                           //________
	int* p1 = &x2; p1++;                         //________
	void* p2 = &x3; p2++;                        //________
	return 0;
}
答:
L3:正确
L4:错误,二维数组的定义方式为int v2[5][2] = {0};
L5:错误,char型只能包含一个字符,"a"包含两个字符,应改为char v3[8] = {'a', 'b', 0};
L6:错误,第一句数组越界,第二句无法从char [11]转换为char [6]
L7:正确
L8:错误,常量必须初始化,且不能对常量修改
L9:正确
L10:错误,引用必须使用一个对象来初始化,如int &x4 = x1;
L11:错误,x2是一个常量,p1不是指向常量的指针
L12:错误,void不能说明p2的对象的大小

四、选做题(请选作适合自己方向的一类题目)

算法类

问答题:
1.写出以(0,0)为圆心旋转a度的旋转变化函数矩阵。
2.给出一个常用的3阶的拉普拉斯模板。
3.Fisher线性差别的准则是什么?
4.SVM是什么含义?

DSP类


驱动类


应用类


Windows类

1.简述动态连接库(dll)和静态连接库lib的差别。
答:静态连接库就是把(lib)文件中用到的函数代码直接链接进目标程序,程序运行的时候不再需要其它的库文件;动态链接就是把调用的函数所在文件模块(DLL)和调用函数在文件中的位置等信息链接进目标程序,程序运行的时候再从DLL中寻找相应函数代码,因此需要相应DLL文件的支持。  
    静态链接库与动态链接库都是共享代码的方式,如果采用静态链接库,则无论你愿不愿意,lib 中的指令都全部被直接包含在最终生成的 EXE 文件中了。但是若使用 DLL,该 DLL 不必被包含在最终 EXE 文件中,EXE 文件执行时可以“动态”地引用和卸载这个与 EXE 独立的 DLL 文件。静态链接库和动态链接库的另外一个区别在于静态链接库中不能再包含其他的动态链接库或者静态库,而在动态链接库中还可以再包含其他的动态或静态链接库。

2.请简述MFC中窗口收到WM_PAINT消息是如何处理的,什么情况下产生WM_PAINT消息。
处理过程:
(1)BeginPaint开始画,就是用白刷去掉原窗口
(2)GetClientPaint获得窗口显示区域和尺寸等信息并绘制
(3)EndPaint释放绘图句柄。
产生WM_PAINT消息:
(1)第一次创建一个窗口时
(2)改变窗口大小时
(3)把窗口从另一个窗口背后移出时
(4)最大化或最小化窗口时

3.请简述Critical Section、Mutex、Semaphore的功能和差别。
Critical Section(临界区)是一段代码,用于保护另一段代码。它保证在一个时刻只有一个内核控制路径访问被临界区保护的代码。
Mutex(互斥量):使两个进程互斥地访问一个资源。支持PV操作。资源个数为1,可以看作是信息量的特殊情况。
Semaphore:一种只能被互斥访问的资源有n个,支持申请和释放该资源的操作。

4.简述多线程程序对比单线程程序的优点和缺点。
(1)多线程的优点:
无需跨进程边界;
程序逻辑和控制方式简单;
所有线程可以直接共享内存和变量等;
线程方式消耗的总资源比进程方式好;
(2)多线程缺点:
每个线程与主程序共用地址空间,受限于2GB地址空间;
线程之间的同步和加锁控制比较麻烦;
一个线程的崩溃可能影响到整个程序的稳定性;
到达一定的线程数程度后,即使再增加CPU也无法提高性能;
线程能够提高的总性能有限,而且线程多了之后,线程本身的调度也是一个麻烦事儿,需要消耗较多的CPU
(3)多进程优点:
每个进程互相独立,不影响主程序的稳定性,子进程崩溃没关系;
可以尽量减少线程加锁/解锁的影响,极大提高性能,就算是线程运行的模块算法效率低也没关系;
通过增加CPU,就可以容易扩充性能;
每个子进程都有2GB地址空间和相关资源,总体能够达到的性能上限非常大
(4)多进程缺点:
逻辑控制复杂,需要和主程序交互;
多进程调度开销比较大;
需要跨进程边界,如果有大数据量传送,就不太好,适合小数据量传送、密集运算

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值