答题总结(1)

1.分别写一个宏和函数来获取元素个数如coute(a)会得到a数组元素个数

    宏:#define coute(a) (a==NULL?0:sizeof(a)/sizeof(a[0])) //注意一定要使用()将函数体括起

    求数组大小的模板函数: 

template<unsigned int N,typename T>
int coute(T (&a)[N]){
	return sizeof(a)/sizeof(a[0]);
}

          在函数中。不论参数是int a[]还是 int* a。函数体中都退化为指针。故sizeof(a)都为4,但是在函数体外定义的int a[]为数组,故sizeof(a)为数组长度(char类型还要考虑结束符号)。使用上面这种写法即可。


2.偏移问题

void main(void)
{
char a[6] = {1,2,3,4,5,6};
char * p;
p = (char*)(&a+1);
}

       此时p指向a+6。&a的类型为 char [6]型,所以对&a加1则是指向了a+6。编译器将&a看成是一个指向类型为长度为6的字符串的的指针,她的下一个元素是a   的绝对地址+6。(&a+1)先取变量a的地址,并根据a的地址获得下一个与a同类型的相邻地址。根据前面所说的a的类型为int[5]数组。  

    a[5]即可以看成是一个一维数组,也可以看成是一个只有一行的二维数组a[1][5]。&a指向二维数组的首地址,即&a=&a[0][5],&a+1指向&a[1][5]。每次加的地址长度为sizeof(5*int).


3.形参为指针数组,则实参为二级指针合法


4.迭代器失效

      vector是顺序存储的,只有在尾部插入才不会导致迭代器失效,在头部插入或者中间插入都会导致插入的部位以及其后的所有迭代器都失效;map是映射,key和value是一一对应的,在内存中是零散存在的,迭代器通过key找到value,无论怎么插入都不会让迭代器失效,当然删除只会使得被删除元素的迭代器失效


5.const对象只能调用const类型成员函数


6.关于运算符重载

    能够重载的包括:

         运算符:+,-,*,/,%,++,--;
         位操作运算符:&,|,~,^(位异或),<<(左移),>>(右移)
         逻辑运算符:!,&&,||;
         比较运算符:<,>,>=,<=,==,!=;
         赋值运算符:=,+=,-=,*=,/=,%=,&=,|=,^=,<<=,>>=;
         其他运算符:[],(),->,,(逗号运算符),new,delete,new[],delete[],->*。 


    不能重载的5个运算符有:.------?:----siezof-----::------.* 

     不能重载‘.’,因为‘.’在类中对任何成员都有意义,已经成为标准用法。不能重载 ?: ,因为这个运算符对于类对象来说没有实际意义,相反还会引起歧义 还有::。注意new和delete均可以重载。


  7.堆是按照完全二叉树来构建的,当删除堆顶元素0之后,将末结点顶上,为了维持最小堆,则继续向下做结点间的替换。c++中 list 容器是对 双向链表的封装,适合大量的删除、插入操作。


8.struct和class的区别:

              1)默认的继承和访问权限。struct是public的,class是private的。class继承默认是private继承,而struct继承默认是public继承。两者都可以继承和被继承。

              2)“class”这个关键字还用于定义模板参数,就像“typename”。但关键字“struct”不用于定义模板参数。

              3)初始化问题:class和struct如果定义了构造函数的话,都不能用大括号进行初始化。如果没有定义构造函数,struct可以用大括号初始化。如果没有定义构造函数,且所有成员变量全是public的话,class可以用大括号初始化。

              4)两者都可以定义有参或者无参构造函数或者析构函数(构造时先基类再子类,析构时先子类再基类)

              5)一般而言:class和struct最本质的区别就在于class是引用类型,内存分配于托管堆;而struct是值类型,内存分配于线程堆栈上。

            6)注意,无参构造函数,不能使用 classname v()进行构造,此时编译器认为声明了函数。

9数组初始化问题

           int x[4]={0}; int y[4]={1}

              则值分别为:x{0,0,0,0},y{1,0,0,0}


10构造函数和析构函数的顺序问题

                构造顺序:

                     (1)如果某个类具体基类,执行基类的默认构造函数。

                     (2)类的非静态数据成员(某个类类型),按照声明的顺序创建。

                     (3)执行该类的构造函数。

              析构顺序:           

                      (1)调用类的析构函数。

                      (2)销毁数据成员,与创建的顺序相反。

                      (3)如果有父类,调用父类的析构函数。

class c
{
public:
    c(){ printf("c
"); }
};
class b 
{
public:
    b(){ printf("b
");}
protected:
    c C;
};
class a : public b
{
public:
    a(){ printf("a
"); }
};
int main()
{
    a A;
}
   构造顺序 b c a,析构顺序 a c b


11.trie树

         又称单词查找树,Trie树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,查询效率比哈希表高。



原文地址:https://www.cnblogs.com/engineerLF/p/5393032.html