物联网小白学C 语言第一期:字符 / 字符串函数 + 内存函数的用法与避坑全指南
对于 C 语言开发者而言,字符、字符串与内存操作是绕不开的核心命题 —— 小到简单的文本处理,大到底层的内存管理,这类操作贯穿了开发的方方面面。为了简化开发流程,C 语言标准库贴心提供了一系列实用工具:字符处理函数、字符串操作函数(如strcpystrcmp)及内存操作函数(如memcpymemset可这些函数看似 “上手容易”,实则藏着不少容易踩的坑:比如字符串函数对'\0'结束符的依赖、内存函
对于 C 语言开发者而言,字符、字符串与内存操作是绕不开的核心命题 —— 小到简单的文本处理,大到底层的内存管理,这类操作贯穿了开发的方方面面。为了简化开发流程,C 语言标准库贴心提供了一系列实用工具:字符处理函数、字符串操作函数(如 strcpy、strcmp)及内存操作函数(如 memcpy、memset)。可这些函数看似 “上手容易”,实则藏着不少容易踩的坑:比如字符串函数对 '\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
更多推荐
所有评论(0)