zoukankan      html  css  js  c++  java
  • c++ 面试宝典---- 一些容易忽略的坑

    1、关于for循环:for(A;B;C) 是先执行 A,在执行判断语句B,判断语句若是复合的 比如 a<=1&&!x++,则是从左往右的执行,不满足前一项时,不判断第二项,接着执行循环体,最后执行C

    对于上述的语句,在执行B是,先执行a<=1&&!x,无论执行结果的真假,都要执行++语句.

    2、对于后自增语句通常是最后执行。比如有指针char*p, *(p++),该句也是先解引用,再执行自增语句,前自增语句通常是先执行自增。

    3、在函数形参中的表达式,是从左往右运算

    int a=1,b=2;
    fun2(a++,b+a);

    考察上面的句子,实际传入的参数为1,4。a传入后,自增,接着传入b+a。若是 fun2(++a,b+a),则实际传入2,4。

    4 printf 语句则是从右至左的运算

    考察语句 :int b=4;printf("%d,%d",b,b++); 输出5,4  因为先打印第二个b,此时为4,然后自增,然后打印的一个b

    如语句为 int b=4;printf("%d,%d",b,++b); 输出 5,5 先打印第二个b,但在这之前先自增,然后打印第一个b

    纠正:对于第3、第4条,c++并没有规定函数形参中的计算顺序,该顺序由编译去决定,以便得到最佳优化,但是c++规定了在传参前,所有表达式应该计算完成,且压栈顺序为从右至左!!!!

    对于前4条的总结 :for 的执行顺序 ,函数压栈顺序,前自增后自增的执行顺序?

    5 小端存储 则 低低高高,即低地址位存低位数据 大端数据 低高高低

    6 在数据补位的时候要警觉 ,有符号数是按符号补位,无符号数按0补位

    7 一些位运算的技巧 : 交换、取负数、加法器(获取最后一位1,将最后一位1置0)、减法器(加一个负数),乘法器(累加)

    8 字节对齐的原因是,地址总线如果是32位,则每次都是按4个字节来访问内存,这就是访问粒度,由于访问粒度的存在,不能随心所欲的从任意字节开始访问数据,字节对齐的意义是将变量存储到容易访问的位置,避免‘拼凑’。

    9 sizeof 是运算符,参数为 指针和数组名的效果是不一样的,strlen 是函数

    10 空类的空间为1,多重继承的空类空间也为1,但是虚继承由于有虚函数指针的存在,其空间为4

    11 凡是有虚函数的类(哪怕他没有继承其他类,他是基类) 他就有虚函数表,继承有虚函数类的子类 更加有 虚函数表,子类中重写虚函数,则该类的虚函数表中 该函数地址被为重写的地址,也就是说

    class D{ virtual void fun(){};}  sizeof(D)==4;

    12 与宏相比,内联函数要做参数类型检查,是嵌入了函数代码的,而不是跳转到函数地址,它将增加空间消耗,与宏相比 它没有额外代价,但更加安全  。函数中有循环不要使用内联,因为内存消耗过高。

    13 指针与引用的区别在于以下几点:

     指针可以指向空、在使用指针是应该检查其合法性(防空)、指针可修改指向别的      这几点表明了它们在应用上的区别,有不指向任何对象的可能或更改指向对象的可能 应该使用指针

     14关于指针:参考下列声明:

    float(**def)[10]    二级指针 指向 一个一维数组的指针

    double*(*gh)[10]  一级指针 指向一个指针数组

    double(*f[10])()  f 是一个数组 数组内容是指向函数的指针

    int*((*b)[10]) ==int *(*b)[10]

    int(*(*f)(int,int))(int)  f 是一个函数指针 形参是 int int 返回一个函数指针 形参是 int 返回类型是 int

    15 句柄是windows提供给对象的稳定访问索引 可以理解为指针的指针,对象的地址实际是该对象的指针(指针存放着该对象的地址),而windows的内存管理经常会释放空闲内存,或是对其进行移动,以为这指针变化,但句柄始终指向指针,即始终对应指针的地址,提供稳定的访问。

    16 设计原则 : 单一职责、里氏代换(适用父类的地方一定适用子类,但反过来不行)、开闭原则(对修改关闭,扩展开放)、依赖倒转(面向接口)、接口隔离(精简单一)、迪米特法(降低耦合)

    17 必须在构造函数初始化列表的成员变量:常量成员、引用成员

    18 使用成员变量或函数的访问方法通常是提供公有的成员函数

    19 构造函数运行抛出异常,异常点前的构造出来的子对象会被逆序析构,之后的不再构建,当前的成为异常对象,不会调用析构

    20 析构函数不要抛出异常

    21 函数重载时要求 形成不同,返回值不作要求 但是对于普通的函数 void fun(int) 与 void fun (const int)  函数签名相同,无法重载  对于引用 void fun(int&) 与 void fun (const int &) 函数签名不同,可以重载,且后者可以绑定右值

    22 赋值构造函数一定要传引用,不能传值,将引起无穷递归导致栈溢出。实际上会引起编译不通过

  • 相关阅读:
    三数之和
    罗马数字与整数
    Oracle 开启或关闭归档
    Oracle RMAN scripts to delete archivelog
    Oracle check TBS usage
    Oracle kill locked sessions
    场景9 深入RAC运行原理
    场景7 Data Guard
    场景4 Data Warehouse Management 数据仓库
    场景5 Performance Management
  • 原文地址:https://www.cnblogs.com/GreenScarf/p/11033127.html
Copyright © 2011-2022 走看看