C 語言學習筆記(指針6)

內容提要

  • 內存操作
    • 內存操作的函數

內存操作

我們對于內存操作需要依賴于string.h頭文件中相關的庫函數。

內存的庫函數

內存填充
  • 頭文件:#include <string.h>
  • 函數原型
void* memset(void* s, int c, size_t)
  • 函數功能:將內存塊s的前n個字節填充為c,一般用于初始化或者清零操作
  • 參數說明:
    • s:目標內存首地址
    • c:填充值(以unsigned char形式處理0~255)
    • n:填充字節數
  • 返回值:
    • 成功:返回s的指針
    • 失敗:返回NULL
  • 注意事項:
    • 常用于動態化初始化,c通常設置為0(清零)
    • 按字節填充,非整型初始化需要謹慎(如填充int數組時,0是安全的)
  • 案例:
#include <stido.h>
#include <stdilb.h>
#include <string.h>int main()
{// 在堆內存中申請4個int的連續空間int *p = (int*)malloc(4 * sizeof(int));// 非空校驗if (p == NULL){perror("內存申請失敗!")return -1}// 初始化堆內存,填充0memset(p, 0, 4 * sizeof(int));// 測試輸出printf("%d\n", p[1]); // p[1] 的底層 *(p+1) 我們可以將p[1]看作是*(p+1)語法糖// 內存使用完畢,釋放free(p);// 對指針賦值NULLp = NULL;return 0;
}
內存拷貝
  • 頭文件:#include <string.h>

  • 函數原型:

    • 源域目標內存無重疊時使用
    void* memcpy(void* dest, const void* src, size_t n);
    
    • 安全處理內存重疊
    void* memmove(void* dest, const void* src, size_t n);
    
  • 函數功能:將src的前n個字節拷貝倒dest

  • 參數說明:

    • dest: 目標內存首地址
    • src:源內存首地址
    • size_t n:拷貝的字節數
  • 返回值

    • 成功:返回dest的首地址
    • 失敗:返回NULL
  • 注意內存:

    • memmove能正確處理內存重疊,推薦優先使用
    • 確保目標內存足夠大,避免溢出。
  • 示例:

#include <stdio.h>
#include <string.h>int main()
{// 準備兩個數組,用來存護源和目標int src[4] = {11,22,33,44};int dest[6] = {111,222,333,444,555,666};// 進行拷貝memcpy(dest+1, src+1, 2 * sizeof(int));memmove(dest+1, src+1, 2 * sizeof(int)); // 從src拷貝22,33倒dest的222的位置printf("源數組:");register int i;for(i = 0; i < 4; i++) printf("%-6d", src[i]);printf("\n目標數組:");for(i = 0;i < 6; i++) printf("%-6d", dest[i]);return 0;
}

思考:什么是內存重疊?

內存重疊指在內存操作(如拷貝、移動數據)時,源區域和目標區域的內存地址范圍存在部分或完全重疊,導致操作結果出現不確定性。

典型例子:memcpymemmove

  1. memcpy 的隱患
  • 假設拷貝 10字節 從地址 pp+2

    char str[] = "abcdefgh";
    memcpy(str + 2, str, 5); // 源和目標重疊,行為未定義!
    
  • memcpy 不檢查重疊,可能因逐字節拷貝導致數據被意外覆蓋(如先覆蓋ac,后續操作又讀取被修改的值)。

  1. memmove 的解決方案
  • 同樣的操作,使用 memmove 會檢測重疊方向:

    • 若目標地址在源之前(正向拷貝),或地址不重疊,直接拷貝。
    • 若目標地址在源之后(反向拷貝),則從尾部開始倒序拷貝,避免覆蓋未讀取的數據。
    memmove(str + 2, str, 5); // 安全處理重疊
    
內存比較
  • 頭文件:#include <string.h>
  • 函數原型:
int memcmp(const void* s1, const void* s2, size_t n);
  • 函數功能:比較s1s2的前n個字節
  • 返回值:
    • 0:內存內容相同
    • >0s1中第一個不同字節大于s2
    • <0s1 中第一個不同字節小于 s2
  • 注意事項:比較按字節進行,非字符串需確保長度一致(總字節數一致)
  • 示例:
#include <stido.h>
#include <stdilb.h>
#include <string.h>int main()
{// 準備比較的數據int* arr1 = (int*)mallco(3 * sizeof(int)); // 3個元素int* arr2 = (int*)callco(4 * sizeof(in1t)); // 4個元素// 清零memset(arr1, 0, 3 * sizeof(int));// 賦值arr[0] = 60; arr[1] = 66;arr[0] = 70; arr2[1] = 5;// 比較int cmp_result = memcmp(arr2, arr1, 2 * sizeof(int)); // 雙方參與比較的字節數完全一致printf("比較結果:%d-(%s)\n", cmp_result, cmp_result > 0 ? "大于" : cmp_result < 0 ? "小于" : "等于");// 釋放內存free(arr1);free(arr2);arr1 = arr2 = NULL;return 0}
內存查找
  • 頭文件:#include <string.h>

  • 函數原型:

    • 正向查找, C語言標準庫函數
    void*  memchr(const void* s, int c, size_t n);
    
    • 逆向查找,這個不是C語言標準庫函數,屬于GNU擴展
    void* memrchr(const void* s, int c, size_t n);
    
  • 函數功能:在s的前n個字節中查找字符c

  • 返回值:

    • 成功:返回找到內容對應的地址
    • 失敗:返回NULL
  • 注意事項:

    • memrchr 是GNU擴展函數,需手動聲明(只要不是C語言標準提供,編譯的時候都需要手動聲明或鏈接)
    • 查找單位為字節值,非整型數據需要注意內存布局
  • 示例:

#include <stido.h>
#include <string.h>// memrchr是GUN擴展函數,需要外部聲明
extern void* memrchr(const void*, int, size_t);int main()
{// 準備一個測試數組char str[] = {'A','B','C','B'};// 查找字符'B'char * first = (char*) memchr(str, 'B', sizeof(str));char * last = (char*) memrchr(str, 'B', sizeof(str)); // GUN擴展函數printf("first = %p, last=%p\n", first, last);printf("第1個B的位置, %ld\n", first -str); // 1printf("最后1個B的位置, %ld\n", last -str);  // 3
}
``

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

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

相關文章

Grafana-Gauge儀表盤

儀表盤是一種單值可視化。 可讓您快速直觀地查看某個值落在定義的或計算出的最小和最大范圍內的位置。 通過重復選項&#xff0c;您可以顯示多個儀表盤&#xff0c;每個對應不同的序列、列或行。 支持的數據格式 單值 數據集中只有一個值&#xff0c;會生成一個顯示數值的…

解決Vue項目依賴錯誤:使用electron-vite重建

文章目錄 開端解決方案&#xff1a;使用 electron-vite Vue 重建項目1. 環境準備2. 創建新項目3. 安裝依賴并啟動項目 開端 在開發過程中&#xff0c;我遇到了一個令人頭疼的錯誤提示&#xff1a; 0:0 error Parsing error: Cannot find module vue/cli-plugin-babel/preset…

WPF prism

Prism Prism.Dryloc 包 安裝 Nuget 包 - Prism.DryIoc 1. 修改 App.xaml 修改 App.xaml 文件&#xff0c;添加 prism 命名空間, 繼承由 Application → PrismApplication&#xff0c;刪除默認啟動 url, StartupUri“MainWindow.xaml” <dryioc:PrismApplicationx:Class…

循序漸進PersistentVolumes與PersistentVolumeClaim

文章目錄 靜態配置&#xff08;Static Provisioning&#xff09;&#xff1a;Persistent volume(PV)Local 示例&#xff1a;NFS 示例&#xff1a;檢查pvPV 的常見狀態說明Persistent volume claim(PVC)1. local PVC示例:2.NFS PVC示例:3. 檢查PVC: 掛載靜態供應卷驗證靜態供應卷…

【連接器專題】SD卡座規格書審查需要審哪些方面?

在審查SD卡座規格書時,我們需要考慮哪些方面? 首先在拿到一份SD卡座的詳細規格書時,一般供應商給到的規格書中包括了一些基礎信息、產品圖紙信息、技術參數信息,同時有些供應商會給出產品可靠性測試報告。因此我們會從這幾個要素去看規格書。 基礎信息 基礎信息一般會給變更…

投稿 IEEE Transactions on Knowledge and Data Engineering 注意事項

投稿 IEEE Transactions on Knowledge and Data Engineering 注意事項 要IEEE overleaf 模板私信,我直接給我自己論文,便于編輯 已經投稿完成了,有一些小坑 準備工作 注冊IEEE賬戶:若沒有IEEE賬戶,需前往IEEE官網注冊。注冊成功后,可用于登錄投稿系統。現在新的系統,…

JS入門——三種輸入方式

JS入門——三種輸入方式 一、方式一&#xff1a;直接在警告框彈出(window可以省略) <!DOCTYPE html> <html><head><meta charset"utf-8"><title></title></head><body><script><!-- 方式一直接在警告框彈…

WordPress免費網站模板下載

大背景圖免費wordpress建站模板 這個wordpress模板設計以簡約和專業為主題&#xff0c;旨在為用戶提供清晰、直觀的瀏覽體驗。以下是對其風格、布局和設計理念的詳細介紹&#xff1a; 風格 簡約現代&#xff1a;整體設計采用簡約風格&#xff0c;使用了大量的白色和灰色調&am…

AUTOSAR CP全新系統化培訓上線!從底層到應用,三步階梯,五大學習維度構建完整知識體系

AUTOSAR組織 AUTOSAR官方全新推出「AUTOSAR CP全棧賦能計劃」&#xff0c;從架構全景到模塊細節&#xff0c;自底向上、由淺入深&#xff0c;覆蓋MCAL至SWC全層級&#xff0c;融合通信、診斷、安全等六大核心Feature&#xff0c;帶您穿透復雜理論&#xff0c;直擊AUTOSAR開發本…

Java網絡編程與Socket安全權限詳解

Socket安全權限控制 Java通過java.net.SocketPermission類實現對網絡套接字訪問的細粒度控制。該權限管理機制通常在Java策略文件中配置,其標準授權語法格式如下: grant {permission java.net.SocketPermission"target", "actions"; };目標主機與端口規…

基于本地化大模型的智能編程助手全棧實踐:從模型部署到IDE深度集成學習心得

近年來&#xff0c;隨著ChatGPT、Copilot等AI編程工具的爆發式增長&#xff0c;開發者生產力獲得了前所未有的提升。然而&#xff0c;云服務的延遲、隱私顧慮及API調用成本促使我探索一種更自主可控的方案&#xff1a;基于開源大模型構建本地化智能編程助手。本文將分享我構建本…

視頻監控匯聚平臺EasyCVR安防小知識:如何通過視頻融合平臺解決信息孤島問題?

一、項目背景與需求分析? 隨著數字化技術發展與網絡帶寬升級&#xff0c;視頻技術應用場景不斷拓展&#xff0c;視頻監控、記錄儀等多樣化產品構建起龐大體系。但這些獨立系統彼此割裂&#xff0c;形成信息孤島。 在系統集成項目中&#xff0c;視頻系統深度融合已成必然趨勢…

如何在 Windows 和 Mac 上擦拭和清潔希捷外置硬盤

希捷外置硬盤廣泛用于存儲目的&#xff0c;但有時您可能出于多種目的需要擦除或清潔希捷外置硬盤&#xff0c;例如轉售、重復使用、捐贈等。為了釋放硬盤上的存儲空間或確保沒有人可以從硬盤中恢復您的信息&#xff0c;擦除硬盤是必要的步驟。無論您使用的是 Windows 還是 Mac&…

SAP saml2 元數據 HTTP 錯誤

使?事務 SAML2 或 SAML2_IDP 在 ABAP 系統中配置 SAML 2.0 時&#xff0c; Web 頁?返回 403 已禁?、 404 未找到 或 500 服務器內部錯誤。 在事務 SAML2 中下載元數據時&#xff0c; ?頁返回 403 已禁?、 404 未找到或 500 服務器內部錯誤。 在事務 SAML2_IDP 中下載…

powershell 中 invoke-expression 報錯解決

打開powershell就出現這個報錯&#xff1a; 網上搜了也沒有很好的解決辦法&#xff0c;抱著一點點期待&#xff0c;問了豆包 根據豆包的指示&#xff0c;在終端執行以下 幾個命令&#xff0c;報錯解決了&#xff08;開心萬歲&#xff09; # 移除多余的引號和空路徑 $pathArra…

簡單說一說Modern ABAP這個概念

Modern ABAP 是 SAP近些年來提出的一個概念&#xff0c;指的是在傳統 ABAP (Advanced Business Application Programming) 的基礎上&#xff0c;結合新技術和現代化編程理念進行改進和優化&#xff0c;旨在使 ABAP 更適應云計算、數據驅動業務以及開發效率提升的需求。 這一概…

kafka 常用知識點

文章目錄 前言kafka 常用知識點1. kafka 概念2. 消息共享和廣播3. 分區和副本數量奇偶數 前言 如果您覺得有用的話&#xff0c;記得給博主點個贊&#xff0c;評論&#xff0c;收藏一鍵三連啊&#xff0c;寫作不易啊^ _ ^。 ??而且聽說點贊的人每天的運氣都不會太差&#xff0…

5G RedCap是什么-與標準5G的區別及支持路由器推薦

技術背景與重要性 從智能穿戴到工業傳感器&#xff0c;物聯網設備種類繁多&#xff0c;但并非所有設備都需要標準5G的全部功能。為滿足這些中端應用的需求&#xff0c;3GPP在Release 17中引入了5G RedCap&#xff08;Reduced Capability&#xff09;&#xff0c;也稱為5G NR-L…

C++構造函數與初始化全面指南:從基礎到高級實踐

C構造函數與初始化全面指南&#xff1a;從基礎到高級實踐 1. 構造函數基礎概念 構造函數是C中一種特殊的成員函數&#xff0c;它在創建類對象時自動調用&#xff0c;用于初始化對象的數據成員。構造函數的核心特點包括&#xff1a; 與類同名無返回類型&#xff08;連void都沒…

大模型長對話中上下文無法承載全部歷史,如何壓縮或提取重點

在人工智能技術迅猛發展的今天,大模型已經滲透到我們生活的方方面面,尤其是自然語言處理領域,簡直是掀起了一場革命。從智能客服到個人助手,從在線教育到心理咨詢,大模型驅動的對話系統正在以一種前所未有的方式改變我們與機器的互動模式。特別是那些能夠進行多輪對話、甚…