C語言進階之內(nèi)存操作函數(shù)詳解
內(nèi)存操作函數(shù)
memcpy
頭文件:string.h
基本用途:進行不相關(guān)(不重疊的內(nèi)存)拷貝。
函數(shù)原型:
void* memcpy(void* destination,//指向目標數(shù)據(jù)的指針 const void* source,//指向被拷貝數(shù)據(jù)的指針 size_t num);//拷貝的數(shù)量(單位:字節(jié))
注:
1.基本原理:從source的位置開始向后復制num個字節(jié)的數(shù)據(jù)到destnation的內(nèi)存位置。
2.這個函數(shù)與strcpy不同,它遇見'\0'的時候并不會停下來。
3.如果source和destnation有任何的重疊,復制的結(jié)果都是未定義的。
4.void* 之前講過,為了保證泛用性,使用void*接收任意類型的數(shù)據(jù)。
使用舉例:
#include <stdio.h>
#include <string.h>
struct {
char name[40];
int age;
}person, person_copy;
int main()
{
char myname[] = "Pierre de Fermat";
memcpy(person.name, myname, strlen(myname) + 1);
person.age = 46;
memcpy(&person_copy, &person, sizeof(person));
printf("person_copy: %s , %d\n", person_copy.name, person_copy.age);
return 0;
}這是將字符串和結(jié)構(gòu)體成員變量拷貝到另一個結(jié)構(gòu)體的舉例。
為了更好的理解這一函數(shù),下面我們來模擬實現(xiàn)一下它。
void* my_memcpy(void* dest, const void* src, size_t num)
{
//斷言,防止dest或者src是空指針,如果是空指針則會報錯
assert(dest && src);
//保存起始地址
void* ret = dest;
while (num--)
{
//一次用最小單位(字節(jié))移動,保證泛用性
*(char*)dest = *(char*)src;
//注:強制類型轉(zhuǎn)換只是臨時的,后面+1操作時已不存在
dest = (char*)dest + 1;
src = (char*)src + 1;
}
//返回目標空間的起始地址
return ret;
}memmove
頭文件:string.h
基本用途:重疊內(nèi)存塊的拷貝。
函數(shù)原型:
void* memove(void* destnation, const void* source, size_t num)
注:
1.和memcpy的區(qū)別就是memove函數(shù)處理的源內(nèi)存塊和目標內(nèi)存塊可以重疊。
2.如果原空間和目標空間出現(xiàn)重疊,就得使用memmove函數(shù)處理。
使用舉例:
#include <stdio.h>
#include <string.h>
int main()
{
char str[] = "memmove can be very useful.....................";
//將字符串中從第15個元素的位置向后數(shù)共11個字符挪到從第20個字符開始向后數(shù)第11個元素
memmove(str + 20, str + 15, 11);
puts(str);
return 0;
}該函數(shù)的模擬實現(xiàn):
#include <stdio.h>
#include <string.h>
#include <assert.h>
void* my_memmove(void* dest, const void* src, size_t num)
{
assert(dest && src);
//當目標位置地址小于源內(nèi)存塊數(shù)據(jù)地址時,采用從前向后拷貝的方式
if (dest < src)
{
//根據(jù)字節(jié)數(shù)量一個一個移動內(nèi)存單元
while (num--)
{
*(char*)dest = *(char*)src;
//向后移動一位
dest = (char*)dest + 1;
src = (char*)dest + 1;
}
}
//當目標為指針大于源內(nèi)存塊數(shù)據(jù)地址時,采用從后向前的拷貝方式
else if (dest > src)
{
//將dest和src指針定位到各自最后的內(nèi)存地址處
dest = (char*)dest + num - 1;
src = (char*)src + num - 1;
//根據(jù)字節(jié)數(shù)量一個一個移動內(nèi)存單元
while (num--)
{
*(char*)dest = *(char*)src;
//向前移動一位
dest = (char*)dest - 1;
src = (char*)src - 1;
}
}
}memcmp
頭文件:stdio.h
基本用途:顧名思義,與strcmp函數(shù)類似,這個函數(shù)是比較內(nèi)存數(shù)據(jù)大小的(逐字節(jié))。
函數(shù)原型:
int memcmp(const void* ptr1, const void* ptr2, size_t num);
注:
1.比較從ptr1和ptr2開始的num個字節(jié)
2.與strcmp返回值類似,仍是第一個指針內(nèi)容大于第二個指針的內(nèi)容,返回大于零的數(shù)字,第一個指針內(nèi)容小于第二個指針的內(nèi)容,返回小于零的數(shù)字,相等,返回零。
基本舉例:
#include <stdio.h>
#include <string.h>
int main()
{
char buffer1[] = "axxxxxxxxxxx";
char buffer2[] = "bbbbbbbbbbbb";
int n;
n = memcmp(buffer1, buffer2, sizeof(buffer1));
printf("%d", n);
return 0;
}結(jié)果:

到此這篇關(guān)于C語言進階之內(nèi)存操作函數(shù)詳解的文章就介紹到這了,更多相關(guān)C語言內(nèi)存操作函數(shù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Linux/Manjaro如何配置Vscode的C/C++編譯環(huán)境
這篇文章主要介紹了Linux/Manjaro配置Vscode的C/C++編譯環(huán)境,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-05-05
C語言中動態(tài)內(nèi)存管理初學者容易犯的6個錯誤分享
本篇文章主要介紹了初學者使用C語言中動態(tài)內(nèi)存管理的4個函數(shù)時最容易犯的6個錯誤,以及如何避免這些錯誤,文中的示例代碼講解詳細,感興趣的可以了解一下2023-04-04

