memcpy與memmove函數

memcpy()與memmove()是C語言中的函數,其聲明在頭文件string.h中,具體聲明如下:

void* __cdecl memcpy(
    _Out_writes_bytes_all_(_Size) void* 	  _Dst,
    _In_reads_bytes_(_Size)       void const* _Src,
    _In_                          size_t      _Size
    );
    
_VCRTIMP void* __cdecl memmove(
    _Out_writes_bytes_all_opt_(_Size) void*       _Dst,
    _In_reads_bytes_opt_(_Size)       void const* _Src,
    _In_                              size_t      _Size
    );

說明
memcpy將計數字節從src複製到目標;wmemcpy複製計數寬字符(兩個字節)。 如果源和目標重疊,則memcpy的行爲是不確定的。 使用memmove處理重疊區域。

參考
https://docs.microsoft.com/zh-cn/cpp/c-runtime-library/reference/memcpy-wmemcpy?view=vs-2019

在C/C++一些筆試中較常見要求不用標準庫函數,實現mommove函數的功能,這裏進行一下自我總結:
函數原型

void *memcpy(void *dst, const void *src, size_t size);
void *memmove(void *dst, const void *src, size_t size);

函數實現

void* memcpy(void* dst, const void* src, size_t size)
{
    char *dst_t = (char*)dst;
    char *src_t = (char*)src;
 
    while(size--) {
        *dst_t++ = *src_t++;
    }
    return dst;
}

由於memcpy是不去處理覆蓋的情況的,所以已經不推薦使用了,而memmove對於src<dst<src+size的情況需要從後往前移動,才能正確處理覆蓋的情況。

void* memmove(void* dst, const void* src, size_t size)
{
    char* dst_t = (char*)dst;	// 指向首地址
    char* src_t = (char*)src;

    if(dst_t > src_t && (src_t + size>s_dst)) {  // 從後往前移動
        dst_t = dst_t + size - 1;
        src_t = src_t + size - 1;
        while(size--) {
            *dst_t-- = *src_t--;
        }
    }else {
        while(size--) {
            *dst_t++ = *src_t++;
        }
    }
    return dst;
}

<----------------------------正文分割線---------------------------->
隨機插入幾個簡單算法
1、二分查找

int BinarySearch(int s[], int n, int key)
{
    int low=0, high=n-1;
    int mid;
    while(low <= high)
    {
        mid = (low + high) / 2;
        if(s[mid] == key)  return mid;
        else if(s[mid] > key)   high = mid - 1;
        else low = mid + 1
    }
    return -1;
}

2、選擇排序

void Select_Sort(int arr[],int sz)
{
    int i = 0;
    int j = 0;
    int temp = 0;
    int minIndex = 0;
    for (i = 0; i < sz; ++i)
    {
        minIndex = i;
        for (j = i+1; j < sz; ++j)
        {
            if (arr[minIndex]>arr[j])
                minIndex = j;//更新最小值的下標
        }
        if (arr[i]>arr[minIndex])
        {
            temp = arr[i];
            arr[i] = arr[minIndex];
            arr[minIndex] = temp;
        }
    }
}

時間複雜度O(n2)O(n^2),空間複雜度O(1)O(1)
3、快速排序

//遞歸實現快速排序
#include <cstdio>
#include<cstdlib>

void quickSort(int* arr,int low,int high);
int Partition(int* arr,int low,int high);

int main(int argc,char* argv[])
{
    int i,a[]={4,2,6,9,1,3,5};
    int length = sizeof(a)/sizeof(a[0]);
    quickSort(a,0,length-1);
    printf("After sorted:  ");
    for(i=0;i<length;i++)
        printf("%d ",a[i]);
}

void quickSort(int* arr,int low,int high)
{
    if(low<high)
    {
        int pivotloc = Partition(arr,low,high);
        quickSort(arr,low,pivotloc-1);
        quickSort(arr,pivotloc+1,high);
    }
}

int Partition(int* arr,int low,int high)
{
    int pivotkey = arr[low];
    while(low<high)
    {
        while(low<high && arr[high] >= pivotkey)
            --high;	// 從後往前掃
        arr[low] = arr[high];
        while(low<high && arr[low] <= pivotkey)
            ++low;	// 從前往後掃
        arr[high] = arr[low];
    }
    arr[low] = pivotkey;
    return low;
}

時間複雜度O(log n)O(log\ n),空間複雜度O(log n)O(log\ n)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章