【零基礎C語言】內存函數

前言:

我們之前學過strcpy,strcmp等等函數,他們可以拷貝字符串和比較字符串等等,那么有沒有什么函數不光可以拷貝字符串還可以拷貝其他的數據呢,答案就是內存函數。

相較于字符串函數,內存函數可以拷貝的數據類型不受限制,故名思意,內存函數就是直接操作內存塊的,因此任何類型的數據都可以進行操作,那么接下來我們需要學習的內存函數有memcpy,memmove,memset,memcmp。

memcpy

memcpy函數是一個內存拷貝函數,它可以將一塊內存的數據拷貝給另一塊內存,以下是它的函數原型:?

?該函數存在三個參數:

  1. dest:指向目標內存,簡單說就是我們需要拷貝的數據存放的對象,比如我們像把數組1的數據拷貝給數組2,那么數組2就是拷貝的目標
  2. src:指向拷貝的來源,就是我們數據拷貝的來源,借用上面的例子就是數組1
  3. num:需要我們傳入拷貝的內存大小,以字節為單位,比如說我們要拷貝一個int類型,那么num就需要傳入4,或者sizeof(int)。

函數使用代碼展現:?

// 內存函數 
// memcpy 
int main()
{// 來源數組1int arr1[] = { 0,1,2,3,4,5,6,7,8,9,10 };// 目標數組2int arr2[20] = { 0 };// 拷貝memcpy(arr2, arr1, 11 * sizeof(int));// 打印for (int i = 0; i < 20; i++){printf("%d ", arr2[i]);}return 0;
}

運行結果:?

這邊注意我們拷貝的目標數組的容量一定要大于或者等于拷貝數據的大小,否則會出現錯誤。

?了解了使用方法后,讓我們來自己實現這個函數的功能把。

函數分析:?

?通過函數模型知道我們也需要dst,src指針指向目標和來源,num傳入拷貝的大小(以字節為單位)。

void* my_memcpy(void* dst, const void* src, size_t num)
{void* ret = dst;while (num--){*(char*)dst = *(char*)src; // 用char*進行強轉保障每次的拷貝是一個字節// 建議寫法1,不可以直接++// 寫法1/*dst = (char*)dst + 1;src = (char*)src + 1;*/// 寫法2((char*)dst)++;((char*)src)++;}return ret;
}

?memmove

memmove函數的使用方法和功能和memcpy基本一致,唯一有區別的是,如果按照我們上面實現memcpy函數的方法,我們是無法實現內存重疊的拷貝的,什么是內存重疊呢,我們來看下面一段代碼:?

int main()
{int arr[] = { 1,2,3,4,5,6,7,8,9,10 };my_memcpy(arr+2, arr, 5 * sizeof(int));for (int i = 0; i < 10; i++){printf("%d ", arr[i]);}return 0;
}

?我們自己拷貝給自己,arr代表數組首元素地址,arr+2指向的就是3,我們需要將1,2,3,4,5,從3的位置拷貝上去。

?最后的拷貝如上圖,但是實際我們運行時如下圖。

?因為拷貝的時候都是從頭到尾,會發生覆蓋問題,為了解決這樣內存塊重疊拷貝的問題,推出了memmove函數,當然現在在VS上的memcpy也可以解決這樣的問題,但是涉及內存塊重疊拷貝還是建議使用memmove函數。

函數原型:?

?該函數存在三個參數:

  1. dest:指向目標內存,簡單說就是我們需要拷貝的數據存放的對象,比如我們像把數組1的數據拷貝給數組2,那么數組2就是拷貝的目標
  2. src:指向拷貝的來源,就是我們數據拷貝的來源,借用上面的例子就是數組1
  3. num:需要我們傳入拷貝的內存大小,以字節為單位,比如說我們要拷貝一個int類型,那么num就需要傳入4,或者sizeof(int)。

?函數使用代碼展現:

int main()
{int arr[] = { 1,2,3,4,5,6,7,8,9,10 };memmove(arr + 2, arr, 5 * sizeof(int));for (int i = 0; i < 10; i++){printf("%d ", arr[i]);}return 0;
}

?運行結果:?

?代碼實現:

void* my_memmove(void* dst, const void* src, size_t num)
{void* ret = dst;if (dst < src){//前->后while (num--){*(char*)dst = *(char*)src;dst = (char*)dst + 1;src = (char*)src + 1;}}else{// 后->前while (num--){*((char*)dst + num) = *((char*)src + num);}}return ret;
}int main()
{int arr[] = { 1,2,3,4,5,6,7,8,9,10 };my_memmove(arr+4, arr+2, 5 * sizeof(int));for (int i = 0; i < 10; i++){printf("%d ", arr[i]);}return 0;
}

?memset

?memset是?來設置內存的,將內存中的值以字節為單位設置成想要的內容

int main ()
{
char str[] = "hello world";
memset (str,'x',6);
printf(str);
return 0;
}

?因為是以每一個字節取設置內存,對于其他存儲高于一個字節的類型只能初始化,不可以設置其他的值,會產生錯誤:

int main()
{int arr[10];memset(arr, 0, 10*sizeof(int));for (int i = 0; i < 10; i++){printf("%d ", arr[i]);}return 0;
}

int main()
{int arr[10];memset(arr, 1, 10*sizeof(int));for (int i = 0; i < 10; i++){printf("%d ", arr[i]);}return 0;
}

?

memcmp?

?較從ptr1和ptr2指針指向的位置開始,向后的num個字節,內存函數的比較也是一個字節一個字節的比較。

函數原型:

#include <stdio.h>
#include <string.h>
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 < 0)
printf("'%s' is less than '%s'.\n", buffer1, buffer2);
else
printf("'%s' is the same as '%s'.\n", buffer1, buffer2);
return 0;
}

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

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

相關文章

贖金信[簡單]

優質博文&#xff1a;IT-BLOG-CN 一、題目 給你兩個字符串&#xff1a;ransomNote和magazine&#xff0c;判斷ransomNote能不能由magazine里面的字符構成。如果可以&#xff0c;返回true&#xff1b;否則返回false。magazine中的每個字符只能在ransomNote中使用一次。 示例 …

DPDK實踐之(1)dpdk基礎使用

DPDK實踐之(1)dpdk基礎使用 Author: Once Day Date: 2024年5月19日 一位熱衷于Linux學習和開發的菜鳥&#xff0c;試圖譜寫一場冒險之旅&#xff0c;也許終點只是一場白日夢… 漫漫長路&#xff0c;有人對你微笑過嘛… 全系列文檔可參考專欄&#xff1a;Linux基礎知識_Once…

java判斷日期格式的正則表達式

java判斷日期格式的正則表達式 在Java中&#xff0c;你可以使用String類的matches()方法來檢查一個字符串是否匹配特定的正則表達式。以下是一個用于判斷日期格式是否為YYYY-MM-DD的正則表達式的例子&#xff1a; public class DateValidator { public static boolean isVal…

C語言 | Leetcode C語言題解之第109題有序鏈表轉換二叉搜索樹

題目&#xff1a; 題解&#xff1a; int getLength(struct ListNode* head) {int ret 0;while (head ! NULL) {ret, head head->next;}return ret; }struct TreeNode* buildTree(struct ListNode** head, int left, int right) {if (left > right) {return NULL;}int …

Mac維護神器CleanMyMac X成為你的蘋果電腦得力助手

在數字化時代&#xff0c;Mac電腦已成為眾多用戶的首選。然而&#xff0c;隨著頻繁的使用和數據量的日益增長&#xff0c;許多Mac用戶面臨著系統雜亂、存儲空間不足以及隱私保護等問題。幸運的是&#xff0c;"CleanMyMac X"這款優化和清理工具應運而生&#xff0c;它…

ROCm上情感分析:使用循環神經網絡

15.2. 情感分析&#xff1a;使用循環神經網絡 — 動手學深度學習 2.0.0 documentation (d2l.ai) 代碼 import torch from torch import nn from d2l import torch as d2lbatch_size 64 train_iter, test_iter, vocab d2l.load_data_imdb(batch_size)class BiRNN(nn.Module):…

java抽象類,接口,枚舉練習題

第一題&#xff1a; 答案&#xff1a; class Animal{//成員變量protected String name;protected int weight;//構造方法public Animal(){this.name"refer";this.weight50;}public Animal(String name,int weight){this.namename;this.weightweight;}//成員方法publ…

Bugku Crypto 部分題目簡單題解(四)

目錄 python_jail 簡單的rsa 托馬斯.杰斐遜 這不是md5 進制轉換 affine Crack it rsa python_jail 啟動場景 使用虛擬機nc進行連接 輸入print(flag) 發現報錯&#xff0c;經過測試只能傳入10個字符多了就會報錯 利用python中help()函數&#xff0c;借報錯信息帶出flag變…

【力扣刷題筆記第三期】Python 數據結構與算法

先從簡單的題型開始刷起&#xff0c;一起加油啊&#xff01;&#xff01; 點個關注和收藏唄&#xff0c;一起刷題鴨&#xff01;&#xff01; 第一批題目 1.設備編號 給定一個設備編號區間[start, end]&#xff0c;包含4或18的編號都不能使用&#xff0c;如&#xff1a;418、…

對于map的新應用

題源codeforces1974 problemC 題目大意 定義當兩個三元組A和B中&#xff0c;滿足三元組中有且僅有兩個元素相等&#xff0c;比如 a 1 b 1 , a 2 b 2 , a 3 ! b 3 a_1b_1,a_2b_2,a_3!b_3 a1?b1?,a2?b2?,a3?!b3? 這只是一種情況&#xff0c;三種情況之一 解題思路 …

java抽象類和接口知識總結

一.抽象類 1.啥是抽象類 用專業語言描述就是&#xff1a;如果一個類中沒有包含足夠的信息來描繪一個具體的對象&#xff0c;這樣的類就是抽象類 當然這話說的也很抽象&#xff0c;所以我們來用人話來解釋一下抽象類 拋開編程語言這些&#xff0c;就以現實舉例&#xff0c;我…

每日練習之排序——鏈表的合并;完全背包—— 兌換零錢

鏈表的合并 題目描述 運行代碼 #include<iostream> #include<algorithm> using namespace std; int main() { int a[31];for(int i 1;i < 30;i)cin>>a[i];sort(a 1,a 1 30);for(int i 1;i < 30;i)cout<<a[i]<<" ";cout&…

Mysql之Innodb存儲引擎

1.Innodb數據存儲 innodb如今能夠做到mysql的默認數據存儲引擎&#xff0c;肯定有著其好處的&#xff0c;那么innodb有什么好處呢? 1. 當意外斷電或者重啟&#xff0c; InnoDB 能夠做到奔潰恢復&#xff0c;撤銷沒有提交的數據 2.InnoDB 存儲引擎維護自己的緩沖池&#xff0c…

UDS(ISO 14229)學習筆記

文章目錄 名詞縮寫Vector視頻筆記$10$27Fault Memory物理尋址和功能尋址UDS服務分類0x19服務0x14DTC汽車控制器(ECU)中DTC的狀態位物理尋址和功能尋址單幀 多幀 首幀 連續幀名詞縮寫 DTC Diagnostic Trouble Code FTB Fault Type Byte SID Service Identifier SF Subfunctio…

DML(Data Manipulation Language)數據操作語言

一、增加 insert into -- 寫全所有列名 insert into 表名(列名1,列名2,...列名n) values(值1,值2,...值n);-- 不寫列名&#xff08;所有列全部添加&#xff09; insert into 表名 values(值1,值2,...值n);-- 插入部分數據 insert into 表名(列名1,列名2) values(值1,值2); 舉…

醫院掛號就診系統的設計與實現

前端使用Vue.js 后端使用SpiringBoot MyBatis 數據使用MySQL 需要項目和論文加企鵝&#xff1a;2583550535 醫院掛號就診系統的設計與實現_嗶哩嗶哩_bilibili 隨著社會的發展&#xff0c;醫療資源分布不均&#xff0c;患者就診難、排隊時間長等問題日益突出&#xff0c;傳統的…

軟考備考三

操作系統 操作系統概述 功能&#xff1a;組織和管理軟件&#xff0c;硬件資源以及計算機系統中的工作流程&#xff0c;控制程序的執行&#xff0c;向用戶提供接口。 分類&#xff1a; 1.批處理操作系統 單道批 多道批&#xff08;宏觀上并行&#xff0c;微觀上串行&#xff09…

Hadoop3:HDFS的Fsimage和Edits文件介紹

一、概念 Fsimage文件&#xff1a;HDFS文件系統元數據的一個永久性的檢查點&#xff0c;其中包含HDFS文件系統的所有目 錄和文件inode的序列化信息。 Edits文件&#xff1a;存放HDFS文件系統的所有更新操作的路徑&#xff0c;文件系統客戶端執行的所有寫操作首先 會被記錄到Ed…

K8s 身份認證和權限

文章目錄 K8s 身份認證和權限認證Service AccountsService Account Admission ControllerToken ControllerService Account Controller 授權(RBAC)RoleClusterRoleRoleBindingClusterRoleBinding K8s 身份認證和權限 Kubernetes 中提供了良好的多租戶認證管理機制&#xff0c;…

二叉樹的鏈式結構

1.二叉樹的遍歷 2.二叉樹鏈式結構的實現 3.解決單值二叉樹題 1.二叉樹的遍歷 1.1前序&#xff0c;中序以及后序遍歷 二叉樹的遍歷是按照某種特定的規則&#xff0c;依次對二叉樹的結點進行相應的操作&#xff0c;并且每個結點只操作一次。 二叉樹的遍歷有這些規則&#xff…