记录一些很方便,提升效率的函数
字符处理
函数名称 | 用途 | 输入 | 返回值 |
isalpha | 判断是否为字母 | char | bool |
tolower | 写转小大写 | char | char |
toupper | 小写转大写 | char | char |
ㅤ | ㅤ | ㅤ | ㅤ |
ㅤ | ㅤ | ㅤ | ㅤ |
数字处理
函数名称 | 用途 | 输入 | 返回值 |
roundf | 将浮点数进行四舍五入 | float | float |
fabs | 转换绝对值 | float | float |
ㅤ | ㅤ | ㅤ | ㅤ |
ㅤ | ㅤ | ㅤ | ㅤ |
ㅤ | ㅤ | ㅤ | ㅤ |
进制转换技巧
16转10
- 例如 输入字符串0xFABCD123
- 则可以跳过前缀开始转换为10进制数字
有关Notion安装或者使用上的问题,欢迎您在底部评论区留言,一起交流~
10转16
用%x或X输出即可,C++则用hex格式化(带上uppercase则输出大写)
10转2
让其从最高到最低位(使用>>操作)分别与 1 进行 & 操作,然后输出。
2转10
直接进行加权计算(c为输入的字符串)
dec_num = dec_num * 2 + (c - '0'); // '0'的ASCII码减完得到数值0/1质数因子(质因子)
质因子(素因数或质因数)是指能整除给定正整数的质数。根据算术基本定理,任何正整数都有独一无二的质因子分解式。例如,8的质因子是2(8=2×2×2),而12的质因子是2和3(12=2×2×3)。
常见算法(C)
- 字典排序
常见算法(C++)
- 字符串逆序输出
常见面试问题
- static的用途
- static修饰的局部变量,会保存在静态存储区,而不是栈中。并且它只会初始化一次,且默认为0, 它不会随着函数的执行结束而释放,它的生命周期和整个程序一致。并且它的作用域还是会限制在当前的函数。
- static修饰的全局变量,作用域会被限制在本文件中,其他的文件不能用extern取访问。
- static修饰的函数,也是只能在本文件调用,不能声明
限制作用域 + 延长生命周期 + 固定初始化
- 引用和指针的区别
- 初始化要求不同:引用初始化时必须绑定一个有效变量,而指针可以暂时为空。
- 指向是否可修改:引用一旦绑定就永远是整个变量的别名,而指针可以指向别的地址。
- 引用不占独立内存,指针占地址存储内存:引用在编译时会被当作别名,不占用内存,而指针会存储目标变量的地址,32位4字节,64位8字节
- 访问方式不同:引用可以直接操作变量,而指针需要解引用才能操作。
- 空值和安全:指针可以指向空或者成为野指针,导致出错。而引用在编译时如果为空就报错了。
- 全局变量和局部变量的区别
- 全局变量的默认作用域是整个文件, 其他文件只要有extern就可以引用,如果是static 修饰则在本文件内。局部变量的作用域在函数内,或者在一个代码块内。
- 全局变量存放在静态存储区(嵌入式中在MCU的Flash),局部变量存在栈区(嵌入式中对应MCU的RAM)
- 全局变量内存地址固定,局部变量内存地址随函数调用压栈出栈动态分配。除了static 修饰的局部变量。
- 全局变量默认初始化为0,局部变量为随机。
- 是不是一个父类写了一个 virtual 函数,如果子类覆盖它的函数不加virtal,也能实现多态?
- 可以实现多态!核心原因是 C++ 中「虚函数的特性会被继承传递」,子类覆盖父类的虚函数时,即使不加
virtual关键字,该函数依然是虚函数,只要满足「覆盖规则」,就能触发多态。 - 虚函数的「继承传递性」:
C++ 中,父类的函数一旦用
virtual声明为虚函数,所有子类中与它「签名完全一致」的函数,默认继承 “虚函数属性” —— 不管子类有没有显式写virtual,它本质还是虚函数,会被写入子类的虚函数表(vtable),替换父类对应的函数入口。 - 「覆盖规则」 只有当子类函数和父类虚函数的「签名完全一致」时,才是「覆盖(override)」,才能触发多态。签名一致要求:函数名、参数列表(类型、个数、顺序)、返回值兼容(父类虚函数返回基类指针/引用,子类覆盖函数返回其派生类指针/引用)、常属性一致(const)
- 什么函数不能声明为虚函数
- 在 C++ 中,无法声明为虚函数的核心原因是:函数的特性与虚函数的 “运行期动态绑定” 机制相冲突—— 虚函数依赖虚函数表(vtable)和虚指针(vptr)实现,且必须是 “属于对象的成员函数”,因此不符合这两个前提的函数都不能声明为虚函数。
- 构造函数(绝对不能声明为虚函数)
- 虚函数的调用依赖「对象的虚指针(vptr)」,而 vptr 是在构造函数执行过程中才初始化的(对象创建时,先分配内存,再执行构造函数,此时才把 vptr 指向当前类的虚函数表)。
- 如果构造函数是虚函数,调用时 vptr 还未初始化,编译器找不到对应的虚函数表入口,会直接编译报错;更本质的是:构造函数的目的是 “创建对象”,而虚函数的目的是 “多态调用已创建对象的方法”,逻辑上矛盾。
- 静态成员函数(static 修饰,绝对不能)
- 静态函数属于「类本身」,而非某个对象,没有
this指针(虚函数需要通过this指针访问对象的 vptr,进而找到虚函数表); - 静态函数的调用方式是 “类名::函数名”,不依赖对象实例,而虚函数的多态调用必须依赖 “基类指针 / 引用指向子类对象”。
- 内联函数(inline 修饰,不能声明为虚函数)
- 内联函数的核心特性是「编译期代码展开」—— 编译器会把内联函数的代码直接嵌入调用处,避免函数调用开销(嵌入式中常用在高频调用的小函数,比如读取寄存器的封装);
- 友元函数(friend 修饰,不能声明为虚函数)
- 友元函数不是类的成员函数(只是拥有访问类私有成员的权限),没有
this指针,无法访问对象的 vptr,自然无法加入虚函数表; - 友元函数不能被继承,而虚函数的多态依赖 “子类覆盖父类虚函数”,继承是前提,因此友元函数不具备成为虚函数的条件。
- 不能声明为虚函数的核心共性:
- 必须是「类的非静态成员函数」(有
this指针,能访问 vptr); - 调用时机必须是「对象创建后」(vptr 已初始化,支持动态绑定)。
- 192.168.0.17/28 的主机范围、子网掩码、广播地址,以及如何区分不同 IP 地址是否在同一网段?
- 子网掩码:/28 表示子网掩码的前缀长度为 28 位(即 32 位掩码中前 28 位为 1),对应的子网掩码为:
255.255.255.240。 - 网络地址:将 IP 地址
192.168.0.17与子网掩码255.255.255.240做与运算:IP 地址第四个字节(17)的二进制:00010001子网掩码第四个字节(240)的二进制:11110000与运算结果:00010000(对应十进制 16)因此网络地址为:192.168.0.16 - 广播地址:将网络地址的主机位(32-子网掩码位数=4)设为全 1,即第四个字节为
16 + 15 = 31(主机位 4 位最大取值为 15),广播地址为:192.168.0.31。 - 主机范围:/28 的子网中,主机位为 4 位(32-28=4),主机位全 0 为网络地址、全 1 为广播地址,因此可用主机地址范围是:
192.168.0.17 ~ 192.168.0.30(网络地址 + 1 至广播地址 - 1)。 - 区分不同 IP 是否在同一网段的方法:将两个 IP 地址分别与同一子网掩码做 “与运算”,若得到的网络地址相同,则两个 IP 处于同一网段;否则不在同一网段。
- 进程间常见的通信方式及那种效率最高?
- 进程间通信的常用方式包括:管道(匿名/命名)、消息队列、共享内存、信号量、套接字(Socket)等,其中共享内存的效率最高。
- 核心原因:共享内存的通信逻辑是:操作系统将同一块物理内存映射到多个进程的虚拟地址空间中,进程可直接读写该内存区域——数据无需在 “进程地址空间” 与 “内核缓冲区” 之间拷贝(管道、消息队列等方式均需 1~2 次数据拷贝),直接完成进程间的数据交换,因此通信延迟极小,是高频、大数据量场景下效率最高的进程间通信方式。
- 其他方式的效率对比:
- 管道/消息队列:数据需经过 “进程→内核缓冲区→目标进程” 的拷贝,存在额外开销,效率中等;
- 套接字:适用于跨网络的进程通信,包含网络协议层的额外处理,效率较低;
- 信号量:主要用于进程间同步互斥,并非传递大量数据的通信方式。
这些函数要么是「不依赖对象(static、友元)」,要么是「生命周期 / 编译机制与虚函数冲突(构造函数、inline)」,本质都是违背了虚函数的两个核心前提:
- 作者:L_Z_J
- 链接:https://www.mcoi.top/article/Post-nowcoder
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。










