常用string.h函数实现整理

memset 、 memcpy 、 memmove 、 strcpy、 strlen 方法的实现整理。

在<string.h>头文件中声明的内存管理函数原型如下:
  1. void *memcpy (void *, const void *, size_t);:从源内存地址的起始位置开始拷贝若干个字节到目标内存地址中,参数分别为:(void *dest, void *src, size_t n),将src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中。
  2. void *memset (void *, int, size_t);:在一段内存块中填充某个给定的值,参数分别为:(void *s, int ch, size_t n),将s中当前位置后面的n个字节用ch替换并返回s。它是对较大的结构体或数组进行清零操作的一种最快方法。
  3. void *memmove (void *, const void *, size_t);:拷贝字节,如果目标区域和源区域有重叠的话,能够保证源在被覆盖之前将重叠区域的字节拷贝到目标区域中,但复制后源内容会被更改,参数分别为:(void* dest, const void* src, size_t count),由src所指内存区域复制count个字节到dest所指内存区域。当目标区域与源区域没有重叠则和memcpy函数功能相同。
在<string.h>头文件中声明的字符串处理函数原型如下:
  1. char *strcpy (char *, const char *);:把含有’\0’结束符的字符串复制到另一个地址空间,参数分别为:(char* dest, const char *src),把从src地址开始且含有NULL结束符的字符串复制到以dest开始的地址空间。
  2. size_t strlen (const char *):计算给定字符串的长度,不包括’\0’在内。
函数功能的实现
1. memcpy
void *memcpy(void *dest, const void *src, size_t count)
{
	char *tmp = dest;
	const char *s = src;
	while (count--)
		*tmp++ = *s++;
	return dest;
}

这样实现存在的一个问题是,如果dest指针所指的区域和src指针所指的区域重叠的话,函数功能不能正确执行,所以会使用restrict关键字来限定这两个参数,void *memcpy( void * restrict dest , const void * restrict src, size_t n)。改进思路:可先进行地址对齐后,按照CPU字长进行拷贝。

2. memmove
void *memmove(void *dest, const void *src, size_t count)
{
	char *tmp = dest;
    const char *s = src;
    if (dest <= src || dest >= (src + count))
    {
        while (count--)
            *tmp++ = *s++;
    }
    else
    {
        tmp += count;
        s += count;
        while (count--)
            *--tmp = *--s;
    }
    return dest;
}

memmove在copy两个有重叠的内存时能正确执行,且memcpymemmove的速度要快一些。

3. memset
void *memset(void *dest, int ch, size_t n)
{
    char *tmp = dest;
    while (n--)
        *tmp++ = ch;
    return dest;
}
1. strlen
size_t strlen(const char *s)
{
    const char *sc;
    for (sc = s; *sc != '\0'; ++sc)
        ;
    return (sc - s);
}

如上单字符的计算效率太低,改进思路1:从字符串的两端同时开始计算。

2. strcpy
char *strcpy(char *dest, const char *src)
{
    char *tmp = dest;
    while (*tmp++ = *src++ != '\0')
        ;
    return dest;
}

改进后的实现:

#include <stddef.h>
char *strcpy(char *dest, const char *src)
{
    register char c;
    char *s = src;
    const ptrdiff_t off = dest - src - 1;
    do
    {
        c = *s++;
        s[off] = c;
    } while (c != '\0');

    return dest;
}

References:
  • https://baike.baidu.com/item/memcpy
  • https://blog.csdn.net/c1204611687/article/details/85864924
  • https://blog.csdn.net/c1204611687/article/details/85849467
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值