c++笔试面试3

1、

C++ STL 的实现:

1.vector  底层数据结构为数组 ,支持快速随机访问

2.list    底层数据结构为双向链表,支持快速增删

3.deque   底层数据结构为一个中央控制器和多个缓冲区,详细见STL源码剖析P146,支持首尾(中间不能)快速增删,也支持随机访问

4.stack   底层一般用23实现,封闭头部即可,不用vector的原因应该是容量大小有限制,扩容耗时

5.queue   底层一般用23实现,封闭头部即可,不用vector的原因应该是容量大小有限制,扩容耗时

6.45是适配器,而不叫容器,因为是对容器的再封装

7.priority_queue 的底层数据结构一般为vector为底层容器,堆heap为处理规则来管理底层容器实现

8.set       底层数据结构为红黑树,有序,不重复

9.multiset  底层数据结构为红黑树,有序,可重复 

10.map      底层数据结构为红黑树,有序,不重复

11.multimap 底层数据结构为红黑树,有序,可重复

12.hash_set 底层数据结构为hash表,无序,不重复

13.hash_multiset 底层数据结构为hash表,无序,可重复 

14.hash_map      底层数据结构为hash表,无序,不重复

15.hash_multimap 底层数据结构为hash表,无序,可重复 

vector表示一段连续的内存区域,随机访问效率很高,因为每次访问离起始处的位移都是固定的,但是在随意位置插入删除元素效率很低,因为它需要将后面的元素复制一遍。 list表示非连续的内存区域,并通过一对指向首尾元素的指针双向链接起来,从而允许向前和向后两个方向进行遍历。在list的任意位置插入和删除元素的效率都很高:指针必须被重新赋值,但不需要用拷贝元素来实现移动。他对随机访问支持不好,需要遍历中间的元素。每个元素有两个指针的额外空间开销。 deque(双端队列,发音为'deck')也表示一段连续的内存区域,但是他支持高效的在其首部插入和删除元素。 选择顺序容器类型的一些准则: 如果我们需要随机访问一个容器,则vector要比List好得多。 如果我们一直要存储元素的个数,则vector又是一个比list好的选择。 如果我们需要的不只是在容器两端插入和删除元素,则list显然比vector好。 除非我们需要在容其首部插入和删除元素,否则vector要比deque好。

2、

小端机器的数据高位字节放在高地址,低位字节放在低地址。
char array[12] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}; 
1,char一字节,直观呈现的结果为:0x08-07-06-05-04-03-02-01 (从后到前下标为0-7)
2,short两字节,直观呈现 的结果 为: 0x0807-0605-0403-0201  (从后到前  下标  为0-3) :
*pshort从0开始,所以0x201;
*(pshort+2)从2开始,所以0x605;
3,int64八字节,直观呈现 的结果 为 0x0807060504030201  (从后到前  下标  为0) :
*pint64从0开始,所以0x807060504030201;
4,int四字节,直观呈现为0x08070605-04030201 (从后到前  下标  为0-1) :
*(pint+2))从2开始,但是最多只到下标1,后面位置默认为0。

3、

有如下C++代码:
1
2
3
4
5
6
7
8
9
struct A{
   void foo(){ printf ( "foo" );}
   virtual void bar(){ printf ( "bar" );}
   A(){bar();}
};
struct B:A{
   void foo(){ printf ( "b_foo" );}
   void bar(){ printf ( "b_bar" );}
};
那么 
1
2
3
A *p= new B;
p->foo();
p->bar();
输出为:  
barfoob_bar
  
  
A *p=newB;// A类指针指向一个实例化对象B, B类继承A类,先调用父类的无参构造函数,bar()输出bar,B类没有自己显示定义的构造函数。
p->foo();//执行B类里的foo()函数,因为foo不是虚函数,所以直接调用父类的foo函数,输出foo
p->bar();//执行B类的bar()函数, 该函数为虚函数,调用子类的实现,输出b_bar
4、
大端机与小端机:分别对应高尾端与低尾端
对于字符串11223344高尾端指尾端是高位即44,所以存储为11 22 33 44
低尾端指尾端在低位,即11,所以存储44 33 22 11.
5、组合
我们知道,在一个类中可以用类对象作为数据成员,即子对象(详情请查看:C++有子对象的派生类的构造函数)。实际上,对象成员的类型可以是本派生类的基类,也可以是另外一个已定义的类。在一个类中以另一个类的对象作为数据成员的,称为类的组合(composition)。

例如,声明Professor(教授)类是Teacher(教师)类的派生类,另有一个类BirthDate(生日),包含year,month,day等数据成员。可以将教授生日的信息加入到Professor类的声明中。如:

      
      
  1. class Teacher //教师类
  2. {
  3. public:
  4. // Some Code
  5. private:
  6. int num;
  7. string name;
  8. char sex;
  9. };
  10. class BirthDate //生日类
  11. {
  12. public:
  13. // Some Code
  14. private:
  15. int year;
  16. int month;
  17. int day;
  18. };
  19. class Professor:public Teacher //教授类
  20. {
  21. public:
  22. // Some Code
  23. private:
  24. BirthDate birthday; //BirthDate类的对象作为数据成员
  25. };

类的组合和继承一样,是软件重用的重要方式。组合和继承都是有效地利用已有类的资源。但二者的概念和用法不同。通过继承建立了派生类与基类的关系,它是一种 “是”的关系,如“白猫是猫”,“黑人是人”,派生类是基类的具体化实现,是基类中的一 种。通过组合建立了成员类与组合类(或称复合类)的关系,在本例中BirthDate是成员类,Professor是组合类(在一个类中又包含另一个类的对象成员)。它们之间不是‘‘是”的 关系,而是“有”的关系。不能说教授(Professor)是一个生日(BirthDate),只能说教授(Professor)有一个生日(BirthDate)的属性。

Professor类通过继承,从Teacher类得到了num,name,age,sex等数据成员,通过组合,从BirthDate类得到了year,month,day等数据成员。继承是纵向的,组合是横向的。
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值