Advertisement

浙江大华2012笔试+解析

阅读量:

一、程序编写题

确定输入字符串是否为回文串。例如,"abccba"是一个回文串;而"abccbaa"则不是回文串。函数声明如下,请完成该函数的设计与实现:
int checkstr(const char *msg);

答:

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

2.请求该链表中第k位前驱节点的位置。其中位于最末端位置的第一个节点定义为该链表的最后一端(其next字段指向空值)。

请详细说明链表节点的定义及其相关函数声明,并在此基础上完成该函数findnode的编写与实现

  1. type Node
  2. {
  3. Node* next;
  4. } // 结构体定义结束
  5. Node* find_node(Node* head, uint k);

答:

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

二、程序填空题

1.请写出下面程序的运行结果

  1. int count = 3;
  2. int main()
  3. {
  4. int i, sum, count = 2;
  5. for(i = 0, sum = 0; i < count; i += 2,count++)
  6. {
  7. static int count = 4;
  8. count++;
  9. if(i % 2 == 0)
  10. {
  11. extern int count;
  12. count++;
  13. sum += count;
  14. }
  15. sum += count;
  16. }
  17. cout<<count<<' '<<sum<<endl;
  18. return 0;
  19. }

请问其运行结束时的打印信息是

  1. 答:四二十
  2. 外部函数extern被用于引用全局变量variable.count;而静态变量variable.count在声明时仅初始化一次,请参阅关于静态变量/static variables/的相关总结。
  3. 在for循环中使用的计数器count指代的是主函数/main函数/中的同一个count;将静态常量(static variable)赋值为4只会执行一段初始化代码;每次计数操作都是对当前的静态变量this.count进行自增操作;最终输出的结果仍然是主函数/ main function/中的那个count值。

2.请写出下面程序的运行结果

  1. void func(char *str)
    {
  2. cout << sizeof(str) << " 字符串长度" << " 和字符数目:" << endl;
  3. }
  4. int main()
    {
  5. const char* stra = "HelloWorld";
  6. char *strb = stra;
  7. cout << sizeof(stra) << " 和 ++strb 的大小:" << sizeof(*strb + 1) << endl;
  8. func (++*strb);
  9. cout << strlen(stra) << " 和 ++*strb 的长度:" << strlen(*strb + 1) << endl;
  10. return 0;
    }

请问其运行结束时的打印信息是

  1. 答:
  2. 11 4
  3. 4 9
  4. 10 9
  5. sizeof(stra) = 11:char数组的大小=数组元素的个数=字符个数+1
  6. sizeof(strb++) = 4:strb是一个指针,在32位系统中,指针的大小是4。注意sizeof有一个特性:编译的时候就把strb替换成类型了,所以里面任何加减操作都是无效的,事实上++没有执行
  7. sizeof(str) = 4:不管数组作为参数怎么表示,数组还是以地址来传递的。str是一个指向stra[1]的指针,所以大小是4,与后面的[50]没有关系
  8. strlen(str) = 9:strlen是指不包括'\0'的字符的个数,与[50]没有关系
  9. strlen(stra) = 10:strlen不包括'\0'
  10. strlen(strb++) = 9:strb指向stra[1],再计算长度,再更改strb为stra[2]

3.请写出下面程序的运行结果

定义一个整数型函数func接受一个整数参数n
函数体开始
初始化变量k为整数类型并赋值为一
如果n大于零则进入条件块
在条件块内执行以下操作:
将k加上调用函数func递减后的n值
使用cout输出当前的n值
再次将k加上调用函数func递减后的n值
函数体结束返回k的值
在主函数中定义整数变量a并赋值为三
调用前面定义的func并将结果输出到标准输出后端并换行处理
最终返回零结束程序执行流程

请问其运行结束时的打印信息是

答:01209

4.请写出下面程序的运行结果

  1. struct SC{int a,b,c;};
  2. struct SD{int a,b,c,d;};
  3. int main()
  4. {
  5. struct SC c1[] = {{3}, {4}, {5}, {6}};
  6. struct SD c2 = (struct SD)c1 + 1;
  7. cout<a<b<c<d<<endl;
  8. return 0;
  9. }

请问其运行结束时的打印信息是

  1. 答:0050
  2. c1的存储方式是这样的:
  3. 3 0 0 | 4 0 0 | 5 0 0 | 6 0 0
  4. c1[0] | c1[2] | c1[3] | c1[4]
  5. c1转换为CD结构后是这样的:
  6. 3 0 0 4 | 0 0 5 0 | 0 6 0 0
  7. c1[0] | c1[1] | c1[2]
  8. c2 = c1 + 1,因此c2指向转换后的c1[1],即0050

5.请写出下面程序的运行结果

类名Base被定义为一个基类:
类名Derived继承自基类Base
在基类Base中定义了一个公共成员:
定义了一个整型成员变量m_ a
子类Derived被初始化为一个新的实例并传递给基类构造函数:
当实例被创建时会调用参数类型为整数并赋值给成员变量a=2
构造函数会打印字符'A'后跟上当前成员变量a的值:
基类中的 destructor方法会打印字符'B'后跟上当前成员变量a的值:
在子类Derived中同样定义了一个公共成员:
定义了一个整型成员变量c_ a并传递给父类构造函数作为参数:
初始化参数类型为整数并赋值给成员变量a=4:
构造方法会打印字符'C'后跟上当前成员变量a的值:
子类中的destructor方法会打印字符'D'后跟上当前成员变量a的值:
最终定义了主程序部分:
定义了两个指针变量aa和bb分别指向基类和子对象类型的新实例:
指针aa被动态分配内存空间并初始化指向一个新的子对象实例:
使用delete关键字释放动态分配的空间并调用destructor方法执行相关操作:
最终返回退出状态码0

请问其运行结束时的打印信息是

  1. 答:执行A2A4C4D4B4B2指令
  2. L17:创建一个基类实例,在初始化时启动一次基类构造函数
  3. L18:创建一个子级实例,在初始化时先启动基类构造函数,在完成之后启动子级构造函数
  4. L19:因为析构函数是纯虚成员函数,在对象被销毁前根据待释放对象的具体类型决定其析构顺序。变量aa指向的是一个子级指针类型对象,在执行其成员解析时会先触发该指针类型的析构操作,在完成该操作后才会触发其所在基数类型的析构操作
  5. L21:变量bb位于栈内内存块中,在执行自动释放机制后会触发一次对应的基数类型析构操作

6.请写出下面程序的运行结果

  1. class Base
  2. {
  3. public:
  4. int m_a, m_b{};
  5. Base(int a = 3, int b = 5) : m_a(a), m_b(b) {}
  6. int func_a() { return m_a - m_b; };
  7. virtual int func_b() { return std::max(m_a, m_b); };
  8. };
  9. class Derived: public Base
  10. {
  11. public:
  12. Derived(int a =4 , int b=7) : Base(a,b) {}
  13. virtual int func_a() { return std::max(m_b +m_a); };
  14. int func_b() { return (m_b >m_a)? (m_b -m_a):0; };
  15. };
  16. int main() {
    17 Derived *aa,*bb;
    18 aa=new Derived(4,7);
    19 bb=new Base(3,5);
    20 std::cout<func_a()<<' '<func_b()<<' '<func_a()<<' '<func_b()<<std::endl;;
    21 delete aa;delete bb;;
    22 return 0;;
    23 }

请问其运行结束时的打印信息是

答:-3 11 -2 2

7.请写出下面程序的运行结果

#include
int func(std::vec_t vec)
{
static int k 初始化为2;
for(遍历器对象it = std::vec.begin(); it != std::vec.end(); ++it)
{
k += (*it 是偶数的话则先加一再累加当前值否则直接累加当前值;
}
return k;
}
int main()
{
std::vec_t vec;
for(int i从0开始循环直到小于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

请填写空出的语句

  1. #define N 10

  2. int get_max_index(int a[], int n)

  3. {

  4. int i, k = 0;

  5. for(i = 1; i < n; i++)

  6. if ( ________ )

  7. k = i;

  8. return ________ ;

  9. }

  10. void main()

  11. {

  12. int i, k, a[N];

  13. for(i = 0; i < N; i++)

  14. cout<<a[i];

  15. k = ________ ;

  16. cout<<k<<" = "<<a[k]<<endl;

  17. }

  18. 答:

  19. a[i] > a[k]

  20. k

  21. get_max_index(a, N)

三、程序改错题

判断这些代码行是否存在编译上的问题或执行中的问题,请标注'无问题'或'存在问题'。

  1. int main()

  2. {

  3. int v1[] = {0, 1, 2, 3}; //________

  4. int v2[5, 2] = {0}; //________

  5. char v3[8] = {"a", "b", 0}; //________

  6. char v4[6] = "string";v4 = "new string"; //________

  7. extern int x1; x1++; //________

  8. const int x2; x2++; //________

  9. static int x3 = 0; x3++; //________

  10. int& x4 = 0; x4++; //________

  11. int* p1 = &x2; p1++; //________

  12. void* p2 = &x3; p2++; //________

  13. return 0;

  14. }

  15. 答:

  16. L3:正确

  17. L4:错误,二维数组的定义方式为int v2[5][2] = {0};

  18. L5:错误,char型只能包含一个字符,"a"包含两个字符,应改为char v3[8] = {'a', 'b', 0};

  19. L6:错误,第一句数组越界,第二句无法从char [11]转换为char [6]

  20. L7:正确

  21. L8:错误,常量必须初始化,且不能对常量修改

  22. L9:正确

  23. L10:错误,引用必须使用一个对象来初始化,如int &x4 = x1;

  24. L11:错误,x2是一个常量,p1不是指向常量的指针

  25. L12:错误,void不能说明p2的对象的大小

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

算法类

问答题:

1.写出以(0,0)为圆心旋转a度的旋转变化函数矩阵。

2.给出一个常用的3阶的拉普拉斯模板。

3.Fisher线性差别的准则是什么?

4.SVM是什么含义?

DSP类

驱动类

应用类

Windows类

1.简述动态连接库(dll)和静态连接库lib的差别。

http://youranxiaoxian.diandian.com/post/2011-10-16/5836945

答: 静态连结就是将(lib)文件所含之函数程式码整合同目标程式的作业流程,在程序运行过程中无需依赖其它连结档的存在;而动连结则是将调用之函数所属(DLL)档块及其调用函数在档块内的位置等信息整合同目标程式的作业流程,在程序运行过程中由(DLL)档块依需求提供相应函數程式码之需求,
此过程则需依赖(DLL)档块的存在才能正常运作。
另外两者之主要区别尚有如下几点不同之处:
一、在功能架构上,
静连结不允许嵌入其它 static 或 dynamic 连结,
而动连结则可自由嵌入其它 type 的连结以满足更复杂的系统架构需求;
二、在实现机制上,
静连结必须先完成整个 target 程序之连结流程,
而后方能执行核心运算功能;
相反地动连结则可边运算边进行相关联之 dynamic 连结之建立与释放机制

2.请阐述在MFC环境中,当程序接收到WM_PAINT消息时其处理方式是什么?这种消息通常会在哪些情况下触发?

  1. 处理流程:
  2. (1)启动绘制操作时:通过调用BeginPaint函数来清除现有图形,并切换到白色画笔。
  3. EndPaint完成后:释放所有与绘图相关的资源以避免潜在泄漏。
  4. 生成WM_PAINT消息:
  5. (1)初始创建新窗口时:系统检测到新的Window激活事件并发送相应的消息。
  6. (2)调整窗口尺寸时:当用户对显示区域进行缩放或重新定位操作后触发此事件。
  7. (3)将当前窗口置于另一应用程序窗口的后方:执行隐藏或遮挡其他应用程序的界面的操作。
  8. (4)调整窗体状态为最大或最小化:通过相关API向系统提交该消息以实现相应的窗体管理功能。

3.请简述Critical Section、Mutex、Semaphore的功能和差别。

Critical Section(临界区)是一段代码块,在特定时刻仅允许一个线程进入该区域进行操作。它通过维护对共享资源的访问顺序来防止数据竞争性破坏现象的发生。
Mutex(互斥量)是一种机制,确保同一资源在任意两个进程之间实现互斥访问.该机制支持基于条件的操作,即PV操作.
Semaphore是一种专为互斥访问设计的资源管理机制,在该机制下,最多有n个进程能够同时使用同一个资源.

4.简述多线程程序对比单线程程序的优点和缺点。

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

全部评论 (0)

还没有任何评论哟~