VC++面试题收集(1)

1、如果用VC开发程序,常见这么几个错误,C2001,C2005,这些错误的原因是什么。
   答:在学习VC++的过程中,遇到的C2001错误的错误消息主要为:unresolved external symbol(不确定的外部“符号”)。如果连接程序不能在所有的库和目标文件内找到所引用的函数、变量或标签,将产生此错误消息。
   一般来说,发生该错误的原因有两个:一是所引用的函数、变量不存在、拼写不正确或者使用错误;其次可能使用了不同版本的连接库。 
   编程中也经常能遇到C2005错误,即重复定义错误,其实LNK2005错误并不是一个很难解决的错误。

2、请说明虚函数的本质和实现机制
   答:虚函数的本质是通过基类访问派生类定义的函数。虚函数只能借助于指针或者引用来达到多态效果。

3、分别说出描述点对象、大小对象和矩形对象的类名称。
   答:CPoint类,CSize类和CRect类。

4、异步socket编程中,send不出数据的原因是什么,你是怎么处理的?
   答:异步socket编程中,send不出数据的原因共有两个,分别是:TCP下连接断开了和该socket处在阻塞状态(也就是说在发送数据中)。处理的办法就是记录下该SOCKET的状态,当状态为阻塞的时间,放入缓冲,当该SOCKET再次可写时,发送。
5、描述并比较以下对象:事件,信标,临界区,互斥对象。
   答:这些对象都是用于线程同步的对象。 
   临界区:一种保证在某一时刻只有一个线程能访问数据的简便办法。它只可以在同一进程内部使用。主要API函数有,产生临界区:InitializeCriticalSection,删除临界区:DeleteCriticalSection,进入临界区:EnterCriticalSection,退出临界区:Le***eCriticalSection。
   互斥对象:互斥对象跟临界区相似,但它不仅仅能够在同一应用程序不同  线程中实现资源的安全共享,而且可以在不同应用程序的线程之间实现对资源的安全共享,当然下面两者也有这个特点。主要API函数有,创建互斥量: CreateMutex,打开一个存在的互斥量: OpenMutex,释放互斥量的使用权:ReleaseMutex,关闭互斥量: CloseHandle。
   信标:使用信号量(信标)最重要用途是:信号允许多个线程同时使用共享资源,它指出了同时访问共享资源的线程最大数目。它的API函数和使用方法都与互斥对象相似,如创建信号灯:CreateSemaphore,传入的参数可以指定信号灯的初始值。
   事件:用来通知其他进程/线程某件操作已经完成。API函数有创建,打开事件对象等,特殊点的是可以用函数SetEvent人工设置事件为有无信号状态,因此创建事件对象时可以有两种方式,一种为自动重置,一种为人工重置。只有人工重置方式创建的事件对象才能正确使用函数SetEvent。 

6、异步IO和同步IO有什么区别?
   答:异步IO当函数返回时不一定就完成了IO操作,而同步IO已经完成了。所以异步IO需要有一个事件,当IO完成时会设置此事件,调用者在事件上等待。
7、分别描述类CDatabase和类CRecordset的用途。
   答:CDatabase类用于建立与数据源的连接,CRecordset类功能强大,可以将它看做数据源的一个记录集,其中封装了对记录集的各种操作,如:滚动,修改,增加,删除,查询等。

8、cdecl、stdcall、fastcall是什么?哪种可以实现个数不定的入口参数,为什么?
答:三者都是函数调用的约定。 
   (1)fastcall:采用寄存器传递参数,特点就是快了。
   (2)cdecl:cdeclare的缩写,是C和C++程序的缺省调用方式,规则是,按从右至左的顺序压参数入栈,由调用者把参数弹出栈,对于传送参数的内存栈是由调用者来维护的,正因为如此,只有这种调用方式可实现个数不定的入口参数。 
   (3)stdcall:是Pascal程序的缺省调用方式,规则是,按从右至左的顺序压参数入栈,被调用的函数在返回前清理传送参数的内存栈。 上两者的主要区别是前者由调用者清理栈,后者由被调用的函清理栈。当然函数名的修饰部分也是不同的。 
  
9、如何查出内存泄漏和非法操作的BUG(在Release版本下)?
   答:使用map文件。 

10、程序中的局部变量、全局变量和动态申请数据具体存在于什么位置?
   答:程序的局部变量存在于堆栈中,全局变量存在于静态区中,动态申请数据存在于堆中。
11、new delete 与malloc free的联系与区别?
   答:new delete 与malloc free都是在堆(heap)上进行动态的内存操作。用malloc函数需要指定内存分配的字节数并且不能初始化对象,new 会自动调用对象的构造函数。delete会调用对象的destructor,而free不会调用对象的destructor。

12、描述内存分配方式以及它们的区别?
   答:(1)从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static变量。 
   (2)在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集。
   (3)从堆上分配,亦称动态内存分配。程序在运行的时候用malloc或new 申请任意多少的内存,程序员自己负责在何时用free或delete释放内存。动态内存的生存期由程序员决定,使用非常灵活,但问题也最多。

13、指针和引用有什么区别? 
   答:(1)引用在创建的同时必须初始化,即引用到一个有效的对象;而指针在定义的时候不必初始化,可以在定义后面的任何地方重新赋值。
   (2)不存在NULL引用,引用必须与合法的存储单元关联;而指针则可以是NULL。
   (3)引用一旦被初始化为指向一个对象,它就不能被改变为另一个对象的引用;而指针在任何时候都可以改变为指向另一个对象.给引用赋值并不是改变它和原始对象的绑定关系。

(4)引用的创建和销毁并不会调用类的拷贝构造函数。
  (5)语言层面,引用的用法和对象一样;在二进制层面,引用一般都是通过指针来实现的,只不过编译器帮我们完成了转换。

14、有一段文本,统计其中的单词数。例如:As a technology , "HailStorm"is so new that it is still only known by its code name.(注意:单词间的间隔不一定是一个空格。)
   答:假设该文本已存入text这个数组里,可执行程序代码如下: 
void main(){
   char text[1000]={"As a technology,'HailStorm'is so new
   that it is still only known by its code name."};
   int i=0,count=0;
   bool flag=true;
   while (text&&i<1000){
      if (text==' '){ 
           flag=true;
      }else if (flag==true && ((text>='a'&&text<='z')
      ||(text>='A'&&text<='Z'))){?
           count++;flag=false;
      }
      i++;
   }
   cout<<count;
}

猜你喜欢

转载自blog.csdn.net/q357010621/article/details/79902524
今日推荐