【C语言内存函数精选】memcpy、memset、memmove及仿真实现!掌握内存操作的艺术!

这篇具有很好参考价值的文章主要介绍了【C语言内存函数精选】memcpy、memset、memmove及仿真实现!掌握内存操作的艺术!。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

【C语言内存函数精选】memcpy、memset、memmove及仿真实现!掌握内存操作的艺术!,C语言进阶篇,c语言,算法,开发语言,青少年编程,程序人生

❤️博客主页: 小镇敲码人
🍏 欢迎关注:👍点赞 👂🏽留言 😍收藏
🌞任尔江湖满血骨,我自踏雪寻梅香。 万千浮云遮碧月,独傲天下百坚强。 男儿应有龙腾志,盖世一意转洪荒。 莫使此生无痕度,终归人间一捧黄。🍎🍎🍎
❤️我的努力求学没有得到别的好处,只不过是愈来愈发觉自己的无知。 💞 💞 💞

【C语言内存函数精选】memcpy、memset、memmove及仿真实现!掌握内存操作的艺术!,C语言进阶篇,c语言,算法,开发语言,青少年编程,程序人生

1. memcpy

1.1 memcpy的使用介绍

【C语言内存函数精选】memcpy、memset、memmove及仿真实现!掌握内存操作的艺术!,C语言进阶篇,c语言,算法,开发语言,青少年编程,程序人生

从以上图片我们可以知道关于memcpy的以下信息:

  • memcpy的功能是进行内存拷贝,它可用作字符串的拷贝(类似于strcpy的功能)、整形数组的拷贝、结构体的拷贝。
  • memcpy有三个参数:
    • 前两个参数是指针,都是void *类型的指针,只不过另外一个是被拷贝的目的对象,一个是拷贝对象,所以用const修饰表示里面的内容不可修改。
    • 最后一个参数类型是size_t类型是传需要拷贝的字节数。
  • memcpy的返回值是一个(void *)指针,返回被拷贝对象的起始地址。

下面我们通过几段代码来演示memcpy函数的使用:

  • 整形数组的拷贝
#include <stdio.h>
#include <string.h>

int main()
{
    int arr1[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };  // 声明并初始化一个整型数组 arr1
    int arr2[20] = { 0 };  // 声明并初始化一个大小为 20 的整型数组 arr2,所有元素初始化为 0
    int* ret = (int*)memcpy(arr2, arr1, 44);  // 使用 memcpy 函数将 arr1 中的元素复制到 arr2 中,总共复制 44 个字节

    for (int i = 0; i < 11; i++)
    {
        printf("%d\n", *(ret + i));  // 打印复制后的 arr2 数组中的元素
    }
     return 0;
}

  • 由于返回的是被拷贝数组的首元素地址,所以我们需要用int*类型的指针接受,但是返回的指针的类型是void*类型的,这类指针在使用前需要进行强制类型的转换,具体可看我的这篇博客里面有对void*类型指针使用的具体介绍,【C语言进阶技巧】指针掌握之道:深入挖掘指针的无尽潜力(第二部)。另外访问数组里面的元素也可以用[]来访问。
    运行结果:
    【C语言内存函数精选】memcpy、memset、memmove及仿真实现!掌握内存操作的艺术!,C语言进阶篇,c语言,算法,开发语言,青少年编程,程序人生
  • 字符串的拷贝
#include<stdio.h>
#include<string.h>

int main()
{
    char arr1[] = "abcdefwbwb";  // 声明一个字符数组 arr1,并初始化为 "abcdefwbwb"
    char arr2[11] = { 0 };  // 声明一个字符数组 arr2,长度为 11,并初始化为全零
    char* ret = (char*)memcpy(arr2, arr1, 11);  // 使用 memcpy 函数将 arr1 的内容复制到 arr2 中,复制长度为 11

    printf("%s\n", ret);  // 打印复制后的结果

    return 0;
}

运行结果:

【C语言内存函数精选】memcpy、memset、memmove及仿真实现!掌握内存操作的艺术!,C语言进阶篇,c语言,算法,开发语言,青少年编程,程序人生

  • 单精度浮点数的拷贝
#include<stdio.h>
#include<string.h>

int main()
{
    float arr1[] = { 1.0, 2.0, 3.0 };  // 声明一个浮点数数组 arr1,并初始化为 {1.0, 2.0, 3.0}
    float arr2[10] = { 0 };  // 声明一个浮点数数组 arr2,长度为 10,并初始化为全零
    float* ret = (float*)memcpy(arr2, arr1, 12);  // 使用 memcpy 函数将 arr1 的内容复制到 arr2 中,复制长度为 12 字节

    for (int i = 0; i < 3; i++)
    {
        printf("%f\n", *(ret + i));  // 打印复制后的结果,即 arr2 中的元素
    }

    return 0;
}

运行结果:

【C语言内存函数精选】memcpy、memset、memmove及仿真实现!掌握内存操作的艺术!,C语言进阶篇,c语言,算法,开发语言,青少年编程,程序人生

1.2 memcpy的模拟实现

#include <stdio.h>
#include <assert.h>

// 自定义的 memcpy 函数实现
void* my_memcpy(void* dest, void* src, size_t num)
{
    void* ret = dest;  // 保存目标地址的起始位置
    assert(dest && src);  // 确保目标地址和源地址非空
    while (num--)
    {
        *(char*)dest = *(char*)src;  // 逐字节复制
        dest = (char*)dest+1;  // 指针地址后移一位
        src = (char*)src + 1;  // 源地址也后移一位
    }
    return ret;  // 返回目标地址的起始位置
}

// 测试函数1,整型数组拷贝
void test1()
{
    int arr1[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };  // 声明并初始化一个整型数组 arr1
    int arr2[20] = { 0 };  // 声明并初始化一个大小为 20 的整型数组 arr2,所有元素初始化为 0
    int* ret = (int*)my_memcpy(arr2, arr1, 44);  // 使用 my_memcpy 函数将 arr1 中的元素复制到 arr2 中,总共复制 44 个字节
    printf("整型数组拷贝:>\n");
    for (int i = 0; i < 11; i++)
    {
        printf("%d\n", *(ret + i));  // 打印复制后的 arr2 数组中的元素
    }
}

// 测试函数2,字符串拷贝
void test2()
{
    char arr1[] = "abcdefwbwb";
    char arr2[11] = { 0 };
    printf("字符串拷贝:>\n");
    char* ret = (char*)my_memcpy(arr2, arr1, 11);
    printf("%s\n", ret);
}

// 测试函数3,单精度浮点数数组拷贝
void test3()
{
    float arr1[] = { 1.0, 2.0, 3.0 };
    float arr2[10] = { 0 };
    float* ret = (float*)my_memcpy(arr2, arr1, 12);
    printf("单精度浮点数数组拷贝:>\n");
    for (int i = 0; i < 3; i++)
    {
        printf("%f\n", *(ret + i));
    }
}

int main()
{
    test1();
    test2();
    test3();
    return 0;
}

这里对my_memcpy关键部分做一下阐述:

  1. 使用void *指针来接收地址,是因为内存拷贝传过来的对象指向的类型是,有可能是字符、结构体、整形或者浮点型,所以万能指针来接收不同类型的地址就可解决类型不符的问题。
  2. void*指针在使用之前需要进行强制类型转换,使用char*来强制类型转换是因为这种指针的间接级别是最小的,加一减一只跳过了一个字节,假设我们使用int*类型,加一减一跳过了4个字节,那如果遇见字符串拷贝的话,就无法找到每个字符的地址,从而不能拷贝成功,所以我们应该使用强制转换为char*的指针,因为这样可以做到逐字节拷贝,不可能会遗漏掉内容,恰好我们memcpy函数的第三个参数是num指需要拷贝的字节数。
    • 注意强制类型转换是临时的强转,当你想要使用void*类型的指针时就必须强制类型转换,在将两个指针后移一个字节时,你可能会这样写(char*)dest++,这种写法是错误的,因为强制类型转换是临时的,++的优先级更高先作用于dest,此时上一行的强转已经不起效了,而(char*)没有和dest作用,导致dest的类型还是void*类型,而void*类型的指针不先强制类型转换是不能++的,所以这里会报错,使用++(char*)dest在有些编译器上面可以通过,但是为了一劳永逸,我们这样写更好dest = (char*)dest+1

运行结果:

【C语言内存函数精选】memcpy、memset、memmove及仿真实现!掌握内存操作的艺术!,C语言进阶篇,c语言,算法,开发语言,青少年编程,程序人生

但是如果我们想用这个my_mencpy函数进行重叠内存的拷贝,就欠妥了,请看如下代码:

#include<stdio.h>
void* my_memcpy(void* dest, void* src, size_t num)
{
    void* ret = dest;  // 保存目标地址的起始位置
    assert(dest && src);  // 确保目标地址和源地址非空
    while (num--)
    {
        *(char*)dest = *(char*)src;  // 逐字节复制
        dest = (char*)dest + 1;  // 指针地址后移一位
        src = (char*)src + 1;  // 源地址也后移一位
    }
    return ret;  // 返回目标地址的起始位置
}

int main()
{
     int arr1[] = { 1,2,3,4,5 ,6,7,8,9,10};
     int * ret = (int*)my_memcpy(arr1 + 2, arr1, 20);
    for (int i = 0; i < 10; i++)
    {   
        printf("%d",*(ret+i));
    }
    return 0;
}

从数组下标i等于0开始拷贝,拷贝到数组下标为2的位置往后5个元素,按理来说,答案应该是1 2 1 2 3 4 5 8 9 10,我们看运行结果:

【C语言内存函数精选】memcpy、memset、memmove及仿真实现!掌握内存操作的艺术!,C语言进阶篇,c语言,算法,开发语言,青少年编程,程序人生

  • 可以看到结果和我们预期的不同,原地址的值被覆盖了,说明my_memcpy不适合重叠内存的拷贝,事实上,我们有一个的内存函数memmove来负责重叠内存的拷贝。
  • 细心的友友可能会发现这次博主的my_memcpy函数做了微调,由于目的地址和源地址在同一数组,我们想利用指针来访问数组应该把数组的首元素地址赋给ret
  • 如果你发现有些编译器上memcpy也能拷贝重叠内存,那估计是它库函数的实现超过了预期,C语言规定是memcpy不负责重叠内存拷贝,所以不能保证所有的编译器memcpy都可以实现重叠内存的拷贝。

2. memmove

2.1 memmove的使用介绍

【C语言内存函数精选】memcpy、memset、memmove及仿真实现!掌握内存操作的艺术!,C语言进阶篇,c语言,算法,开发语言,青少年编程,程序人生

  • memmove这个函数的参数和memcpy的参数是一样的,它的功能是负责重叠内存的拷贝,它也可以实现不重叠的内存拷贝,下面我们通过一段代码来演示memmove函数的使用。
#include<stdio.h>
#include<string.h>

int main()
{
     int arr1[] = { 1,2,3,4,5 ,6,7,8,9,10};
     memmove(arr1 + 2, arr1,20);
    for (int i = 0; i < 10; i++)
    {   
        printf("%d ",arr1[i]);
    }
    return 0;
}

运行结果:

【C语言内存函数精选】memcpy、memset、memmove及仿真实现!掌握内存操作的艺术!,C语言进阶篇,c语言,算法,开发语言,青少年编程,程序人生
这和我们之前预期的结果是一致的。

2.2 memmove的模拟实现

#include <stdio.h>
#include <assert.h>

void* my_memmove(void* dest, void* src, size_t num)
{
    assert(src && dest);  // 确保源地址和目标地址非空

    void* ret = dest;  // 保存目标地址的起始位置

    if (dest < src)  // 如果目标地址在源地址之后,执行正向复制
    {
        while (num--)
        {
            *(char*)dest = *(char*)src;  // 逐字节复制数据
            dest = (char*)dest + 1;  // 目标地址指针后移一位
            src = (char*)src + 1;  // 源地址指针后移一位
        }
    }
    else  // 如果目标地址在源地址之前,执行反向复制
    {
        while (num--)
        {
            *((char*)dest + num) = *((char*)src + num);  // 逐字节复制数据
        }
    }

    return ret;  // 返回目标地址的起始位置
}

int main()
{
    int arr1[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

    // 调用 my_memmove 函数将 arr1 数组中的元素复制到 arr1 数组的第 3 个位置开始,总共复制 20 个字节
    my_memmove(arr1 + 2, arr1, 20);

    // 打印复制后的 arr1 数组中的元素
    for (int i = 0; i < 10; i++)
    {
        printf("%d ", arr1[i]);
    }
    return 0;
}

我们通过画图来分析这段代码核心部分my_memmove的思路:
【C语言内存函数精选】memcpy、memset、memmove及仿真实现!掌握内存操作的艺术!,C语言进阶篇,c语言,算法,开发语言,青少年编程,程序人生

  • *((char*)dest+num) = *((char*)src+num);这段代码的意思是从后往前开始拷贝,num--后跳过19个字节,刚好指向了最后一个字节的内容。
    运行结果:

【C语言内存函数精选】memcpy、memset、memmove及仿真实现!掌握内存操作的艺术!,C语言进阶篇,c语言,算法,开发语言,青少年编程,程序人生

  • 值得一提的是,无论是memcpy还是memmove函数,拷贝的字节数都不能比目的对象的空间要大,否则系统就会报错,这造成了缓冲区溢出的问题,请看如下代码:
int main()
{
	int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
	int arr2[5] = { 0 };
	memcpy(arr2, arr1, 40);
}

运行结果:

【C语言内存函数精选】memcpy、memset、memmove及仿真实现!掌握内存操作的艺术!,C语言进阶篇,c语言,算法,开发语言,青少年编程,程序人生

  • 还有一种情况就是源对象的大小比num要小,但是目的空间大小足够,此时虽然在VS编译器上虽然不会报错,但是也不建议这样去做,因为还是进行了非法的内存访问,请看如下代码:
int main()
{
	int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
	int arr2[20] = { 0 };
	memcpy(arr2, arr1,80);
}

编译器还是报了警告:
【C语言内存函数精选】memcpy、memset、memmove及仿真实现!掌握内存操作的艺术!,C语言进阶篇,c语言,算法,开发语言,青少年编程,程序人生

我们通过调试也可以看一看此时arr2中放的是什么:

【C语言内存函数精选】memcpy、memset、memmove及仿真实现!掌握内存操作的艺术!,C语言进阶篇,c语言,算法,开发语言,青少年编程,程序人生

可以看到除了前10个元素与arr1相同后10个元素是随机值。

  • 这两种警告显然前一种更加致命,从编译器的反应就可以看出,因为前面一种是arr2的空间不足,然后你把不属于arr2空间的地址也写入了内容,这就造成了缓冲区溢出的问题,更为严重,而后者只是非法访问了一下后面地址的内容,而没有进行其它的操作,相对较轻,但也应该尽可能避免,防止引发其它的错误。

3. memcmp

3.1 menmcmp的使用介绍

【C语言内存函数精选】memcpy、memset、memmove及仿真实现!掌握内存操作的艺术!,C语言进阶篇,c语言,算法,开发语言,青少年编程,程序人生

  • memcmp是内存比较函数,num是要比较的字节数。

  • memcmp函数是按字节进行比较的,并且它是无符号字节比较。在这种比较方式下,会先比较两个内存块的第一个字节,如果相等,则继续比较下一个字节,直到发现不相等的字节或者比较完所有字节。

下面我们通过下面代码来演示一下memcmp函数的使用:

#include<stdio.h>
#include<string.h>
int main()
{
	int arr1[] = { 1,2,1,4,5,6 };
	int arr2[] = { 1,2,257 };
	printf("%d\n",memcmp(arr1, arr2, 9));
	return 0;
}

运行结果:

【C语言内存函数精选】memcpy、memset、memmove及仿真实现!掌握内存操作的艺术!,C语言进阶篇,c语言,算法,开发语言,青少年编程,程序人生
但是当我们比较到10个字节时它却返回-1,请看运行代码:

【C语言内存函数精选】memcpy、memset、memmove及仿真实现!掌握内存操作的艺术!,C语言进阶篇,c语言,算法,开发语言,青少年编程,程序人生
这是为什么呢?我们通过调试来看一下arr1arr2的内存的存储就知道了,我们通过画图来分析:

【C语言内存函数精选】memcpy、memset、memmove及仿真实现!掌握内存操作的艺术!,C语言进阶篇,c语言,算法,开发语言,青少年编程,程序人生
因为memcmp是一个字节一个字节的比较,比较整形大小是不合适的,因为负数在内存中是补码的形式存储,而memcmp是无符号位字节,另外如果仅仅比较正整数,小端存储下也是不合适的,因为如果一个大数,前面一个低地址的字节处是都是0,而高地址处是非0的,当它和整数1比较,系统一个字节一个的比较,第一个字节处就不同了,系统就自动返回-1了,而不会管你后面的字节里面放的是什么,下面我们用一段代码来演示一下:

#include<stdio.h>
#include<string.h>
int main()
{
	int arr1[] = {256};
	int arr2[] = { 1};
	printf("%d\n",memcmp(arr1, arr2, 4));
	return 0;
}

运行结果:

【C语言内存函数精选】memcpy、memset、memmove及仿真实现!掌握内存操作的艺术!,C语言进阶篇,c语言,算法,开发语言,青少年编程,程序人生
如果你不信,可以比较前4个字节的数据:

【C语言内存函数精选】memcpy、memset、memmove及仿真实现!掌握内存操作的艺术!,C语言进阶篇,c语言,算法,开发语言,青少年编程,程序人生
我们这里依然画图分析一下:

【C语言内存函数精选】memcpy、memset、memmove及仿真实现!掌握内存操作的艺术!,C语言进阶篇,c语言,算法,开发语言,青少年编程,程序人生

  • 一个字符只占一个字节,无论是大端存储还是小端存储都不会影响它在内存中的存储,而memcmp函数每次比较一个字节就相当于比较了一个字符,所以可以用memcmp函数来比较字符对象。

通过下面代码我们来演示一下通过memcmp函数来比较字符串的大小:

#include<stdio.h>
#include<string.h>
int main()
{
	char arr1[] = "abcfefabcdef";
	char arr2[] = "abcg";
	printf("%d\n", memcmp(arr1, arr2,4));
	return 0;
}

运行结果:

【C语言内存函数精选】memcpy、memset、memmove及仿真实现!掌握内存操作的艺术!,C语言进阶篇,c语言,算法,开发语言,青少年编程,程序人生
当然你可能会说这可能是一个特例,我们将g字符改为f,按照字符串的比较规则,只比较前4个字符,应该返回0,我们看运行结果:

【C语言内存函数精选】memcpy、memset、memmove及仿真实现!掌握内存操作的艺术!,C语言进阶篇,c语言,算法,开发语言,青少年编程,程序人生
我们将memcmp函数的第三个参数改为5,比较前5个字符,由于arr2的第5个字符是\0,\0的ASCII码值是0,所以应该返回大于0的数字,我们来看运行结果:

【C语言内存函数精选】memcpy、memset、memmove及仿真实现!掌握内存操作的艺术!,C语言进阶篇,c语言,算法,开发语言,青少年编程,程序人生
结果确实和我们预期的一样,说明memcmp函数是可以进行字符对象的比较的,并且但看这一点,它与strncmp函数是非常相似的,如果你不了解这个函数可以看一下博主的这篇文章【C语言进阶技巧】探秘字符与字符串函数的奇妙世界。

字符在内存中是以ASCII码值来存储的,它本质上也是整形家族。

【C语言内存函数精选】memcpy、memset、memmove及仿真实现!掌握内存操作的艺术!,C语言进阶篇,c语言,算法,开发语言,青少年编程,程序人生

4. memset函数

4.1 memset函数的使用介绍

【C语言内存函数精选】memcpy、memset、memmove及仿真实现!掌握内存操作的艺术!,C语言进阶篇,c语言,算法,开发语言,青少年编程,程序人生

  • memset函数的功能是进行内存设置,就是一个字节一个字节里面的数值。
  • memset函数有三个参数。
    • 它的第一个参数是一个void*的地址,也就是我们要设置的对象。
    • 它的第二个参数是一个int型的value值,是我们设置的每个字节的数值。
    • 它的第三个参数是是一个size_t类型的num值,它代表要设置的字节数。

下面我们通过具体的代码来演示memset函数是怎样使用的:

  • 设置字符串
#include<stdio.h>
#include <string.h>  // 包含字符串处理相关的头文件

int main()
{
    char arr1[] = "hello world";  // 定义一个字符数组 arr1,并初始化为字符串 "hello world"
    memset(arr1 + 1, 'x', 4);     // 使用 memset 函数将 arr1 中第二个字符及其后的 4 个字符都设置为字符 'x'
    printf("%s\n", arr1);        // 打印修改后的字符串 arr1

    return 0;  // 返回 0,表示程序执行成功
}

运行结果:

【C语言内存函数精选】memcpy、memset、memmove及仿真实现!掌握内存操作的艺术!,C语言进阶篇,c语言,算法,开发语言,青少年编程,程序人生
在上述代码中,我们希望将字符数组从第二个字符开始数往后的四个字符全部修改为字符x,我们传第二个字符的地址,和需要修改的字符,(这里注意:字符在内存中存贮是以ASCII码值的形式,所以字符本质上也是整形,我们用整形接收这个字符x实际上是接收了它的ASCII码值。),然后再传需要修改的字节数,这里由于memset函数是一个字节一个字节设置的,一个字符所占内存是一字节,所以设置一字节实际上就等同于设置了一个字符。

  • 易错点:有朋友可能会使用字符指针去存字符串,然后再使用memset函数去修改却发现这时候程序崩了,这是因为指针指向了一个字符串常量,它是只读的,修改它是未定义行为。

如果我们想把整形数组里面的每个值都设置为1,是否可行呢?

  • 设置整形数组
#include<stdio.h>
#include <string.h>  // 包含字符串处理相关的头文件

int main()
{
    int arr1[10] = { 0 };    // 定义一个整型数组 arr1,大小为 10,并初始化所有元素为 0

    memset(arr1, 1, 8);      // 使用 memset 函数将 arr1 中的前 8 个字节都设置为值为 1 的字节

    return 0;                // 返回 0,表示程序执行成功
}

使用memset函数后,调试查看arr1数组在内存储存的值为:

【C语言内存函数精选】memcpy、memset、memmove及仿真实现!掌握内存操作的艺术!,C语言进阶篇,c语言,算法,开发语言,青少年编程,程序人生

可以看到此时arr1数组的前8个字节都被我们设置为了1,但是一个整形元素是4个字节,所以此时前两个元素并不是1,如果我们想把前2个元素都设置为1,显然用memset函数无法一次性达到,并且比较麻烦。文章来源地址https://www.toymoban.com/news/detail-609602.html

  • memcpymemmove函数相同,如果你试图设置不属于你的内存,就会报缓冲区溢出的错误。
    【C语言内存函数精选】memcpy、memset、memmove及仿真实现!掌握内存操作的艺术!,C语言进阶篇,c语言,算法,开发语言,青少年编程,程序人生

到了这里,关于【C语言内存函数精选】memcpy、memset、memmove及仿真实现!掌握内存操作的艺术!的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【C语言】memcpy,memmove,memcmp,memset函数详解

    💐 🌸 🌷 🍀 🌹 🌻 🌺 🍁 🍃 🍂 🌿 🍄🍝 🍛 🍤 📃 个人主页 :阿然成长日记 👈点击可跳转 📆 个人专栏: 🔹数据结构与算法🔹C语言进阶 🚩 不能则学,不知则问,耻于问人,决无长进 🍭 🍯 🍎 🍏 🍊 🍋 🍒 🍇 🍉 🍓 🍑 🍈 🍌 🍐 🍍 #includestring.h 与strn

    2024年02月17日
    浏览(23)
  • 【C语言】内存函数memcpy和memmove的功能与模拟实现

    1.memcpy 功能:把source指向的前num个字节内容拷贝到destination指向的位置去,可以拷贝任意类型的数据。 注:1.memcpy并不关心\\0,毕竟传的也不一定是字符串,因此拷贝过程中遇到\\0也不会停下来。 2.num的单位是字节,并不是要拷贝的元素个数 3.如果source和destination有任何的重叠

    2024年02月19日
    浏览(34)
  • memcpy、memmove、memcmp、memset函数的作用与区别

    作用: 从source的位置开始向后复制num个字节的数据到destination的内存位置。 注意: memcpy() 函数在遇到 ’\\0’ 的时候 不会停下来 (strcpy字符串拷贝函数在遇到’\\0’的时候会停下来); destination和source 所指向的内容不能重叠, 否则得不到想要的结果。 void* memcpy(void* destination

    2024年02月14日
    浏览(23)
  • C语言内存函数(memcpy、memmove、memcmp)详解

    memcpy函数为内存拷贝函数,既可以拷贝字符串,也可以拷贝整形数组、浮点型数组等,具有明显的应用优势, destination为目的地空间,source为不可修改(const)的来源空间,num表示无符号的字节数。其主要含义为将source内容拷贝到destination中,拷贝num个字节数。其返回类型、目

    2024年02月07日
    浏览(23)
  • C语言—模拟实现memcpy,memmove

    函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置。 这个函数在遇到 \\\'\\0\\\' 的时候并不会停下来。 如果source和destination有任何的重叠,复制的结果都是未定义的。 其实要实现memcpy非常的简单,我们不管传进来的是哪种数据类型都统一强转为char*,我们知

    2024年02月15日
    浏览(26)
  • 提升内功之模拟实现库函数strlen/strncpy/strcmp/strcat/strstr/memcpy/memmove

    strlen函数的作用就是求字符串的首元素开始往后计算字符串的长度,直到’\\0‘,但不会把\\0的长度计算进去 strncpy的作用就是从source指向的字符串复制num个字节的内容到destination指向的字符串去 如果source的长度小于num,则填充0 注意source和destination的内容在空间上不要重叠,如

    2024年02月16日
    浏览(31)
  • 【C语言】memmove()函数(拷贝重叠内存块函数详解)

    🦄 个人主页 :修修修也 🎏 所属专栏 :C语言 ⚙️ 操作环境 : Visual Studio 2022 目录  一.memmove()函数简介 1.函数功能 2.函数参数 1.void * destination 2.onst void * source 3.size_t num 3.函数返回值 4.函数头文件 二.memmove()函数的具体使用 1.使用memmove()函数完成拷贝整型数组数据(目的地与源重

    2024年02月06日
    浏览(27)
  • 【C语言】memcpy()函数(内存块拷贝函数)

    🦄 个人主页 :修修修也 🎏 所属专栏 :C语言 ⚙️ 操作环境 : Visual Studio 2022 目录 一.memcpy()函数简介 🎏函数功能 🎏函数参数 📌void * destination 📌const void * source 📌size_t num 🎏函数返回值 🎏函数头文件 二.memcpy()函数的具体使用 🎏使用memcpy()函数完成拷贝整型数组数据 🎏使

    2024年02月05日
    浏览(28)
  • memcpy内存拷贝函数

    目录 一、memcpy内存拷贝函数 注意事项 二、memcpy与strcpy对比 三、模拟实现memcpy函数 四、memcpy函数不能进行两块存在内存重叠的空间的内存拷贝 五、改进my_memcpy函数 头文件: string.h 函数原型: void* memcpy(void* destination , const void* source , size_t num) 函数作用: 将源地址中num个字节

    2024年02月07日
    浏览(29)
  • 【c++中内存拷贝函数(C++ memcpy)详解】

    原型 :void*memcpy(void*dest, const void*src,unsigned int count);  功能 :由src所指内存区域复制count个字节到dest所指内存区域。   说明 :src和dest所指内存区域不能重叠,函数返回指向dest的指针。     举例 :  下面自行实现这个函数 程序清单 1 V0.1版程序  程序清单 2 测试V0.1用例   

    2023年04月20日
    浏览(24)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包