深入探究 C 語言內存函數:memcpy、memmove、memset 和 memcmp

一,常見的內存函數

在 C 語言的編程世界里,對內存的高效操作至關重要。C 標準庫為我們提供了一系列強大的內存操作函數,其中?memcpymemmovememset?和?memcmp?這四個函數是處理內存數據的得力助手。接下來,讓我們深入了解它們的功能、使用方法以及適用場景。

1. memcpy:簡單直接的內存復制

功能

memcpy?函數的主要功能是從源內存地址復制指定數量的字節到目標內存地址。它不關心內存中的內容是否為字符串,只是單純地按字節進行復制。這使得它在復制數組、結構體等任意類型的數據時非常有用。

原型

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

這里的參數解釋如下:

  • dest:指向目標內存區域的指針,數據將被復制到這個位置。
  • src:指向源內存區域的指針,const?修飾表示該函數不會修改源內存中的內容。
  • n:要復制的字節數,這決定了復制操作的范圍。

返回值

函數返回指向目標內存區域?dest?的指針,方便我們進行鏈式操作或后續的內存使用。

示例代碼

#include <stdio.h>
#include <string.h>int main() {int src[] = {1, 2, 3, 4, 5};int dest[5];// 使用 memcpy 復制數組memcpy(dest, src, sizeof(src));// 輸出復制后的數組for (int i = 0; i < 5; i++) {printf("%d ", dest[i]);}printf("\n");return 0;
}

?

在這個示例中,我們使用?memcpy?將?src?數組的內容復制到?dest?數組中,通過?sizeof(src)?確保復制的字節數與源數組大小一致。

2. memmove:處理重疊內存的復制

功能

memmove?函數的功能和?memcpy?類似,也是從源內存地址復制指定數量的字節到目標內存地址。但它的優勢在于能夠處理源內存區域和目標內存區域有重疊的情況,會以一種安全的方式進行復制,避免數據覆蓋問題。

原型

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

參數的含義和?memcpy?相同。

返回值

同樣返回指向目標內存區域?dest?的指針。

示例代碼

#include <stdio.h>
#include <string.h>int main() {char str[] = "abcdefg";// 有重疊的內存復制memmove(str + 2, str, 3);printf("%s\n", str);return 0;
}

在這個例子中,我們將?str?字符串的前 3 個字符復制到從第 3 個字符開始的位置,由于存在內存重疊,使用?memmove?可以保證復制操作的正確性。

3. memset:內存區域的初始化利器

功能

memset?函數用于將指定內存區域的前?n?個字節設置為指定的值。這在初始化數組、結構體等內存區域時非常方便,比如將數組元素全部初始化為 0。

原型

void *memset(void *s, int c, size_t n);

參數說明如下:

  • s:指向要設置的內存區域的指針。
  • c:要設置的值,通常是一個字符或一個字節大小的整數,在內部會被轉換為?unsigned char?類型。
  • n:要設置的字節數。

返回值

返回指向被設置的內存區域?s?的指針。

示例代碼

#include <stdio.h>
#include <string.h>int main() {int arr[5];// 將數組元素全部初始化為 0memset(arr, 0, sizeof(arr));// 輸出初始化后的數組for (int i = 0; i < 5; i++) {printf("%d ", arr[i]);}printf("\n");return 0;
}

在這個示例中,我們使用?memset?將?arr?數組的所有元素初始化為 0,通過?sizeof(arr)?確定要設置的字節數。

4. memcmp:內存內容的比較工具

功能

memcmp?函數用于比較兩個內存區域的前?n?個字節。它按字節比較兩個內存區域的內容,并返回一個表示大小關系的值,常用于比較數組、結構體等數據是否相等。

原型

int memcmp(const void *s1, const void *s2, size_t n);

?

參數解釋如下:

  • s1:指向第一個內存區域的指針。
  • s2:指向第二個內存區域的指針。
  • n:要比較的字節數。

返回值

  • 如果?s1?所指向的內存區域小于?s2?所指向的內存區域,返回一個負整數。
  • 如果兩個內存區域相等,返回 0。
  • 如果?s1?所指向的內存區域大于?s2?所指向的內存區域,返回一個正整數。

示例代碼

#include <stdio.h>
#include <string.h>int main() {int arr1[] = {1, 2, 3};int arr2[] = {1, 2, 3};// 比較兩個數組int result = memcmp(arr1, arr2, sizeof(arr1));if (result == 0) {printf("兩個數組相等\n");} else {printf("兩個數組不相等\n");}return 0;
}

總結

memcpymemmovememset?和?memcmp?這四個內存函數在 C 語言編程中各有其獨特的用途。memcpy?適用于簡單的非重疊內存復制,memmove?則是處理重疊內存復制的首選,memset?能高效地初始化內存區域,memcmp?可用于比較內存內容。熟練掌握這些函數,能讓我們在處理內存數據時更加得心應手,編寫出高效、穩定的 C 語言程序。

?

二,模擬實現memcpymemmovememset?和?memcmp內存函數

1. 模擬?memcpy

代碼實現
#include <stdio.h>// 模擬 memcpy 函數
void* my_memcpy(void* dest, const void* src, size_t n) {char* d = (char*)dest;const char* s = (const char*)src;for (size_t i = 0; i < n; i++) {d[i] = s[i];}return dest;
}int main() {int arr1[] = {1, 2, 3};int arr2[3];my_memcpy(arr2, arr1, sizeof(arr1));for (int i = 0; i < 3; i++) {printf("%d ", arr2[i]);}return 0;
}
詳細講解
  • 功能:把源內存區域的數據復制到目標內存區域。
  • 參數處理:將?dest?和?src?強制轉換為?char*?類型,因為?char?是 1 字節,方便按字節操作。
  • 復制過程:通過?for?循環,從源地址逐字節復制到目標地址,共復制?n?個字節。
  • 返回值:返回目標內存區域的指針。

2. 模擬?memmove

代碼實現
#include <stdio.h>// 模擬 memmove 函數
void* my_memmove(void* dest, const void* src, size_t n) {char* d = (char*)dest;const char* s = (const char*)src;if (d < s) {// 目標地址在源地址前面,從前往后復制for (size_t i = 0; i < n; i++) {d[i] = s[i];}} else {// 目標地址在源地址后面,從后往前復制,避免覆蓋for (size_t i = n; i > 0; i--) {d[i - 1] = s[i - 1];}}return dest;
}int main() {char str[] = "abcdefg";my_memmove(str + 2, str, 3);printf("%s\n", str);return 0;
}
詳細講解
  • 功能:和?memcpy?類似,但能處理內存重疊的情況。
  • 內存重疊判斷:若?dest?地址小于?src?地址,從前往后復制;反之,從后往前復制。
  • 復制過程:根據判斷結果,使用?for?循環進行逐字節復制。
  • 返回值:返回目標內存區域的指針。

3. 模擬?memset

代碼實現
#include <stdio.h>// 模擬 memset 函數
void* my_memset(void* s, int c, size_t n) {char* p = (char*)s;for (size_t i = 0; i < n; i++) {p[i] = (char)c;}return s;
}int main() {int arr[5];my_memset(arr, 0, sizeof(arr));for (int i = 0; i < 5; i++) {printf("%d ", arr[i]);}return 0;
}
詳細講解
  • 功能:將指定內存區域的前?n?個字節設置為指定的值。
  • 參數處理:將?s?強制轉換為?char*?類型,方便按字節操作。
  • 設置過程:通過?for?循環,將每個字節設置為?c(轉換為?char?類型)。
  • 返回值:返回被設置的內存區域的指針。

4. 模擬?memcmp

代碼實現
#include <stdio.h>// 模擬 memcmp 函數
int my_memcmp(const void* s1, const void* s2, size_t n) {const char* p1 = (const char*)s1;const char* p2 = (const char*)s2;for (size_t i = 0; i < n; i++) {if (p1[i] != p2[i]) {return p1[i] - p2[i];}}return 0;
}int main() {int arr1[] = {1, 2, 3};int arr2[] = {1, 2, 3};int result = my_memcmp(arr1, arr2, sizeof(arr1));printf("%d\n", result);return 0;
}
詳細講解
  • 功能:比較兩個內存區域的前?n?個字節。
  • 參數處理:將?s1?和?s2?強制轉換為?char*?類型,方便按字節比較。
  • 比較過程:通過?for?循環逐字節比較,若發現不同字節,返回它們的差值。
  • 返回值:若都相同返回 0;若?s1?大于?s2?返回正數;若?s1?小于?s2?返回負數。

??????????????????????????????????? 以上就是詳細講解了模擬實現內存函數的例子

希望這篇文章能幫助你更好地理解和使用這些重要的 C 語言內存函數!如果你在使用過程中遇到任何問題,歡迎在評論區留言交流。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/70724.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/70724.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/70724.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Java 集合

Java 集合 在 Java 編程中&#xff0c;集合框架&#xff08;java.util 包&#xff09;是處理一組對象的強大工具。與數組不同&#xff0c;集合提供了更靈活的數據存儲和操作方式。本文將詳細介紹 Java 集合框架的核心接口、常用實現類及其應用場景&#xff0c;幫助你更好地理解…

go基本語法

跟Java比較學習。 hello word 示例代碼 test1.go文件&#xff1a; // 包路徑 package main// 導入模塊&#xff0c;下面兩種都行 import ("fmt" ) import "log"// main方法 func main() {log.Print("hello word !!!")fmt.Print("hello …

【Docker】如何在Linux、Windows、MacOS中安裝Docker

Linux安裝Docker 在終端中執行一鍵安裝腳本命令安裝docker sudo curl -fsSL https://gitee.com/tech-shrimp/docker_installer/releases/download/latest/linux.sh | bash -s docker --mirror Aliyun1.1 配置docker鏡像源 在終端執行 一行命令&#xff0c;編輯配置文件 sudo …

2.24力扣-回溯電話號碼的字母組合

17. 電話號碼的字母組合 - 力扣&#xff08;LeetCode&#xff09; class Solution {List<String> ans new LinkedList<>();StringBuilder temp new StringBuilder();public List<String> letterCombinations(String digits) {if(digitsnull || digits.leng…

Cocos Creator Shader入門實戰(一):材質和Effect的了解

引擎版本&#xff1a;3.8.5 環境&#xff1a; Windows 簡介 在Cocos Creator中&#xff0c;游戲炫彩繽紛的效果是借助著色器(Shader)來實現的。 Cocos主要基于OpenGL ES&#xff0c;而Shader的編寫則是在可編程渲染管線中基于修改&#xff1a;頂點著色器(Vertex) 和 片段著色…

akka現有的分布式定時任務框架總結

根據你的需求&#xff0c;以下是一些基于 Akka 實現的分布式定時任務框架&#xff0c;以及相關的 GitHub 項目推薦&#xff1a; 1. Openjob Openjob 是一個基于 Akka 架構的新一代分布式任務調度框架&#xff0c;支持多種定時任務、延時任務、工作流設計&#xff0c;采用無中…

微信小程序地圖map全方位解析

微信小程序地圖map全方位解析 微信小程序的 <map> 組件是一個功能強大的工具&#xff0c;可以實現地圖展示、定位、標注、路徑規劃等多種功能。以下是全方位解析微信小程序地圖組件的知識點&#xff1a; 一、地圖組件基礎 1. 引入 <map> 組件 在頁面的 .wxml 文…

Python的PyTorch+CNN深度學習技術在人臉識別項目中的應用

人臉識別技術是一種基于人臉特征進行身份識別的生物識別技術&#xff0c;其核心原理包括人臉檢測、人臉對齊、特征提取、特征匹配、身份識別。 一、應用場景 安防&#xff1a;門禁、監控。 金融&#xff1a;刷臉支付、身份驗證。 社交&#xff1a;自動標注、美顏。 醫療&am…

《數據庫索引設計與優化》譯本錯誤糾正(1)

今天在學習《數據庫索引設計與優化》第十一章第198頁的時候遇到一個問題&#xff0c;即參數的文字描述與實際不符。我看的是從網絡上找到的譯本&#xff0c;許多喜歡白嫖的朋友可能也會像我一樣遇到這種問題。 可以看到&#xff0c;上面對參數Z的描述是&#xff1a;Z上一次索引…

API測試工具:Swagger vs Postman 2025最新全面對比

隨著微服務架構的普及和云原生應用的激增&#xff0c;高效的 API 開發、測試和文檔管理工具變得越來越重要。在眾多 API 工具中&#xff0c;Swagger 和 Postman 各自以不同的方式解決著 API 開發生命周期中的關鍵問題&#xff0c;本文將從多個維度深入對比這兩款工具&#xff0…

如何查詢SQL Server數據庫服務器的IP地址

如何查詢SQL Server數據庫服務器的IP地址 作為數據庫管理員或開發人員&#xff0c;了解如何查詢SQL Server數據庫服務器的IP地址是一項重要技能。本文將介紹幾種簡單而有效的方法&#xff0c;幫助你輕松獲取這一信息。無論你是新手還是經驗豐富的專業人士&#xff0c;這些方法…

centos 7 安裝python3 及pycharm遠程連接方法

安裝openssl 使用pip3安裝 virtualenv的時候會提示WARNING: pip is configured with locations that require TLS/SSL, however the ssl module in Python is not available. 這是因為缺少openssl 2.0以上版本 解決辦法&#xff1a; 一、先確認版本 openssl version 二、安…

AI人工智能之機器學習sklearn-數據預處理和劃分數據集

1、概要 本篇學習AI人工智能之機器學習sklearn數據預處理和劃分數據集&#xff0c;從代碼層面講述如何進行數據的預處理和數據集劃分。 2、簡介 本片講述數據預處理的標準化處理、歸一化處理&#xff0c;以常用的兩個類為例 標準化處理類 StandardScaler歸一化處理類 MinMax…

智能硬件-01智能停車場

行業背景 隨著現代人們生活水平的提高&#xff0c;私家車輛在不斷增加&#xff0c;小區將面臨著臨時車用戶要多于固定車用戶的窘境&#xff0c;尤其是在早晚高峰時段車輛出入擁堵&#xff0c;對小區的車輛管理難度越來越大&#xff0c;對停車場收費員的崗位要求越來越高&#…

定長內存池的實現、測試及錯誤分析

背景 C/C 申請內存使用的是 malloc &#xff0c;malloc 其實就是一個大眾貨&#xff0c;什么場景下都可以用&#xff0c;但是什么場景下都可以用就意味著什么場景下都不會有很高的性能。 定長內存池解決固定大小的內存申請釋放需求&#xff0c; 性能達到極致&#xff0c;不考…

vue3 下載文件 responseType-blob 或者 a標簽

在 Vue 3 中&#xff0c;你可以使用 axios 或 fetch 來下載文件&#xff0c;并將 responseType 設置為 blob 以處理二進制數據。以下是一個使用 axios 的示例&#xff1a; 使用 axios 下載文件 首先&#xff0c;確保你已經安裝了 axios&#xff1a; npm install axios然后在你…

Search API:讓數據獲取變得簡單高效的搜索引擎代理商

Search API&#xff1a;讓數據獲取變得簡單高效的搜索引擎代理商 在當今數字化時代&#xff0c;數據驅動的決策變得越來越重要&#xff0c;而獲取精準、實時的數據是眾多企業、研究機構和開發者的核心需求。然而&#xff0c;直接爬取搜索引擎或行業資訊網站可能會遇到諸多挑戰&…

halcon三維對象處理例程總結(二)

目錄 一、intersect_plane_object_model_3d二、interactive_intersection三、measure_plant四、moments_object_model_3d五、projective_trans_object_model_3d六、read_object_model_3d_generic_ascii一、intersect_plane_object_model_3d 計算三維物體模型與平面之間的相交部…

基于 Python 的項目管理系統開發

基于 Python 的項目管理系統開發 一、引言 在當今快節奏的工作環境中&#xff0c;有效的項目管理對于項目的成功至關重要。借助信息技術手段開發項目管理系統&#xff0c;能夠顯著提升項目管理的效率和質量。Python 作為一種功能強大、易于學習且具有豐富庫支持的編程語言&…

2月24(信息差)

&#x1f30d;“任意舞蹈任意學”&#xff01;宇樹機器人又進化了 傳Meta有意合作拋出橄欖枝 &#x1f384;兩部門&#xff1a;深入推進公路沿線充電基礎設施建設 推動大功率充電技術標準應用 ?小米15 Ultra、小米SU7 Ultra定檔2月27日 雷軍宣布&#xff1a;向超高端進發 1.…