手写字符串处理函数

本文介绍了C语言中几个关键的字符串处理和内存操作函数,如strlen计算字符串长度,memset设置内存区域值,strcat和strncat拼接字符串,strcpy和strncpy复制字符串,以及memcpy和memmove用于安全的内存复制。特别地,memcpy未处理内存重叠情况,而memmove则考虑了这种情况。这些函数在编程中常用于数据操作和内存管理。
摘要由CSDN通过智能技术生成

1.strlen
字符串长度函数,不包括’\0’

int strlen(const char* str) {
    assert(str != NULL);
    int len = 0;
    while ((*str++) != '\0') len++;
    return len;
}

2.memset

void* memset(void* str, int value, size_t n) {
    assert(str != NULL && n >= 0);
    char* temp = (char*)str;
    while (n--) *temp++ = value;
    return str;
}

3.strcat

char* strcat(char* dest, const char* src) {  
    assert((dest != NULL) && (src != NULL));
    char* res = dest;  
    while(*dest != '\0') dest++;  
    while(*src != '\0') *dest++ = *src++;  
    *dest = '\0';
    return res;  
}  

4.strncat

char* strncat(char* dest, const char* src, size_t n) {  
    assert((dest != NULL) && (src != NULL));
    assert(n >= 0);
    char* res = dest;  
    while(*dest != '\0') dest++;  
    while(n-- && *src != '\0') *dest++ = *src++;  
    *dest = '\0';
    return res;  
}

5.strcpy

char* strcpy(char* dest, const char* src) {
    assert((dest != NULL) && (src != NULL));
    char* res = dest;
    while ((*dest++ = *src++) != '\0');
    return res;
}

6.strncpy

char* strncpy(char* dest, const char* src, size_t n) {
    assert((dest != NULL) && (src != NULL));
    char* res = dest;
    while (n-- && (*dest++ = *src++) != '\0');
    return res;
}

7.memcpy
(1)系统实现:没有考虑内存重叠

void* memcpy(void* dest, const void* src, size_t n) {
    assert((dest != NULL) && (src != NULL) && (n >= 0));
    char* pdest = (char*)dest;
    const char* psrc = (char*)src;
    while (n--) *pdest++ = *psrc++;
    return dest;
}

(2)手写实现:要考虑内存重叠

void* memcpy(void* dest, const void* src, size_t n) {
    assert((dest != NULL) && (src != NULL) && (n >= 0));
    char* pdest = NULL;
    const char* psrc = NULL;
    if (src < dest && ((char*)src + n) > (char*)dest) {
        // (1)dest和src重合,src在前面,dest在后面 => 从后往前复制
        pdest = (char*)dest + n - 1;
        psrc = (char*)src + n -1;
        while (n--) *pdest-- = *psrc--;
    } else {
        // (1)dest和src重合,dest在前面,src在后面 (2)dest和src没有重合 => 从前往后复制
	    pdest = (char*)dest;
        psrc = (char*)src;
        while (n--) *pdest++ = *psrc++;
    }
    return dest;
}

8.memmove
系统实现:已经考虑内存重叠

void* memmove(void* dest, const void* src, size_t n) {
    assert((dest != NULL) && (src != NULL) && (n >= 0));
    char* pdest = NULL;
    const char* psrc = NULL;
    if (src < dest && ((char*)src + n) > (char*)dest) {
        // (1)dest和src重合,src在前面,dest在后面 => 从后往前复制
        pdest = (char*)dest + n - 1;
        psrc = (char*)src + n -1;
        while (n--) *pdest-- = *psrc--;
    } else {
        // (1)dest和src重合,dest在前面,src在后面 (2)dest和src没有重合 => 从前往后复制
	    pdest = (char*)dest;
        psrc = (char*)src;
        while (n--) *pdest++ = *psrc++;
    }
    return dest;
}

对比分析
(1)strcpy和memcpy
strcpy只能复制字符串;memcpy可以复制任意内容,例如字符数组、整型、结构体等。
strcpy不需要指定长度,遇到"\0"才结束,如果空间不够会引起内存溢出;memcpy通过参数指定复制长度。
strcpy不能复制包含’\0’的字符串;memcpy可以复制包含“\0”的字符串。

(2)memcpy和memmove
memcpy没有考虑内存重叠;memmove考虑内存重叠。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值