C/C++ 面试题记录

Posted shuang0109

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C/C++ 面试题记录相关的知识,希望对你有一定的参考价值。

1、new 、 delete 、 malloc 、 free 的区别与关系?

  new / delete 是C++的运算符,malloc / free 是C的标准库函数。

  new会调用对象的构造函数,delete会调用对象的析构函数。它们都可用于动态申请内存和释放内存。

  对于非内部数据类型的对象而言,使用malloc / free 无法满足动态对象的要求,对象在创建的时候要自动执行构造函数,在销毁时要自动执行析构函数。

  由于malloc/free是库函数而不是运算符,不在编译器控制权限之内,不能够把执行构造函数和析构函数的任务强加于malloc/free。

2、C++是不是安全类型的?

  不是;两个不同类型的指针之间可以相互转换(reinterpret cast)。 C# 是安全类型的。

3、const 与 #define 相比有何优点?

  const 作用: 定义常量、修饰函数参数、修饰函数返回值。被const修饰的东西都受到强制保护,可以防止意外的修改。

  const常量具有数据类型,而宏常量没有数据类型。编译器可以对const常量进行类型安全检查,而#define只是进行字符替换,没有类型安全检查。

  有些集成的调试工具可以对const常量进行调试,但不能对宏定义进行调试。

4、引用与指针的区别?

  引用必须被初始化,指针不需要。

  引用初始化以后不能修改,指针可以改变其所指的对象。

  不存在指向空值的引用,但存在指向空值的指针。

5、 成员函数通过什么来区分不同对象的成员数据?为什么能够区分?

  通过this指针, 因为它指向的是对象的首地址。

6、什么时候必须重新拷贝构造函数?

  当构造函数涉及到动态存储分配空间的时候,要自己编写拷贝构造函数,并且要深拷贝。

7、静态函数存在的意义?

  静态私有成员在类外不能被访问,只能通过类的静态成员函数来访问。

8、不允许重载的5个运算符?

  .*(成员指针访问运算符)、 ::(域运算符)、 sizeof 、 ? : 、 .(成员访问符)

9、流运算符为什么不能通过类的成员函数重载?一般怎么解决?

  因为通过类的成员函数重载要求运算符的第一个操作数必须是自己, 而流运算符重载要求第一个操作数是流对象。一般通过友元来解决。

10、对象间是怎样实现数据的共享的?

  通过类的静态成员变量来实现的。静态成员变量占有自己独立的空间不为某个对象所私有。

11、友元关系有什么特性?

  单向的,非传递的,不能继承的。

12、const char *p, char *  const p;的区别

  如果const位于星号的左侧,则const就是用来修饰指针所指向的变量,即指针指向为常量;

  如果const位于星号的右侧,const就是修饰指针本身,即指针本身是常量。

13、继承优缺点。

  1、类继承是在编译时刻静态定义的,且可直接使用,

  2、类继承可以较方便地改变父类的实现。

  缺点:

  1、因为继承在编译时刻就定义了,所以无法在运行时刻改变从父类继承的实现

  2、父类通常至少定义了子类的部分行为,父类的任何改变都可能影响子类的行为

  3、如果继承下来的实现不适合解决新的问题,则父类必须重写或被其他更适合的类替换。这种依赖关系限制了灵活性并最终限制了复用性。

14、多态的作用?

  1.隐藏实现细节,使得代码能够模块化;扩展代码模块,实现代码重用。

  2.接口重用:为了类在继承和派生的时候,保证使用家族中任一类的实例的某一属性时的正确调用

15、析构函数为什么要虚拟?

  为了防止析构不彻底造成内存泄漏

16、如何引用一个已经定义过的全局变量?

  可以用引用头文件的方式,也可以用extern关键字,如果用引用头文件方式来引用某个在头文件中声明的全局变理,假定你将那个变写错了,那么在编译期间会报错,如果你用extern方式引用时,假定你犯了同样的错误,那么在编译期间不会报错,而在连接期间报错。

17、用什么函数开启新进程、线程。

  线程:CreateThread/AfxBeginThread

  进程:CreateProcess

18、strcpy()memcpy()的区别?

  strcpy()memcpy()都可以用来拷贝字符串,strcpy()拷贝以’\0’结束,但memcpy()必须指定拷贝的长度。

19、总结static的应用和作用?

  (1)函数体内static变量的作用范围为该函数体,不同于auto变量,该变量的内存只被分配一次,因此其值在下次调用时仍维持上次的值;

  (2)在模块内的static全局变量可以被模块内所用函数访问,但不能被模块外其它函数访问;

  (3)在模块内的static函数只可被这一模块内的其它函数调用,这个函数的使用范围被限制在声明它的模块内;

  (4)在类中的static成员变量属于整个类所拥有,对类的所有对象只有一份拷贝;

  (5)在类中的static成员函数属于整个类所拥有,这个函数不接收this指针,因而只能访问类的static成员变量。

20、struct(结构) union(联合)的区别?

  1. 结构和联合都是由多个不同的数据类型成员组成, 但在任何同一时刻, 联合中只存放了一个被选中的成员(所有成员共用一块地址空间), 而结构的所有成员都存在(不同成员的存放地址不同)。

  2. 对于联合的不同成员赋值, 将会对其它成员重写,  原来成员的值就不存在了, 而对于结构的不同成员赋值是互不影响的。

21、windows消息系统由哪几部分构成?

  1.消息队列:操作系统负责为进程维护一个消息队列;程序运行时不断的从该消息队列中获取消息、处理消息。

  2.消息循环:应用程序通过消息循环不断地获取消息、处理消息。

  3.消息处理:消息循环负责将消息派发到相关的窗口上使用关联的窗口过程函数进行处理。

22、winsock建立连接的主要实现步骤?

  服务器端:socket()建立套接字,绑定(bind)并监听(listen),用accept()等待客户端连接, accept()发现有客户端连接,建立一个新的套接字,自身重新开始等待连接。该新产生的套接字使用send()recv()写读数据,直至数据交换完毕,closesocket()关闭套接字。

  客户端:socket()建立套接字,连接(connect)服务器,连接上后使用send()recv(),在套接字上写读数据,直至数据交换完毕,closesocket()关闭套接字。

 23、进程间通信的主要方式

  信号量、管道、消息、共享内存

24、构成Win32 API 函数的三个动态链接库是什么?

  内核库,用户界面管理库,图形设备界面库。

25、windows消息分为几类?并对各类做简单描述。

  1.窗口消息:与窗口相关的消息,除WM_COMMAND之外的所有以WM_开头的消息;

  2.命令消息;用于处理用户请求,以WM_COMMAND表示的消息;

  3.控件通知消息:统一由WM_NOTIFY表示,

  4.用户自定义消息。(WM_USER 、 WM_APP)

26、MFC中,大部分类是从哪个类继承而来?

  CObject

27、TCP/IP 建立连接的过程

  在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接。

  第一次握手:建立连接时,客户端发送连接请求到服务器,并进入SYN_SEND状态,等待服务器确认;

  第二次握手:服务器收到客户端连接请求,向客户端发送允许连接应答,此时服务器进入SYN_RECV状态;

  第三次握手:客户端收到服务器的允许连接应答,向服务器发送确认,客户端和服务器进入通信状态,完成三次握手

28、memset ,memcpy 的区别

  memset用来对一段内存空间全部设置为某个字符,一般用在对定义的字符串进行初始化为‘\0‘

  memcpy用来做内存拷贝,你可以拿它拷贝任何数据类型的对象,可以指定拷贝的数据长度。

29、已知strcpy函数的原型是: char * strcpy(char * strDest,const char * strSrc);不调用库函数,实现strcpy函数。

  char *strcpy(char *strDest, const char *strSrc)

  { 

    if (strDest == NULL || strSrc == NULL)

      return NULL;

    if (strDest == strSrc)

      return strSrc;

    char *tempPtr = strDest;

    while ((*strDest = *strSrc) != ‘\0‘);

    return tempPtr;

  }

30、已知类String 的原型为:

class String

{

public:

  String(const char *str = NULL); // 普通构造函数

  String(const String &other); // 拷贝构造函数

  ~ String(void); // 析构函数

  String & operate =(const String &other); // 赋值函数

private:

  char *m_data; // 用于保存字符串

};

String (const char *str = NULL)

{

  if (str == NULL) {    //strlen在参数为NULL时会抛异常才会有这步判断

    m_data = new char[1];

    m_data[0] = ‘‘;

  }  else  {

    m_data = new char[strlen(str) + 1];

    strcpy(m_data, str);     

  }

}

String (const String & other) 

{

  m_data = new char[strlen(other.m_data) + 1];

  strcpy(m_data, other.m_data);

}

String & String::operator =(const String & other) 

{

  if (this = &other)

    return *this;

  delete []m_data;

  m_data = new char[strlen(other.m_data) + 1];

  strcpy(m_data, othe.m_data);

  return *this;

}

String::~ String(void)

{

  delete []m_data ;

}

 

 

以上是关于C/C++ 面试题记录的主要内容,如果未能解决你的问题,请参考以下文章

常见嵌入式/C/C++面试题100+集合(含参考答案)-更新中

经典SQL面试题(转)

C/C++ 面试题

C/C++面试题分享

程序员面试:C/C++求职者必备 20 道面试题!

面试题七 C/C++ 两个字符串由数字组成的相加,最大不超过32bit整形的系统函数--程序员面试题