Lazy loaded image
📘刷题笔记
字数 3503阅读时长 9 分钟
2025-11-12
2025-11-27
😀
记录一些很方便,提升效率的函数

字符处理

函数名称
用途
输入
返回值
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)

    1. 字典排序

      常见算法(C++)

      1. 字符串逆序输出

        常见面试问题

        1. static的用途
          1. 限制作用域 + 延长生命周期 + 固定初始化
            • static修饰的局部变量,会保存在静态存储区,而不是栈中。并且它只会初始化一次,且默认为0, 它不会随着函数的执行结束而释放,它的生命周期和整个程序一致。并且它的作用域还是会限制在当前的函数。
            • static修饰的全局变量,作用域会被限制在本文件中,其他的文件不能用extern取访问。
            • static修饰的函数,也是只能在本文件调用,不能声明
        1. 引用和指针的区别
            • 初始化要求不同:引用初始化时必须绑定一个有效变量,而指针可以暂时为空。
            • 指向是否可修改:引用一旦绑定就永远是整个变量的别名,而指针可以指向别的地址。
            • 引用不占独立内存,指针占地址存储内存:引用在编译时会被当作别名,不占用内存,而指针会存储目标变量的地址,32位4字节,64位8字节
            • 访问方式不同:引用可以直接操作变量,而指针需要解引用才能操作。
            • 空值和安全:指针可以指向空或者成为野指针,导致出错。而引用在编译时如果为空就报错了。
        1. 全局变量和局部变量的区别
            • 全局变量的默认作用域是整个文件, 其他文件只要有extern就可以引用,如果是static 修饰则在本文件内。局部变量的作用域在函数内,或者在一个代码块内。
            • 全局变量存放在静态存储区(嵌入式中在MCU的Flash),局部变量存在栈区(嵌入式中对应MCU的RAM)
            • 全局变量内存地址固定,局部变量内存地址随函数调用压栈出栈动态分配。除了static 修饰的局部变量。
            • 全局变量默认初始化为0,局部变量为随机。
        1. 是不是一个父类写了一个 virtual 函数,如果子类覆盖它的函数不加virtal,也能实现多态?
            • 可以实现多态!核心原因是 C++ 中「虚函数的特性会被继承传递」,子类覆盖父类的虚函数时,即使不加 virtual 关键字,该函数依然是虚函数,只要满足「覆盖规则」,就能触发多态。
              • 虚函数的「继承传递性」: C++ 中,父类的函数一旦用 virtual 声明为虚函数,所有子类中与它「签名完全一致」的函数,默认继承 “虚函数属性” —— 不管子类有没有显式写 virtual,它本质还是虚函数,会被写入子类的虚函数表(vtable),替换父类对应的函数入口。
              • 「覆盖规则」 只有当子类函数和父类虚函数的「签名完全一致」时,才是「覆盖(override)」,才能触发多态。签名一致要求:函数名、参数列表(类型、个数、顺序)、返回值兼容(父类虚函数返回基类指针/引用,子类覆盖函数返回其派生类指针/引用)、常属性一致(const)
        1. 什么函数不能声明为虚函数
            • 在 C++ 中,无法声明为虚函数的核心原因是:函数的特性与虚函数的 “运行期动态绑定” 机制相冲突—— 虚函数依赖虚函数表(vtable)和虚指针(vptr)实现,且必须是 “属于对象的成员函数”,因此不符合这两个前提的函数都不能声明为虚函数。
          1. 构造函数(绝对不能声明为虚函数)
              • 虚函数的调用依赖「对象的虚指针(vptr)」,而 vptr 是在构造函数执行过程中才初始化的(对象创建时,先分配内存,再执行构造函数,此时才把 vptr 指向当前类的虚函数表)。
              • 如果构造函数是虚函数,调用时 vptr 还未初始化,编译器找不到对应的虚函数表入口,会直接编译报错;更本质的是:构造函数的目的是 “创建对象”,而虚函数的目的是 “多态调用已创建对象的方法”,逻辑上矛盾。
          2. 静态成员函数(static 修饰,绝对不能)
              • 静态函数属于「类本身」,而非某个对象,没有 this 指针(虚函数需要通过 this 指针访问对象的 vptr,进而找到虚函数表);
              • 静态函数的调用方式是 “类名::函数名”,不依赖对象实例,而虚函数的多态调用必须依赖 “基类指针 / 引用指向子类对象”。
          3. 内联函数(inline 修饰,不能声明为虚函数)
              • 内联函数的核心特性是「编译期代码展开」—— 编译器会把内联函数的代码直接嵌入调用处,避免函数调用开销(嵌入式中常用在高频调用的小函数,比如读取寄存器的封装);
          4. 友元函数(friend 修饰,不能声明为虚函数)
            1. 友元函数不是类的成员函数(只是拥有访问类私有成员的权限),没有 this 指针,无法访问对象的 vptr,自然无法加入虚函数表;
            2. 友元函数不能被继承,而虚函数的多态依赖 “子类覆盖父类虚函数”,继承是前提,因此友元函数不具备成为虚函数的条件。
            • 不能声明为虚函数的核心共性:
              • 这些函数要么是「不依赖对象(static、友元)」,要么是「生命周期 / 编译机制与虚函数冲突(构造函数、inline)」,本质都是违背了虚函数的两个核心前提:
                1. 必须是「类的非静态成员函数」(有 this 指针,能访问 vptr);
                1. 调用时机必须是「对象创建后」(vptr 已初始化,支持动态绑定)。
          5. 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 处于同一网段;否则不在同一网段。
          6. 进程间常见的通信方式及那种效率最高?
              • 进程间通信的常用方式包括:管道(匿名/命名)、消息队列、共享内存、信号量、套接字(Socket)等,其中共享内存的效率最高
              • 核心原因:共享内存的通信逻辑是:操作系统将同一块物理内存映射到多个进程的虚拟地址空间中,进程可直接读写该内存区域——数据无需在 “进程地址空间” 与 “内核缓冲区” 之间拷贝(管道、消息队列等方式均需 1~2 次数据拷贝),直接完成进程间的数据交换,因此通信延迟极小,是高频、大数据量场景下效率最高的进程间通信方式。
              • 其他方式的效率对比:
                • 管道/消息队列:数据需经过 “进程→内核缓冲区→目标进程” 的拷贝,存在额外开销,效率中等;
                • 套接字:适用于跨网络的进程通信,包含网络协议层的额外处理,效率较低;
                • 信号量:主要用于进程间同步互斥,并非传递大量数据的通信方式。
         
        上一篇
        基于epoll+线程池的即时通讯系统
        下一篇
        在本地阿里云服务器ESC上安装部署NotionNext

        评论
        Loading...