行业知识
内存函数详解
1. memcpy函数
void * memcpy ( void * destination, const void * source, size_t num );
1.1 函数的功能,使用与注意事项
1. memcpy���数的作用是内存拷贝,即将source指向的空间中的num个字节拷贝到destination指向的空间中去,然后返回destination原本的值。
()#include #include int main(){ int arr1[] = { 1,2,3,4,5,6,7,8,9,10 }; int arr2[10] = { 0 }; memcpy(arr2, arr1, 20); int i = 0; for (i = 0; i 2. 该函数与strncpy不同之处在于,该函数在遇到'\0'时并不会停下来。
3. source与destination所指向的空间有任何重叠时,拷贝的结果都是未定义的。当需要进行这样的拷贝时,一般由下文会讲到的memmove函数完成。
() 对于第三点,给出以下示例
#include #include int main(){ int arr[] = {1, 2, 3, 4, 5, 6, 7}; memcpy(arr + 2, arr, 12); for(int i = 0; i 此时,arr+2指向的空间与arr指向的空间是有重叠部分的,结果并不是我们所预期的“1 2 1 2 3 6 7”而是“1 2 1 2 1 6 7”(不同平台可能有不同的结果,vs2022和vscode输出的都是前者,因为他们对该函数的实现较为完善,与memmove的实现相似。按照C语言标准的规定,该函数的输出结果应该为后者)。
这是因为,当第一个整形拷贝完之后,source指向空间的前三个整形已经变成了“1 2 1”,继续拷贝下去,“1”就会被拷贝到原本“5”的位置上。
1.2 函数的模拟实现
void* my_memcpy(void* dest, const void* src, size_t num){ assert(dest && src); void* ret = dest; while(num--) { *(char*)dest = *(char*)src; dest = (char*)dest + 1; src = (char*)src + 1; } return ret;} 2. memmove函数
void * memmove ( void * destination, const void * source, size_t num );
2.1 函数的功能,使用与注意事项
基本与memcpy一样,但按照C语言标准规定,该函数才具备拷贝有重叠的空间的能力
2.2 函数的模拟实现
我们可以发现,之前memcpy无法做到重叠空间的拷贝的原因是,source指向空间中还未拷贝但预备拷贝的内容遭到了修改。
由于指向的空间有重叠的部分,所以source中一定会有内容被修改。但,问题是如何让这样的变化不影响拷贝呢?
当然是,确保重叠部分的空间都是在被拷贝之后再被修改。
当destination指向位置在source指向位置之后时,重叠部分位于source的后端,那么我们就应该从后端开始向前拷贝;
当destination指向位置在source指向位置之前时,重叠部分位于source的前端,那么我们就应该从前端开始向后拷贝。
void* my_memmove(void* dest, const void* src, size_t num){ assert(dest && src); void* ret = dest; //dest在前,从前向后拷 //dest在后,从后向前拷 if(dest 3. memset函数
void * memset ( void * ptr, int value, size_t num );
3.1 函数的功能,使用与注意事项
memset函数的作用是设置内存,即将ptr指向空间中的num个字节的值设置为value,然后返回ptr原本的值。
#include #include int main (){ char str[] = "hello world"; memset (str,'x',6); printf("%S\n", str); return 0;} 3.2 函数的模拟实现
void* my_memset(void* ptr, int value, size_t num){ assert(ptr); while(num--) { *((char*)ptr + num) = value; } return ptr;} 4. memcmp函数
int memcmp ( const void * ptr1, const void * ptr2, size_t num );
4.1 函数的功能,使用与注意事项
依次比较ptr1与ptr2指向空间中num个字节的值的大小。
若ptr1较大,返回大于零的数;
若ptr2较大,返回小于零的数;
若相同,则返回零。
该函数似乎意义不大,用到的地方很少,毕竟比较字节的大小似乎没有什么意义。
#include #include int main(){ char buffer1[] = "DWgaOtP12df0"; char buffer2[] = "DWGAOTP12DF0"; int n; n = memcmp(buffer1, buffer2, sizeof(buffer1)); if (n > 0) printf("'%s' is greater than '%s'.\n", buffer1, buffer2); else if (n 4.2 函数的模拟实现
int my_memcmp(const void* ptr1, const void* ptr2, size_t num){ assert(ptr1 && ptr2); while(*(char*)ptr1 == *(char*)ptr2 && num--) { ptr1++; ptr2++; } return *(char*)ptr1 - *(char*)ptr2;}
上一篇:bring怎么读英语语音?