对于 C 语言开发者而言,字符、字符串与内存操作是绕不开的核心命题 —— 小到简单的文本处理,大到底层的内存管理,这类操作贯穿了开发的方方面面。为了简化开发流程,C 语言标准库贴心提供了一系列实用工具:字符处理函数、字符串操作函数(如 strcpystrcmp)及内存操作函数(如 memcpymemset)。可这些函数看似 “上手容易”,实则藏着不少容易踩的坑:比如字符串函数对 '\0' 结束符的依赖、内存函数中字节数与元素数的混淆、memcpy 与 memmove 在重叠场景下的用法差异等,稍有不慎就可能导致程序出错。结合近期的学习与实践经历,我梳理了这篇总结,力求清晰呈现两类函数的核心用法、关键区别与避坑要点。需要说明的是,内容均基于个人理解,若存在表述不当或理解偏差,欢迎大家在评论区留言指正,一起交流成长~

(1)首先我们先聊一聊字符/字符串函数

1.字符分类函数(#include<ctype.h >)

  • 分类函数isalpha()(字母)、isdigit()(数字)、isspace()(空白)等,返回非 0/0 表示 “是 / 否”。

 2.字符转换函数 (#include<ctype.h >)    

  • 转换函数toupper()(小写转大写)、tolower()(大写转小写)
  • #include <ctype.h>
    char ch = 'a';
    printf("%c\n", toupper(ch)); // 输出:A

3.字符串操作函数(<string.h>

         strlen:求字符串长度
  • 功能:统计字符串中'\0'前的字符数。
char str[] = "hello";
printf("%zu\n", strlen(str)); // 输出:5
  • 模拟实现:
  • size_t my_strlen(const char* str) {
      const char* p = str;
      while (*p) p++;
      return p - str;
    }
     strcpy:字符串拷贝
  • 功能:将源字符串(含'\0')拷贝到目标空间。
  • 注意:目标空间需足够大。
  • 模拟实现
char* my_strcpy(char* dest, const char* src) {
  char* ret = dest;
  while (*src) *dest++ = *src++;
  *dest = '\0'; // 补结束符
  return ret;
}
        strcat:字符串追加
  • 功能:将源字符串追加到目标字符串的'\0'位置。
  • 模拟实现
  • char* my_strcat(char* dest, const char* src) {
      char* ret = dest;
      while (*dest) dest++; // 找到目标末尾
      while (*src) *dest++ = *src++;
      *dest = '\0';
      return ret;
    }
    strcmp:字符串比较
  • 功能:逐字符比较 ASCII 码,返回差值(>0/=0/<0)。
  • 模拟实现
    int my_strcmp(const char* str1, const char* str2) {
      while (*str1 == *str2) {
        if (*str1 == '\0') return 0;
        str1++; str2++;
      }
      return *str1 - *str2;
    }
    长度受限函数(strncpy/strncat/strncmp)

    避免内存越界的 “安全版”:

  • strncpy(dest, src, n):最多拷贝 n 个字符。
  • strncat(dest, src, n):最多追加 n 个字符。
  • strncmp(str1, str2, n):最多比较 n 个字符。
        其他常用字符串函数
  • strstr:查找子串,返回子串首地址(找不到返回 NULL)。
  • strtok:按分隔符分割字符串(会修改原串)。
  • strerror:将错误码(errno)转为错误描述字符串。

(2)接下来就行内存操作函数(#include<string.h>)

memcpy:内存拷贝

  • 功能:从源地址拷贝 n 个字节到目标地址。
    • 注意:源和目标空间不能重叠(使用时一定要注意)
    • 模拟实现
      void* my_memcpy(void* dest, const void* src, size_t n) {
        void* ret = dest;
        while (n--) {
          *(char*)dest = *(char*)src; // 按字节拷贝
          dest = (char*)dest + 1;
          src = (char*)src + 1;
        }
        return ret;
      }

       memmove:内存移动

    • 功能:与memcpy类似,但支持源和目标空间重叠
    • 实现思路:重叠时从后往前拷贝,避免数据覆盖。
    • 模拟实现:
    • void* my_memmove(void* dest, const void* src, size_t n) {
        void* ret = dest;
        if (dest < src) {
          // 前→后拷贝(无重叠)
          while (n--) *(char*)dest++ = *(char*)src++;
        } else {
          // 后→前拷贝(有重叠)
          dest = (char*)dest + n - 1;
          src = (char*)src + n - 1;
          while (n--) *(char*)dest-- = *(char*)src--;
        }
        return ret;
      }

      memset:内存设置

    • 功能:将目标地址的 n 个字节设置为指定值。
    • 使用:
    • char str[10];
      memset(str, 'a', 5); // 前5个字节设为'a'

      memcmp:内存比较

    • 功能:逐字节比较两个地址的 n 个字节,返回差值(>0/=0/<0)。
    • 使用
      int arr1[] = {1,2,3};
      int arr2[] = {1,2,4};
      printf("%d\n", memcmp(arr1, arr2, sizeof(arr1))); // 输出:-1

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐