- memcpy
C 库函数void *memcpy(void *str1, const void *str2, size_t n)
从存储区 str2 复制 n 个字节到存储区 str1。 - strcpy
C 库函数char *strcpy(char *dest, const char *src)
把 src 所指向的字符串复制到 dest。 - strncpy
C 库函数char *strncpy(char *dest, const char *src, size_t n)
把 src 所指向的字符串复制到 dest,最多复制 n 个字符。当 src 的长度小于 n 时,dest 的剩余部分将用空字节填充。 - strlen
C 库函数size_t strlen(const char *str)
计算字符串 str 的长度,直到空结束字符,但不包括空结束字符。 - memset
C 库函数void *memset(void *str, int c, size_t n)
复制字符 c(一个无符号字符)到参数 str 所指向的字符串的前 n 个字符。
memcpy、strcpy的区别如下:
- 复制内容不同。memcpy可以复制任何内容,而strcpy只能复制字符串。
- 复制的方法不同。strcpy不需要指定长度,它遇到被复制字符串的结束符
\0
才结束,如果空间不够,会引起内存溢出;memcpy会根据第三个参数长度去决定复制长度。 - 用途不同。通常复制字符串时会用strcpy,需要复制其他类型时,会用memcpy。并且数据中包含
\0
的数据只能用memcpy。
memcpy && strncpy
如果只是操作字符串且拷贝字符串长度小于源字符串长度时,其实这两个函数差别不大,类型转换都不是问题。
有一点差别就是当你要拷贝大于原字符串长度的时候,也就是 n 大于原字符串长度,strncpy 会用 ‘\0’ 来填充,而 memcpy 则会在原字符串所在地址按照长度拷贝内存里的值,所以多余的字符是内存中不确定的值。
考虑内存重叠的strcpy示例:
char* mystrcpy(char* dst, const char* src)
{
assert(dst != NULL);
assert(src != NULL);
if (dst == src)
return dst;
int size = strlen(src) + 1;
if (dst < src || src + size <= dst)
{
char* d = dst;
const char* s = src;
while (size--)
*d++ = *s++;
}
else
{
char* d = dst + size - 1;
const char* s = src + size - 1;
while (size--)
*d-- = *s--;
}
return dst;
}
char* memcpy(void *dest, const void *src, int count)
{
assert(dest != NULL);
assert(src != NULL);
char *d = dest;
char *s = src;
if (d <= s || s + count <= d) {
while (count--) {
*d++ = *s++;
}
} else {
d += count - 1;
s += count - 1;
while (count--) {
*d-- = *s--;
}
}
return dest;
}
附上strcmp(),strlen()的实现过程。
strcmp()函数是根据ACSII码的值来比较两个字符串的;strcmp()函数首先将s1字符串的第一个字符值减去s2第一个字符,若差值为零则继续比较下去;若差值不为零,则返回差值。
int strcmp(cosnt char* str1, const char* str2) {
assert(str1 && str2);
while(*str1 == *str2) {
if(*str1 == '\0') return 0;
str1++;
str2++;
}
return *str1 - *str2;
}
int strcmp(const char* str1, const char* str2) {
int ret = 0;
while (!(ret = *(unsigned char*)str1 - *(unsigned char*)str2) && *str1) {
str1++;
str2++;
}
if (ret < 0) return -1;
if (ret > 0) return 1;
return 0;
}
int strlen(cosnt char* str) {
assert(str != NULL);
int len;
while ((*str++) != '\0') {
len++;
}
return len;
}