C语言:模拟实现memcpy函数

模拟实现memcpy函数之前,我们首先来了解一下memcpy函数的功能和用法:memcpy指的是c和c++使用的内存拷贝函数,memcpy函数的功能是从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中。它的函数原型是

void *memcpy(void *dest, const void *src, size_t n);

此处dest代表目标变量,src代表源变量,memcpy函数做的就是将源变量src从起始位置拷贝n个字节到目标变量dest的起始位置。一定要注意此处的n代表的是字节数。

那么怎么实现呢,基本思想是让两个指针指向dest和src变量,然后当*dest==*src时,让两个指针同时向后移,然后进行循环,一直到n为0,循环结束,此时也就将n个字节的内容全部拷贝完毕。

我们看代码,里面有比较详细的注释

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

void* my_memcpy(void* dest, const void* src, int n)//因为memcpy是内存拷贝函数,所以必须什么类型都能接收,所以此处用void*做参数类型和返回值类型
{
    assert(dest != NULL);
    assert(src != NULL);
    char* ret = dest;//因为dest在循环体中不断发生变化,所以将dest的地址存放在指针变量ret中,此后ret就随着dest进行变化,但dest不会随着ret进行变化,最后函数返回ret的值
    while (n--)
    {
        *(char*)dest = *(const char*)src;//void类型不能进行解引用操作,所以要进行强制类型转化,因为此处n指的是字节数,需要一个字节一个字节拷贝,所以强制类型转化为char*。
        ++(char*)dest;//void*类型不能进行++操作,所以要进行强制类型转化,如果是后置++,那么强制类型转化先对dest进行,所以要进行前置++
        ++(char*)src;
    }
    return ret;
}

//arr1打印输出函数
void print(int arr1[], int sz)
{
    int i = 0;
    for (i = 0; i < sz; i++)
    {
        printf("%d ", arr1[i]);
    }
    printf("\n");
}

int main()
{
    char* str1[10] = { 0 };
    char* str2 = "abcdefg";
    char* ret = NULL;
    ret = my_memcpy(str1, str2, 5);//n代表的是字节数
    printf("%s\n", ret);

    int arr1[10] = { 0 };
    int arr2[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    my_memcpy(arr1, arr2, 40);//此处n是字节数,40个字节也就是10个int型值
    int sz = sizeof(arr1) / sizeof(arr1[0]);
    print(arr1, sz);
    system("pause");
    return 0;
}

输出的结果为:
这里写图片描述

在实现代码时要注意以下几点:

1.模拟实现的my_memcpy函数的返回值和参数的类型,必须是void*。因为memcpy函数是内存拷贝函数,它必须什么类型都能接收。
2.目标变量dest的地址需要存放在一个临时指针变量中,因为dest在循环体中一直是变化的。
3.void*类型不能进行解引用操作和++运算,在解引用操作和++运算之前,要进行强制类型转换。并且因为此函数是一个字节一个字节的拷贝,所以要将dest和src变量强制类型转化为char*类型。
4.要将dest和src指针变量assert断言,使其不为NULL。并且因为src是不能改变的,所以用const修饰,以保护起来。

猜你喜欢

转载自blog.csdn.net/windyj809/article/details/80047420