深度解析C語言內存函數(小米面試題)

目錄

  • 一、memcpy
    • 1.1 代碼演示
    • 1.2 memcpy的模擬實現
  • 二、memmove
    • 2.1 代碼演示
    • 2.2 模擬實現(小米面試題)
  • 三、memset
    • 3.1 代碼演示
    • 3.2 總結
  • 四、memcmp
    • 4.1 代碼演示
    • 4.2 總結
  • 總結


一、memcpy

(memory copy 內存復制)
之前文章中寫的strcpy,strncpy函數是用來拷貝字符串的,是有局限性的,那么如何拷貝一個整型數組,或者結構體數組呢?
字符函數與字符串函數(上)
字符函數與字符串函數(下)
這就要用到memcpy了

void* memcpy( void* destination,const void* source,size_t num );

功能

  • memcpy是完成內存塊拷貝的,不關注內存中存放的數據是啥
  • 函數memcpy從source的位置開始向后復制num個字節的數據到destination指向的內存位置
  • 如果source和destination有任何的重疊,復制的結果都是未定義的
    (內存重疊的情況使用memmove就行)
  • memcpy的使用需要包含<string.h>

參數
destination:指針,指向目標空間,拷貝的數據存放在這里
source:指針,指向源空間,要拷貝的數據從這里來
num:要拷貝的數據占據的字節數

返回值
拷貝完成后,返回目標空間的起始地址

1.1 代碼演示

在這里插入圖片描述
這里再展示一個浮點數的拷貝
在這里插入圖片描述
這里數據顯示的原因是浮點數在內存中無法精確保存,數組中的浮點數都要轉換為二進制存到內存中去,這里小數點后的2轉換為二進制很難,很可能寫到50位都無法精確湊齊0.2
在這里插入圖片描述
當然這里不知道多少個字節也可以算一下:
在這里插入圖片描述

1.2 memcpy的模擬實現

在這里插入圖片描述

在這里插入圖片描述

乍一看,是不是覺得已經漂亮的實現了,實則暗藏漏洞
在這里插入圖片描述
假設這里source空間的數據是1,2,3,4,5,覆蓋到3,4,5,6,7上
結果如圖:
在這里插入圖片描述
預想情況下的覆蓋情況應該是1 2 1 2 3 4 5 8 9 10,這里卻是1 2 1 2 1 2 1 8 9 10
在這里插入圖片描述
這里當3,4被1,2覆蓋了之后,3就變為1,4就變為2,此時* (char* )src走到3的時候,走完4個字節就是1覆蓋5,再往后就是變為2的4覆蓋6,變為1的5覆蓋7。所以就會監視就會出現這樣的數據結果。

這就是另一種場景(內存重疊的情況使用memmove就行),但是呢這里memcpy又能正常的完成該場景的要求,也就是超常發揮了,500塊的實力干了100塊的活,這就是內卷。
在這里插入圖片描述


二、memmove

(memory move 內存移動)

void* memmove( void* destination,const void* source,size_t num );

功能

  • memmove函數也是完成內存塊拷貝的
  • 和memcpy的差別就是memmove函數處理的源內存塊和目標內存塊是可以重疊的
  • memmove的使用需要包含<string.h>

參數返回值與memcpy是一樣的

2.1 代碼演示

在這里插入圖片描述
在這里插入圖片描述

2.2 模擬實現(小米面試題)

內存重疊拷貝根據memcpy寫的內容有兩種情況

第一種情況

在這里插入圖片描述
這里src<dest(數組隨著下標的增長,地址是由低向高變化的),就必須從src的末尾數據5開始,向著dest的末尾數據7從后向前拷貝,否則從前向后拷貝就會出現1 2 1 2 3 4 5 8 9 10的情況。

第二種情況

在這里插入圖片描述
當dest<src的時候,就必須從src的其實數據3開始,向著dest的起始數據1開始從前向后拷貝。這樣才不會出錯。

memmove底層邏輯也是基于這些情況實現的
memmove的拷貝是分三種情景的

第一種情景

在這里插入圖片描述
這里是dest<src的情景,需要從前向后拷貝

第二種情景

在這里插入圖片描述
這里是src<dest,需要從后向前拷貝
前兩種情景都是dest與src有內存重疊的情況下的考量。
在這里插入圖片描述
第三種情況dest的內存與src的內存已經完全脫離了,無論哪種拷貝方式都是可以的。
在這里插入圖片描述
這里給每種情景標號。

寫代碼的方案就可以分兩種

  1. 1,3從前向后拷貝,2從后向前拷貝
  2. 1 從前向后拷貝,2,3從后向前拷貝

我個人還是覺得方案二更好一些,找 1 與 2 3 的邊界就夠,方案一則要找1與2的邊界,2與3的邊界,相對麻煩。

#include<assert.h>
void* my_memmove(void* dest, const void* src, size_t num)
{assert(dest && src);void* ret = dest;if (dest < src)//1{//從前向后拷貝while (num--){*(char*)dest = *(char*)src;dest = (char*)dest + 1;src = (char*)src + 1;}}else{//從后向前拷貝while (num--){//跳過19個字節,指向第20個字節*((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, 20);my_memmove(arr, arr + 2, 20);return 0;
}

這里再說一下這里類型轉換的問題

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

在表達式 (char*)src + 1 中:
(char* )src:將 src(const void* 類型)臨時轉換為 const char* 類型。
結果類型:表達式 (char* )src + 1 的結果類型是 const char*,指向原地址后一個字節的位置。

在賦值語句 src = (char*)src + 1; 中:
左值 src:類型為 const void*(函數參數類型)。
右值 (char* )src + 1:類型為 const char* 。
C 語言允許將任意類型的指針隱式轉換為 void* 或 const void* ,因此 const char* 可以直接賦值給 const void* ,無需顯式強制類型轉換。


三、memset

(memory move 內存設置)

void* memset( void* ptr,int value,size_t num );

功能

  • memset函數是用來設置內存塊的內容的,將內存中指定長度的控件設置為特定的內容。
  • memset的使用需要包含<string,h>

參數
ptr:指針,指向要設置的內存空間,也就是存放了要設置的內存空間的起始地址。
value:要設置的值,函數將會把value值轉換成unsigned char的數據進行設置的。也就是以字節為單位來設置內存塊的。
num:要設置的內存長度,單位是字節。

返回值:返回的是要設置的內存空間的起始地址。

3.1 代碼演示

在這里插入圖片描述
這是一個字符數組元素的設置,那么整型數組元素能不能設置呢?
在這里插入圖片描述

在這里插入圖片描述
可以看到是不可以的,memset是以字節為單位設置的,它把每一個字節設置為01,也就是1,而1的16進制的表示是0x 00 00 00 01,所以是達不到所設想的要求的。

但是它可以把整型數組的每個元素設置為0
在這里插入圖片描述
它把每個字節設置為0,每個元素也就會變為0了。

3.2 總結

當有一塊內存空間需要設置內容的時候,就可以使用memset函數,值得注意的是memset函數對內存單元的設置是以字節為單位的。

四、memcmp

(memory compare)

int memcmp( const void* ptr1,const void* ptr2,size_t num );

功能
比較指定的兩塊內存塊的內容,比較從ptr1和ptr2指針指向的位置開始,向后的num個字節。
memcmp的使用需要包含<string.h>

參數
ptr1:指針,指向一塊待比較的內存塊。
ptr2:指針,指向另一塊待比較的內存塊。
num:指定的比較長度,單位是字節。

返回值

返回一個整數值,指示內存塊內容之間的關系:

返回值含義說明
< 0兩個內存塊中第一個不匹配字節,在 ptr1 中對應的值(按 unsigned char 值計算)小于在 ptr2 中的值
0兩個內存塊的內容相等
> 0兩個內存塊中第一個不匹配字節,在 ptr1 中對應的值(按 unsigned char 值計算)大于在 ptr2 中的值

4.1 代碼演示

這里比較前16個字節相等
在這里插入圖片描述
但如果比較前17個呢?
在這里插入圖片描述
結果如預期所設想。

4.2 總結

如果要比較2塊內存空間的數據的大小,可以使用memcmp函數,這個函數的特點就是可以指定比較長度。
memcmp函數是通過返回值告知大小關系的。


總結

以上就是C語言內存函數的全部內容了,下午也是上網沖浪的時候發現了小米的暑期實習面試題有我所寫的內容,也是非常開心哈哈,畢竟證明了自己所學都是有價值的,而且是貼近就業的,喜歡作者文章的靚仔靚女們不要忘記一鍵三連支持一下~
你們的支持就是我最大的動力。

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

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

相關文章

DK124反激式開關電源芯片

18W 高性能交直流轉換芯片 特性 DK124 是一款離線式開關電源芯片&#xff0c;最大輸出功率達到 24W。內部集成了 PWM 控制器、700V 功率管和初級峰值電流檢測電路&#xff0c;并采用了可以省略輔助供電繞組的專利自供電技術&#xff0c;極大簡化了外圍應用電路&#xff0c;減…

商品銷售數據分析實驗

進入虛擬機&#xff0c;啟動HDFS和Yarn1.創建表 hive show databases; use test;銷售訂單表create table t_dml (detail_id bigint,sale_date date, province string,city string,product_id bigint,cnt bigint,amt double )row format delimited fields terminated by ,;商品…

PH熱榜 | 2025-07-08

1. TensorBlock Forge 標語&#xff1a;人工智能模型的API 介紹&#xff1a;Forge是一個快速且安全的工具&#xff0c;讓你可以跨不同供應商連接和運行AI模型 產品網站&#xff1a; 立即訪問 Product Hunt&#xff1a; View on Product Hunt 票數&#xff1a; &#x1f53a…

2025-01)electronjs-v11.2.0升級到新版本electronjs-v37.2.0記錄,node版本記錄,淘寶鏡像配置記錄,升級記錄

背景:由于22年使用electronjs開發的自助機客戶端幾年沒去維護,現在有需求要修改,電腦也換新了,node環境也沒,直接把electron從 之前的 11.2.0 版本 升級到了37.2.0版本,升級最主要的目的是升級谷歌瀏覽器內核,升級后谷歌瀏覽器內核直接從87升級到了138,可以支持谷歌最新…

iQOO手機怎樣相互遠程控制?其他手機可以遠程控制iQOO嗎?

iQOO是Vivo同一品牌下的產品&#xff0c;它們兩款手機都可以使用手機內置的遠程控制功能。具體做法是&#xff0c;打開控制端的iQOO手機的【設置】【快捷與輔助】、【遠程協助】&#xff0c;然后輸入被控端的電話號碼&#xff0c;等被控端的手機接受遠程協助后&#xff0c;就可…

【入門級-C++程序設計:3、程序基本語句-多層循環語句】

1、定義&#xff1a; 在 C 中&#xff0c;多層循環&#xff08;嵌套循環&#xff09;是指在一個循環體內包含另一個或多個循環語句。它常用于處理多維數據結構&#xff08;如二維數組&#xff09;、復雜的迭代邏輯&#xff08;如矩陣運算、圖形打印、組合遍歷等&#xff09;。多…

四、jenkins自動構建和設置郵箱

一、jenkins自動構建什么自動構建、有啥用&#xff1a;觸發方式代碼提交&#xff08;Git push&#xff09;定時任務&#xff08;如每天凌晨構建&#xff09;手動點擊等方式&#xff08;立即執行&#xff09;執行內容從 Git/SVN 拉取最新代碼運行編譯&#xff08;如 Maven/Gradl…

【深度學習新浪潮】深入解析LLM關鍵概念:架構、優化與最新研究進展

1. Transformer架構與注意力機制 概念解析 Transformer是LLM的核心架構,由編碼器和解碼器組成,其核心創新是自注意力機制,通過計算輸入序列中每個位置的關聯權重,動態聚焦關鍵信息。自注意力機制的計算復雜度為O(n),在處理長序列時成為性能瓶頸。 代碼示例:基礎Transfo…

RAGflow圖像解析與向量化分析

RAGflow圖像解析與向量化分析 注:需要提前部署好ragflow,才方便一 一對應代碼,部署教程:rag部署教程,這樣才會方便后續更改 1. 圖像解析流程 RAGflow通過多種解析器處理不同類型的文檔,其中圖像解析是一個重要組成部分。以下是RAGflow處理圖像的主要流程: 1.1 PDF文…

千翼破界,百景賦能 | 2025深圳eVTOL展無人機場景應用專場即將啟幕

在技術革新、應用深化、產業鏈協同升級及低空空域管理改革等多重政策紅利驅動下&#xff0c;我國工業級無人機產業正邁入爆發式增長新階段&#xff0c;持續引領民用無人機市場繁榮。數據顯示&#xff0c;2019 至2024年&#xff0c;我國民用無人機市場規模從435.1億元躍升至1108…

Go語言標識符命名規則詳解:工程化實踐

引言 Go語言的命名規則是其簡潔哲學和工程實用性的集中體現。下面從語法規范、最佳實踐到實際應用進行全面解析&#xff1a; 一、基礎命名規則 1. 變量命名 // 小駝峰式&#xff08;lowerCamelCase&#xff09; var userName string var maxRetryCount 3 var isConnected bool…

RISC-V:開源芯浪潮下的技術突圍與職業新賽道 (一)為什么RISC-V是顛覆性創新?

第一篇&#xff1a;開篇&#xff1a;為什么RISC-V是顛覆性創新&#xff1f; 打破70年架構壟斷&#xff0c;開源硬件如何重塑芯片產業規則&#xff1f;一、傳統架構的“圍城之困”&#xff08;痛點切入&#xff09; ARM/X86的統治代價 授權費暴利模型 &#xff1a; ARM指令集授權…

【機器學習筆記 Ⅱ】7 多類分類

1. 多類分類&#xff08;Multi-class Classification&#xff09; 定義 多類分類是指目標變量&#xff08;標簽&#xff09;有超過兩個類別的分類任務。例如&#xff1a; 手寫數字識別&#xff1a;10個類別&#xff08;0~9&#xff09;。圖像分類&#xff1a;區分貓、狗、鳥等。…

2025年深圳杉川機器人性格測評和Verify測評SHL題庫高分攻略

1、杉川機器人包含性格測評和Verify測評&#xff0c;預計用時60min&#xff0c;請確保作答時周圍環境無干擾、網絡暢通&#xff1b;2、請使用電腦完成作答&#xff0c;建議使用以下瀏覽器登錄&#xff1a;IE9.0及以上版本&#xff0c;火狐&#xff0c;谷歌&#xff1b;3、杉川機…

【flutter 在最新版本中已經棄用了傳統的 apply from 方式引入 Gradle 插件】

報錯 Flutter assets will be downloaded from https://storage.flutter-io.cn. Make sure you trust this source! Launching lib\main.dart on 2112123AC in debug mode... Running Gradle task assembleDebug...FAILURE: Build failed with an exception.* Where: Script D…

Web后端實戰:(部門管理)

1.準備工作 1.1開發規范 1.1.1前后端分離開發 我們目前基本都是采用的前后臺分離開發方式&#xff0c;如下圖所示&#xff1a; 那么基于前后臺分離開發的模式下&#xff0c;我們后臺開發者開發一個功能的具體流程如何呢&#xff1f;如下圖所示&#xff1a; 需求分析&…

字節尋址(Byte Addressing) 與 Verilog中的寄存器索引

字節尋址&#xff08;Byte Addressing&#xff09; 與 Verilog中的寄存器索引 之間的關系。 您的疑問非常正確&#xff0c;直接看 3h1 很容易讓人以為地址就是 0x01。 但答案是&#xff1a;是的&#xff0c;3h1 在這里對應的字節地址&#xff08;Byte Address&#xff09;確實是…

Ubuntu遠程桌面

方法1: 檢查并使用已安裝的VNC或遠程桌面組件 請在終端中執行以下命令檢查系統中已安裝的相關組件: bash# 檢查系統中已安裝的VNC和遠程桌面相關軟件 dpkg -l | grep -E "vnc|vino|remote|rdp"# 檢查常見遠程桌面服務 which vino-server tigervncserver x11vnc xr…

WEB攻防-文件包含LFIRFI偽協議編碼算法無文件利用黑白盒

知識點&#xff1a; 1、文件包含-原理&分類&危害-LFI&RFI 2、文件包含-利用-黑白盒&無文件&偽協議 一、演示案例-文件包含-原理&分類&利用 1、原理 程序開發人員通常會把可重復使用的函數寫到單個文件中&#xff0c;在使用某些函數時&#xff…

LabVIEW的GPIB儀器校準

基于LabVIEW開發平臺與 GPIB 總線技術&#xff0c;采用是德科技、泰克等硬件設備&#xff0c;構建示波器與頻譜分析儀自動校準系統。通過圖形化編程實現校準流程自動化&#xff0c;涵蓋設備連接、參數配置、數據采集、誤差分析及報告生成&#xff0c;顯著提升校準效率與精度&am…