(嵌入式八股)第9章 嵌入式常考手撕题(二)

9.11 独立实现memcpy() 函数

memcpy() 是 C 语言标准库中的一个常用函数,用于 内存拷贝。它的作用是:

  • 从源 (src) 复制 n 个字节 到目标 (dest)。
  • srcdest 的内存区域不能重叠,否则行为未定义(UB)。
  • 该函数 不会 处理字符串结束符 \0,因为它是 内存级别 的拷贝,而不是字符串拷贝。

1. memcpy() 实现

下面是标准的 memcpy() 实现,它通过指针逐字节拷贝数据:

  • 创建源数据 src[] = "Hello, memcpy!"这是一个 包含 \0 终止符 的字符串,总长度 15 字节(包括 \0)。
  • 创建目标数组 dest[20]dest 用于存储 src 复制后的内容,大小足够避免溢出。
  • 调用 my_memcpy(dest, src, sizeof(src))sizeof(src) 计算整个字符串的长度(包括 \0),确保完整拷贝。
  • 输出 dest 的值printf("拷贝后的字符串: %s\n", dest); 显示 dest 的内容。
  • 2. memcpy() 的边界情况:拷贝部分数据

    如果只拷贝 5 个字节:

    • memcpy()不会自动添加 \0,需要手动处理字符串终止符。

    3. memcpy() 的优化版本

    为了提高性能,我们可以使用 按 8 字节批量拷贝 的方式优化 memcpy()

    优化点:

    • 按 8 字节批量拷贝(提升效率)。
    • 处理剩余的字节,保证完整复制。

    结论

    my_memcpy()标准实现,逐字节拷贝,适用于小数据量。

    memcpy() 不自动添加 \0,处理字符串时需手动添加。

    my_memcpy_optimized()按 8 字节批量拷贝,适用于大数据量。

    9.12 独立实现strcpy() 函数

    strcpy() 函数功能

  • strcpy()用于拷贝字符串,即 src 字符串的内容复制到 dest 目标地址
  • 拷贝时包含 \0 终止符,确保 dest 也是一个有效的 C 字符串。
  • 不会检查 dest 空间是否足够,如果 dest 长度小于 src,会导致 缓冲区溢出(Buffer Overflow),产生 未定义行为(UB)
  • strcpy() 的实现

  • dest:目标地址(拷贝后的字符串存放的位置)。
  • src:源字符串(需要拷贝的字符串)。
  • char* p = dest;

    • 记录 dest 地址,最终返回这个地址(符合 strcpy() 规范)。

    while (*src != '\0') { *p++ = *src++; }

    • 逐字节拷贝 src 的字符到 dest,直到遇到 \0 终止符。

    *p = '\0';

    • 手动添加 \0 终止符,确保 dest 也是一个合法的 C 字符串。

    return dest;

    • 返回 dest 指针,以支持 链式调用

    9.13 独立实现strcmp() 函数

    strcmp() 函数功能

    strcmp() 用于比较两个字符串 st

    依据 字典顺序(ASCII 码顺序) 进行比较:

  • s < t 返回 负整数-1-n
  • s == t 返回 0
  • s > t 返回 正整数1+n
  • 逐个字符进行比较,直到:

  • 找到不同字符时返回 (*s - *t) 的值。
  • 若两个字符串相等,则返回 0
  • strcmp() 的实现

  • s:第一个字符串
  • t:第二个字符串
  • while (*s == *t):当 st 当前位置的字符相等时继续。
  • if (*s == '\0') return 0;:若遇到 \0,说明 st 相等,返回 0
  • return *s - *t;若遇到不同字符,返回 ASCII 码差值
  • 执行过程

  • "apple"小于"banana",返回 负值
  • "apple"等于"apple",返回 0
  • "apple"小于"apples"(因 apple 终止于 \0),返回负值。
  • "apples"大于"apple",返回正值。
  • 比较 NULL 指针

    ❌ 运行时错误(Segmentation Fault)

    • NULL不是有效的字符串,访问 *NULL 会导致程序崩溃
    • strcmp()不能 直接用于 NULL,应先检查指针是否为空。

    改进版本:检查 NULL

    总结

    my_strcmp()标准实现,适用于完整字符串比较

    避免 NULL 访问错误,必要时使用 my_strcmp_safe()

    9.14 独立实现strcat() 函数

    strcat() 函数功能

  • strcat()src 字符串拼接到 dest 末尾
  • 覆盖 dest 末尾的 \0,然后在新拼接后的字符串末尾 添加 \0 终止符
  • 返回 指向 dest 的指针,以支持 链式调用(如 strcat(strcat(dest, s1), s2))。
  • strcat() 的实现

  • dest:目标字符串,必须有足够的空间存放 src 追加的内容。
  • src:源字符串,追加到 dest 末尾。
  • 找到 dest\0 结尾p 移动到 dest 末尾的 \0 位置。
  • 追加 src 字符:逐个字符复制 src,覆盖 dest 的 \0。
  • 添加新的 \0 终止符:确保 dest 仍是 合法的 C 字符串。
  • 返回 dest 指针:允许链式调用。
  • 拼接过程

    • src = ", World!" 逐字符复制到 dest 末尾,最终 dest 变为 "Hello, World!"

    9.15 独立实现memmove() 函数

    memmove() 函数功能

  • 剩余60%内容,订阅专栏后可继续查看/也可单篇购买

    作者简介:仅用大半年时间0基础天坑急转嵌入式开发,逆袭成功拿下华为、vivo、小米等15个offer,面试经验60+,收藏20+面经,分享自己的求职历程与学习心得。 专栏内容:最新求职与学习经验,详细讲解了嵌入式开发的学习路径、项目经验分享、简历优化技巧、面试心得及实习经验,从测评,笔试,技术面,HR面,AI面,主管面,谈薪一站式服务,助你突破技术瓶颈、打破信息差,争取更多大厂offer。

    全部评论

    相关推荐

    评论
    5
    5
    分享

    创作者周榜

    更多
    牛客网
    牛客企业服务