C\C++面试知识点总结(超全)


关键字const

主要作用:

  1. 修饰变量或对象,说明该变量或对象不能被改变
  2. 修饰指针,分为指向常量的指针(const在星号左边,不能用指针改值,属于底层const)和常指针(const在*号右边,能用指针改值,属于顶层const
  3. 修饰引用,常用于形参,既避免了拷贝,又避免了函数对值的修改
  4. 修饰成员函数,说明该成员函数内不能修改成员变量。此时可以用于区分重载(常对象调用常成员函数)
  5. 修饰成员变量,此时只能在构造函数初始化参数列表初始化

拓展:

与define的区别:

  1. const常量有数据类型,而宏常量没有
  2. 编译器可以对const进行安全检查,而只对宏常量进行字符替换
  3. 有些调试工具只可以对const进行调试

如何修改常成员函数中类的成员变量:

  • 在类的成员变量中,用mutable修饰成员变量即可

关键字static

主要作用:

  1. 修饰普通变量,使变量存储在静态区。在main函数前就分配了空间。有初始值就初始化,没有就默认初始化
  2. 修饰普通函数,防止多人开发时函数名相同
  3. 修饰成员变量,使所有该类的对象共享这一份复制,在实现文件中初始化。不需要生成对象就能访问该成员。class::m_val
  4. 修饰成员函数,此时static成员函数没有this指针,故只能访问static成员变量。不需要生成对象就能使用该函数。class::m_func
  5. 函数体内的static变量作用范围仅为该函数体,不同于auto变量,该变量的内存只被分配一次。在下一次调用该函数时依然维持上一次的值

this指针

  1. 是一个隐含于每一个非静态成员函数中的指针(全局函数和静态函数没有),指向正被该成员函数操作的那个对象
  2. 本质是成员函数的第一个参数T*const this(常指针)。常成员函数第一个参数为const T *const this。调用成员函数时,编译器将类的指针作为实参传递进去,成员函数内隐含使用this指针访问数据成员
  3. this不是一个常规变量,只是一个右值,不能取其地址&this
  4. this指针并不占用对象的空间,跟对象之间没有包含关系,只是当前调用的对象被它指向而已
  5. 避免自赋值if (this == &rhs) return *this;

inline内联函数

inline必须与函数定义放在一起才能使函数成为内联,仅放在函数声明前不起作用

例:
普通函数:声明定义都以inline修饰
成员函数:类内定义则隐式当成内联函数;类外定义则类外定义处使用inline修饰

优点:

  1. 内联函数同宏函数一样在被调用处进行代码展开省去了函数调用的开销(参数压栈、栈帧开辟和回收、结果返回等),从而提高程序的运行速度
  2. 内联函数相较于宏,在代码展开时会做安全检查或自动类型转换,且可以在运行时调试,真正具有函数特性
  3. 类的声明中定义的函数除了虚函数的其他函数都隐式地当成内联函数

缺点:

  1. 代码膨胀(复制):内联是通过代码复制来消除函数调用的开销,每一处内联函数调用都要复制代码,使总代码量增大
  2. 不能包含循环、递归、switch等复杂操作
  3. 是否对函数内联,决定权在编译器

扩展:

虚函数能否是内联函数?

  • 可以是,若虚函数是通过对象来访问的,在编译期间就能确定,于是可以内联,但最终是否内联取决于编译器
  • 若虚函数是通过基类指针来访问的,呈现多态性,在编译期间不能确定,编译器无法知道运行期调用哪个代码,于是就不能内联。否则在delete基类指针时会先调用派生类的析构函数,再调用基类析构函数

assert断言

  1. 是一个宏,并非函数
  2. 原型定义在 <assert.h>(C)<cassert>(C++)
  3. 如果它的条件返回false,则输出错误信息,程序终止执行

sizeof关键字(操作符)和字节对齐

sizeof介绍

并非函数返回字节数
括号内的内容在编译过程中是不被编译的,而是被类型替代

字节对齐

字节对齐是在编译时决定的,一旦决定则不会再改变。

  1. 作用于数据类型
    在这里插入图片描述
  2. 作用于数组,则得到数组所占空间的大小
  3. 作用于指针,则得到指针本身所占空间的大小(一般为4)
  4. 作用于变量,则得到变量类型所占空间的大小
    在这里插入图片描述
  5. 作用于普通结构体和类,结构体长度一定是最长的数据元素的整数倍结构体内类型相同的连续元素和数组一样,将在连续空间内
    在这里插入图片描述
    在这里插入图片描述
  6. 作用于带有虚函数或者虚继承的类
    在这里插入图片描述
  7. pack预处理指令:禁止对齐调整(不要轻易做这样的调整,会降低程序性能),合法参数是1\2\4\8\16
    在这里插入图片描述
    在这里插入图片描述

总结:

  • 当作用于结构类型或变量,sizeof返回实际的大小
  • 当作用于静态的数组,sizeof返回全部数组的大小
  • sizeof不能返回被动态分配的数组或外部的数组大小
  • 数组作为参数传递给函数时传递的是指针而不是数组,于是函数中return sizeof(数组名)结果是4
  • 一般地址总线总是按照对齐后的地址来访问的。假如你想得到0x00000001开始的4字节内容,系统首先需要以0x00000000读4字节,从中取得3字节,然后再用0x00000004作为开始地址,获得下一个4字节

总之记住四条规则

  1. 地址一般从0开始
  2. 元素存放的位置一定会在自己大小的整数倍上开始
  3. 检查计算出的存储单元是否为所有元素中最宽的元素长度的整数倍。若是,则结束;否则,将其补齐为它的整数倍
  4. 当结构体内的元素的长度都小于处理器位数时,以结构体中最长数据元素为对其单位。否则以处理器位数作为对齐单位

与strlen的区别

区别:

  • strlen的参数只能是char*,而且必须是‘\0’结尾的(由于其实现是计算‘\0’以前的字符个数),而且它是一个函数。sizeof是一个关键字。
  • sizeof操作符的结果类型是size_t,在头文件中typedef为unsigned int类型
  • sizeof在编译的时候就能计算出来,而strlen要在运行时才能确定,主要用来计算字符串长度
  • 4
    点赞
  • 90
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值