欧美free性护士vide0shd,老熟女,一区二区三区,久久久久夜夜夜精品国产,久久久久久综合网天天,欧美成人护士h版

首頁綜合 正文
目錄

柚子快報激活碼778899分享:c語言 C:內(nèi)存函數(shù)

柚子快報激活碼778899分享:c語言 C:內(nèi)存函數(shù)

http://yzkb.51969.com/

目錄

前言:

一、memcpy 函數(shù)的使用及實現(xiàn)

1、memcpy函數(shù)的介紹

?1.1 memcpy函數(shù)參數(shù)解讀

?2、memcpy函數(shù)的使用

3、memcpy函數(shù)的模擬實現(xiàn)

二、memmove函數(shù)的使用及模擬

1、memmove函數(shù)的使用

2、memmove函數(shù)的模擬實現(xiàn)

三、memset 函數(shù)的使用

1、memset函數(shù)的介紹(cplusplus)

2、memset函數(shù)的使用

2.1 memset函數(shù)對數(shù)組的應(yīng)用

2.2 memset函數(shù)對字符串的應(yīng)用

?編輯

?四、memcmp函數(shù)的使用

1、memcmp函數(shù)的介紹

2、memcmp函數(shù)的使用

前言:

上篇文章介紹了C語言字符串函數(shù),我們學(xué)會了一些對字符串的操作,比如說將字符串從一個字符數(shù)組拷貝到另一個字符數(shù)組中,我們可以通過使用strcpy函數(shù)實現(xiàn)。但是,如果我們想要拷貝一個整型數(shù)組到另一個整型數(shù)組中時,strcpy函數(shù)就失效了,那我們應(yīng)該怎么才能實現(xiàn)這個操作呢?不要著急,本篇文章將帶大家搞定這個問題。

一、memcpy函數(shù)的使用及實現(xiàn)

1、memcpy函數(shù)的介紹

cplusplus上的介紹:

作用介紹:

參數(shù)介紹:

返回值介紹:

?1.1 memcpy函數(shù)參數(shù)解讀

(1)void* destination

該參數(shù)的作用是目標(biāo)空間,用來存放將要拷貝的內(nèi)存,為什么返回值是 void* 呢?這是因為這個函數(shù)的作用是內(nèi)存拷貝,既然是內(nèi)存拷貝,內(nèi)存中又可能存放的是整型數(shù)組,也有可能存放的是字符數(shù)組……,因此我們不關(guān)心存放數(shù)據(jù)的類型,因此使用void*指針來接收任意類型的數(shù)據(jù)的地址。

(2)const void* source

source是源頭,也就是要拷貝的內(nèi)存數(shù)據(jù),這里也是void*指針是因為我們不知道我們未來要拷貝的數(shù)據(jù)是什么類型的,可能是整型,可能是字符,也可能是結(jié)構(gòu)體,因此我們也使用void*。

用const修飾是因為我們不希望要拷貝的數(shù)據(jù)被修改,因此使用const修飾會使得整個工程更加穩(wěn)定。

(3)size_t num

num的作用是限定拷貝的字節(jié)數(shù),比如說source中有十個字節(jié)的數(shù)據(jù),我們可以通過修改num的值來拷貝我們想要的個數(shù),num為5,我們就拷貝五個字節(jié)的數(shù)據(jù)到destination中;num的類型是size_t的原因是我們拷貝的個數(shù)最低都是0個,不會出現(xiàn)負數(shù)的情況,因此使用size_t類型最為合適。

?2、memcpy函數(shù)的使用

前面學(xué)習(xí)了memcpy函數(shù),接下來我們將使用memcpy函數(shù)來實現(xiàn)一些操作

比如說我們打算將整型數(shù)組arr1[ ] = {1,2,3,4,5,6,7,8,9,10}拷貝到整型數(shù)組 arr2[10] = { 0 };

#include

int main()

{

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

?? ?int arr2[10] = { 0 };

?? ?memcpy(arr2, arr1, 5 * sizeof(int));

?? ?return 0;

}

調(diào)試結(jié)果:

源頭從 3 開始拷貝,比如說:

#include

int main()

{

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

int arr2[10] = { 0 };

memcpy(arr2, arr1+2, 5 * sizeof(int));

return 0;

}

?一些總結(jié):

函數(shù)memcpy從source的位置開始向后賦值num個字節(jié)的數(shù)據(jù)到destination指向的內(nèi)容;這個函數(shù)在遇到\0的時候并不會停下來,與字符串函數(shù)不同;如果source和destination有任何的重疊,賦值的結(jié)果都是未定義的。

3、memcpy函數(shù)的模擬實現(xiàn)

接下來我們嘗試自己寫一個函數(shù)來實現(xiàn)memcpy的功能

void* my_memcpy(void* dest, const void* src, size_t num)

{

}

int main()

{

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

int arr2[10] = { 0 };

my_memcpy(arr2, arr1, 5 * sizeof(int));

return 0;

}

注意:在my_memcpy中,源頭是void*指針類型的??

現(xiàn)在有一個問題,我們不知道我們要拷貝的是內(nèi)容是什么類型的,我們只知道要拷貝的是20個字節(jié),我們該怎么將這20個字節(jié)拿到arr2中呢?

在前面學(xué)習(xí)qsort函數(shù)的模擬實現(xiàn)中,我們用到了一個方法,我們可以一個字節(jié)一個字節(jié)的拷貝,那么就可以使用強制類型轉(zhuǎn)換將void*指針轉(zhuǎn)換為char*指針

void* my_memcpy(void* dest, const void* src, size_t num)

{

while (num--)//num是字節(jié)總數(shù),因此num每減1,就拷貝一個字節(jié)

{

*(char*)dest = *(char*)src;

dest = (char*)dest + 1;

src = (char*)src + 1;

}

}

調(diào)試結(jié)果:?

總代碼:

#include

void* my_memcpy(void* dest, const void* src, size_t num)

{

// 保存目標(biāo)地址,以便最后返回

void* ret = dest;

// 循環(huán) num 次進行逐個字節(jié)的復(fù)制

while (num--)

{

// 將源地址指向的內(nèi)容復(fù)制到目標(biāo)地址指向的位置,并轉(zhuǎn)換為 char* 類型進行操作,確保每次只復(fù)制一個字節(jié)

*(char*)dest = *(char*)src;

// 目標(biāo)地址向后移動一個字節(jié)

dest = (char*)dest + 1;

// 源地址向后移動一個字節(jié)

src = (char*)src + 1;

}

// 返回復(fù)制后的目標(biāo)地址

return ret;

}

int main()

{

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

int arr2[10] = { 0 };

my_memcpy(arr2, arr1, 5 * sizeof(int));

return 0;

}

如果我們向?qū)nt arr1[] = { 1,2,3,4,5,6,7,8,9,10 };中(1,2,3,4,5)拷貝放到(3,4,5,6,7)的位置上,這樣可以實現(xiàn)嗎?

my_memcpy(arr1+2, arr1, 5 * sizeof(int));

調(diào)試結(jié)果:

為什么這里會是(1,2,1,2,1)呢?其實也很好理解

?因此最終結(jié)果是(1,2,1,2,1,2,1,8,9,10)?

關(guān)于重疊問題,我們一般使用后面的這個函數(shù)memmove函數(shù)

而memcpy函數(shù)一般用來處理不重疊情況。

在vs2022中,memcpy的能力是比較強的,也是可以用來處理重疊問題,但是對于memcpy函數(shù),本來的作用是不包括處理重疊的問題的,這就像是老師說讓你考到60分就行,但是你能考100分。但是不能保證在所有的編譯器上memcpy都可以考到100分

也就是說無法確定其它編程環(huán)境是否可以實現(xiàn),因此,如果要處理重疊問題,最好還是交給memmove函數(shù).

二、memmove函數(shù)的使用及模擬

1、memmove函數(shù)的使用

memove函數(shù)的使用與memcpy函數(shù)是一樣的,也是用來實現(xiàn)內(nèi)存中數(shù)據(jù)的拷貝的,因此就不詳細介紹了。不過前面也說了memmove函數(shù)可以實現(xiàn)重疊拷貝,來測試一下

#include

#include

int main()

{

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

memmove(arr1+2, arr1, 5 * sizeof(int));

return 0;

}

調(diào)試結(jié)果:?可以看到的確將(1,2,3,4,5)的內(nèi)容拷貝到(3,4,5,6,7)的位置上了

那么memmove函數(shù)究竟是怎么實現(xiàn)這個操作的呢?我們來模擬了解一下

2、memmove函數(shù)的模擬實現(xiàn)

前面我們知道,如果拷貝1,會把3給覆蓋,拷貝2,會把4給覆蓋。

該怎么拷貝才能實現(xiàn)不被覆蓋呢?

可以從后向前拷貝,先拷貝5,覆蓋7,在拷貝4覆蓋6,這時候在拷貝3覆蓋5,拷貝2覆蓋4,拷貝1覆蓋3,由于3,4,5已經(jīng)拷貝完成,不會出現(xiàn)還沒有拷貝就被覆蓋的情況。

那是不是從后向前拷貝就一定正確呢?

我們在換一種情況試試:

這時候如果還是從后向前拷貝的話會出現(xiàn)什么問題呢?

8拷貝到6,7拷貝到5,這時候向拷貝6的時候已經(jīng)變成了8,因此從后向前失效了。

這時候我們在從前向后拷貝,3拷貝到1,4拷貝到2……恰好可以全部拷貝。

不知道大家有沒有發(fā)現(xiàn)一個規(guī)律:

如果dest在src的后面,則從后向前拷貝;

如果dest在src的前面,則從前向后拷貝;

如果沒有重疊,則隨意。

如果是 后->前,該怎么拷貝呢?

比如說先拷貝5,我們只需要在起始位置跳過num個字節(jié)即可

比如說:*((char*)src + num)

代碼實現(xiàn):

#include

#include

void* my_memmove(void* dest, const void* src, size_t num)

{

void* ret = dest;

if (dest < src)

{

//前->后

while (num--)

{

*(char*)dest = *(char*)src;

dest = (char*)dest + 1;

src = (char*)src + 1;

}

}

else

{

while (num--)

{

//后->前

//num進來減1,變?yōu)?9,src加上19后跳到最后一位上,也就是5,dest加上19跳到8的位置,然后將5賦值到8的位置

*((char*)dest + num) = *((char*)src + num);

}

}

return ret;

}

int main()

{

int arr[] = { 1,2,3,4,5,6,7,8,9,10 };

my_memmove(arr+2, arr, 5 * sizeof(int));

return 0;

}

三、memset函數(shù)的使用

1、memset函數(shù)的介紹(cplusplus)

參數(shù)介紹:注意:

memset是以字節(jié)為單位來設(shè)置內(nèi)存的 ,而不是以一個元素為單位設(shè)置的。

?作用介紹:

返回值介紹:

2、memset函數(shù)的使用

2.1 memset函數(shù)對數(shù)組的應(yīng)用

那么memset函數(shù)究竟有什么作用呢?

比如說:

#include

int main()

{

int arr[10] = { 0 };

int i = 0;

for (i = 0; i < 10; i++)

{

arr[i] = i + 1;

}

return 0;

}

我們想將arr數(shù)組全部初始化為0,我們該怎么做呢?

你可能會說這不簡單?直接使用循環(huán)不就可以了嗎?

for (i = 0; i < 10; i++)

{

arr[i] = 0;

}

這樣的確可以,不過我們也可以使用庫函數(shù)memset函數(shù)來實現(xiàn)這個操作。

我們要設(shè)置的這個空間整型數(shù)組arr[10]的地址交給ptr,而數(shù)組的地址就是數(shù)組名arr,我們需要將該數(shù)組的元素都變?yōu)?,也就是要設(shè)置的值value為0,由于是整型數(shù)組,有十個元素,所以num就等于40字節(jié)。

代碼展示:

#include

#include

int main()

{

int arr[10] = { 0 };

int i = 0;

for (i = 0; i < 10; i++)

{

arr[i] = i + 1;

}

/*for (i = 0; i < 10; i++)

{

arr[i] = 0;

}*/

memset(arr, 0, 10 * sizeof(int));

for (i = 0; i < 10; i++)

{

printf("%d ", arr[i]);

}

return 0;

}

調(diào)試過程:

結(jié)果展示:

?如果memset(arr, 1, 10 * sizeof(int));這是否是將每一個元素都改為1了呢?

調(diào)試監(jiān)控窗口

為什么沒有達到想要的結(jié)果呢?

我們在來看一下內(nèi)存窗口:

破案了,memset函數(shù)將每一個字節(jié)都設(shè)置為1,而不是把一個元素設(shè)置為1。

前面強調(diào)了memset是以字節(jié)為單位來設(shè)置內(nèi)存的 ,而不是以一個元素為單位設(shè)置的。

2.2 memset函數(shù)對字符串的應(yīng)用

代碼:

#include

#include

int main()

{

char arr[] = "hello world";

//如何將helo改為五個x

memset(arr, 'x', 5);

return 0;

}

調(diào)試結(jié)果:

如果我們想修改world呢?

memset(arr+6, 'x', 5);

從前向后數(shù)hello五個字符,還有一個空格,共6個字符。

注意:這個函數(shù)比較常見,因此需要熟練掌握!?。?

?四、memcmp函數(shù)的使用

memcmp函數(shù)與之前學(xué)習(xí)的strcmp函數(shù)的功能是比較相似的,不過strcmp函數(shù)只能用來做字符串的比較,而memcmp函數(shù)是用來做內(nèi)存塊的比較,不論是什么類型。

1、memcmp函數(shù)的介紹

參數(shù)介紹:?

返回值介紹:

2、memcmp函數(shù)的使用

直接上例題,比較arr1與arr2中前3個元素

#include

#include

int main()

{

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

int arr2[] = { 1,2,3,3 };

int ret = memcmp(arr1, arr2, 12);

printf("%d\n", ret);

return 0;

}

結(jié)果:

如果我們比較前4個元素呢?

int ret = memcmp(arr1, arr2, 16);、

這里返回的就是1了。

結(jié)語:本篇文章到這里就結(jié)束啦!期待下次的相遇??!

柚子快報激活碼778899分享:c語言 C:內(nèi)存函數(shù)

http://yzkb.51969.com/

好文鏈接

評論可見,查看隱藏內(nèi)容

本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點和立場。

轉(zhuǎn)載請注明,如有侵權(quán),聯(lián)系刪除。

本文鏈接:http://gantiao.com.cn/post/19534327.html

發(fā)布評論

您暫未設(shè)置收款碼

請在主題配置——文章設(shè)置里上傳

掃描二維碼手機訪問

文章目錄