C語言速成12之指針:程序如何在內存迷宮里找寶藏?

程序員Feri一名12年+的程序員,做過開發帶過團隊創過業,擅長Java、鴻蒙、嵌入式、人工智能等開發,專注于程序員成長的那點兒事,希望在成長的路上有你相伴!君志所向,一往無前!


0. 前言:程序如何在內存迷宮里找寶藏?

想象內存是一個巨大的圖書館,每個書架格子(1 字節)都貼著獨一無二的門牌號(地址)。

當我們寫下 int num = 5;,就像在圖書館里租了 4 個相鄰的格子,把數字 5 藏了進去。

現在問題來了:程序怎么找到這 4 個格子里的寶藏?

有兩種尋寶方式:

直接尋寶:喊出格子的昵稱(變量名 num),編譯器會幫你翻譯成具體門牌號

間接尋寶:先找到記錄門牌號的小本本(指針),通過本本上的地址找到寶藏,這就是 C 語言的 "指針魔法"

接下來,我們將揭開這本神奇小本本的秘密,讓你成為內存迷宮的尋寶大師!

1. 指針:給內存地址取個 "外號"

1.1 內存格子的門牌號系統

內存就像一棟無限延伸的公寓樓,每個房間(1 字節)都有門牌號(如 0x0001)。當我們定義int num = 5時:

num是 4 間相連公寓的 "小區名字"

數字 5 是存在這 4 間公寓里的寶藏

第一間公寓的門牌號(如 0x0001)就是num的 "指針",相當于給地址取了個好記的外號

1.2 指針家族成員大閱兵

角色名稱

真實身份

生活類比

變量

帶名字的儲物箱

標著 "零食" 的抽屜,里面裝著薯片

變量名

儲物箱的標簽

抽屜上的 "零食" 標簽

變量值

儲物箱里的東西

抽屜里的薯片

指針

儲物箱的門牌號

抽屜在柜子里的位置編號(如 3 層 5 號)

指針變量

專門記門牌號的小本本

記錄所有抽屜位置的筆記本,翻開某頁寫著 "零食抽屜:3 層 5 號"

魔法口訣:指針不是具體的門牌號,而是帶 "戶型" 的地址 ——int指針知道自己要找的是 4 間相連的公寓(4 字節),char只找 1 間單身公寓(1 字節)

2. 指針變量:會記地址的 "智能筆記本"

2.1 召喚指針變量的咒語

數據類型 *指針變量名 = 初始地址; // 咒語格式

int *p = # // 召喚一個叫p的筆記本,專門記int型變量的地址

數據類型:規定筆記本只能記某種戶型的地址,比如int*只能記 4 字節公寓的地址

*符號:這是指針變量的身份標識,就像筆記本封面上寫著 "地址專用"

危險警告:沒初始化的指針就像空白筆記本,隨便用可能記著錯誤地址,導致程序去危險區域搞破壞!

2.2 內存里的 "地址傳遞游戲"

當執行int num = 5; int *ptr = #時:

num住在 0x1000-0x1003 公寓,存著數字 5

ptr住在 0x2000-0x2003 公寓,里面寫著 "0x1000"(num 的門牌號)

通過*ptr就能打開 num 的公寓,就像對著筆記本念咒

語:"根據地址 0x1000,取出里面的寶藏!"

3. 指針的神奇應用:讓程序玩出花樣

3.1 變量操作:隔空改值的魔法

//?定義一個交換魔法函數void?swap(int?*x,?int?*y)?{int?temp?=?*x;?//?從x地址的公寓取出寶藏存到臨時盒子*x?=?*y;???????//?把y地址的寶藏放進x的公寓*y?=?temp;?????//?把臨時盒子的寶藏放回y的公寓
}int?main()?{int?a=1,?b=2;swap(&a,?&b);?//?告訴swap函數:a住在&a,b住在&bprintf("a=%d?b=%d",?a,?b);?//?見證奇跡:a和b的值交換了!
}

魔法原理:直接告訴函數變量的真實地址,讓函數能直接修改原始數據,不用帶復印件(值傳遞),省內存又高效!

3.2 數組遍歷:在內存街道上大步流星

int?arr[]?=?{1,2,3,4,5};
int?*p?=?arr;?//?p指向數組第一個元素的地址,就像站在街道起點for(int?i=0;?i<5;?i++)?{printf("%d?",?*(p+i));?//?p+i表示向前走i步,每步跨4米(int占4字節)
}

速度秘訣:指針直接按地址蹦跶,比數組下標(還要計算偏移量)快得多,就像開著跑車在內存街道飛馳!

3.3 動態數據結構:搭積木般建鏈表

//?定義鏈表節點:每個節點是一塊帶地址的積木
typedef?struct?Node?{int?data;??????????//?積木上的數字struct?Node?*next;?//?積木上的箭頭,指向下一塊積木
}?Node;//?創建積木的工廠函數
Node*?createNode(int?value)?{Node*?newNode?=?(Node*)malloc(sizeof(Node));?//?申請一塊新積木newNode->data?=?value;????????????????????????//?在積木上寫數字newNode->next?=?NULL;??????????????????????????//?箭頭先指向空return?newNode;????????????????????????????????//?交出這塊積木
}//?搭建鏈表:把積木用箭頭連起來
Node*?head?=?createNode(1);
head->next?=?createNode(2);?//?第一塊積木的箭頭指向第二塊

數據結構奧秘:指針就像積木的箭頭,讓零散的內存塊能連成任意形狀,鏈表、樹、圖全靠這些箭頭!

4. 指針運算:在內存地址上玩數學游戲

4.1 取址咒 &:打聽變量住哪兒

int?num?=?10;printf("num住在:%p\n",?(void*)&num);?//?輸出類似0x7fff5fbff7d4的門牌號

注意:數組名天生會變魔術!int arr[5]; int *p=arr;等價于p=&arr[0],直接指向第一個元素的地址。

4.2 解引用咒 *:按地址拆快遞

int?a=2024,?*p=&a;
printf("a的快遞是:%d\n",?*p);?//?輸出2024,就像按快遞單地址拆開包裹
*p?=?2025;?//?直接修改地址里的內容,相當于往包裹里塞新東西

雙重解引用:如果 p 是記地址的筆記本,

**pp?就是記筆記本位置的書包!
int?**pp?=?&p;
**pp就是從書包里拿出筆記本,再看里面的地址。

4.3 指針加減法:在內存街道上散步

向前走 n 步:指針 + n 表示往后走 n 個 "戶型長度",比如int指針走 1 步是 4 字節,char走 1 步是 1 字節

int?arr[]?=?{1,2,3};
int?*p?=?arr;
printf("%d",?*(p+2));?//?從起點走2步(8字節),拿到第三個元素3

計算距離:兩個指針相減得到中間的元素個數(需在同一塊內存區域)

int?len?=?&arr[2]?-?&arr[0];?//?結果是2,表示中間有2個元素(索引0和1)

4.4 危險警告:別碰這些指針地雷!

野指針:沒初始化或指向已釋放內存的指針,就像沒有目的地的導航,可能帶你沖進懸崖(程序崩潰)

int?*p;?//?沒初始化的p,里面可能存著隨機地址
*p?=?10;?//?危險!往未知地址寫數據,可能破壞重要內存

類型亂轉:強制把double轉成int,就像把大箱子塞進小抽屜,數據會被擠變形!

double?d=3.14;
int?*p?=?(int*)&d;?//?強行用int指針讀double地址,得到的是亂碼值

5. 指針安全手冊:避免翻車的 3 個鐵律

5.1 上車先系安全帶:初始化指針

int?*p?=?NULL;?//?空指針,就像筆記本第一頁寫著"無地址"
int?a,?*q?=?&a;?//?直接指向有效變量a的地址,安全起步

開車前檢查: if(p != NULL)再操作,避免空指針 dereference 車禍。

5.2 車型要匹配:指針類型別亂改

double?d=3.14;
//?錯誤示范:讓小卡車(int*)去拉巨型貨物(double變量)
int?*p?=?(int*)&d;?
//?正確做法:用對應的貨車(double*)
double?*pd?=?&d;

5.3 借的內存要還:動態內存管理

int?*p?=?malloc(sizeof(int));?//?向系統借了一塊內存
free(p);?//?用完要還!
p?=?NULL;?//?還完標記為NULL,防止再次誤用

內存泄漏警告:借了不還,系統內存會越來越少,程序最終會 "內存不足" 卡死!

結語:掌握指針,成為內存世界的造物主

指針就像 C 語言給程序員的 "內存造物主權限":

你可以直接操控內存地址,實現底層魔法

用指針變量記錄地址,像管理地圖一樣管理內存

通過指針運算,在內存迷宮里精準移動

從簡單的變量交換,到復雜的操作系統內核,指針貫穿 C 語言的每個角落。建議打開編譯器,親手寫幾個指針程序:試試用指針交換變量,用指針遍歷數組,甚至搭一個簡單的鏈表 —— 在實踐中感受指針的魔力!

每日靈魂拷問:如果 C 語言沒有指針,程序員該怎么實現動態數據結構?Java 的 "引用" 和 C 的指針有啥區別?(提示:Java 引用像被限制的指針,不能直接操作地址哦~)

好啦,本篇就到這里啦,希望在前進的路上,我們都可堅持到達終點!

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

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

相關文章

部署n8n

https://github.com/n8n-io/n8n docker volume create n8n_data docker run -it --rm --name n8n -p 5678:5678 -v n8n_data:/home/node/.n8n docker.n8n.io/n8nio/n8n Discover 2192 Automation Workflows from the n8ns Community

ABP VNext + Orleans:Actor 模型下的分布式狀態管理最佳實踐

ABP VNext Orleans&#xff1a;Actor 模型下的分布式狀態管理最佳實踐 &#x1f680; &#x1f4da; 目錄 ABP VNext Orleans&#xff1a;Actor 模型下的分布式狀態管理最佳實踐 &#x1f680;一、引言&#xff1a;分布式系統的狀態挑戰 &#x1f4a1;二、架構圖與技術棧 &am…

構建安全AI風險識別大模型:CoT、訓練集與Agent vs. Fine-Tuning對比

構建安全AI風險識別大模型:CoT、訓練集與Agent vs. Fine-Tuning對比 安全AI風險識別大模型旨在通過自然語言處理(NLP)技術,檢測和分析潛在的安全威脅,如數據泄露、合規違規或惡意行為。本文從Chain-of-Thought (CoT)設計、訓練集構建、以及Agent-based方法與**AI直接調優…

Baklib內容中臺的主要構成是什么?

Baklib內容中臺核心架構 Baklib作為一站式知識管理平臺的核心載體&#xff0c;其架構設計圍繞智能搜索引擎優化技術與多終端適配響應系統展開。通過模塊化內容組件的靈活配置&#xff0c;企業可快速搭建知識庫、FAQ頁面及幫助中心等標準化場景&#xff0c;同時借助可視化數據看…

Ubuntu Desktop 24.04 常用軟件安裝步驟

文章目錄 Ubuntu Desktop 24.04 常用軟件安裝步驟Snipaste F1快捷截圖&#xff08;超方便 | 我6臺電腦每臺都用&#xff09;搜狗輸入法快速瀏覽工具 | 空格鍵快速預覽文件壁紙工具 | varietySSH 工具 | Termius 終端分屏工具 | TmuxCaffeine | 避免息屏小工具 一些設置將啟動臺…

詳細使用@rollup/plugin-inject的方式

rollup/plugin-inject 是一個 Rollup 插件&#xff0c;它允許你在構建時自動注入模塊中的變量引用&#xff0c;避免手動在每個文件中 import。Vite 使用的是 Rollup 構建底層&#xff0c;因此該插件在 Vite 項目中也適用。 一、使用場景 比如你希望在代碼中不手動寫 import { …

Day 0017:Web漏洞掃描(OpenVAS)解析

一、NVT腳本解析&#xff1a;漏洞檢測的“DNA” 1. NVT腳本結構 每個NVT腳本都是一個Lua腳本&#xff0c;包含以下核心模塊&#xff1a; lua -- 示例&#xff1a;檢測Apache HTTPd 2.4.49路徑穿越漏洞&#xff08;CVE-2021-41773&#xff09; script_id "1.3.6.1.4.1.…

【HarmonyOS Next之旅】DevEco Studio使用指南(二十六) -> 創建端云一體化開發工程

目錄 1 -> 創建HarmonyOS應用工程 1.1 -> 新建工程 1.1.1 -> 前提條件 1.1.2 -> 選擇模板 1.1.3 -> 配置工程信息 1.1.4 -> 關聯云開發資源 1.2 -> 工程初始化配置 1.2.1 -> 自動開通云開發服務 1.3 -> 端云一體化開發工程目錄結構 1.3.1…

Python 包管理工具 uv

Python 包管理工具 uv 是由 Astral 團隊&#xff08;知名工具 Ruff 的開發者&#xff09;基于 Rust 開發的新一代工具&#xff0c;旨在通過高性能和一體化設計革新 Python 生態的依賴管理體驗。以下是其核心特性、優勢及使用指南的全面解析&#xff1a; 一、uv 的核心優勢 極致…

何謂第二大腦?讀書筆記

2025/05/11 發表想法 每個人都是矛盾結合體&#xff0c;既想學到新知識、新的能力&#xff0c;又想沒辦法專注的學習&#xff0c;既無法專注有渴望學習新技能&#xff0c;逐漸會產生焦慮、失眠等負面癥狀&#xff0c;這就是現實社會現照&#xff0c;那怎么辦&#xff1f;我們能…

動態防御體系實戰:AI如何重構DDoS攻防邏輯

1. 傳統高防IP的靜態瓶頸 傳統高防IP依賴預定義規則庫&#xff0c;面對SYN Flood、CC攻擊等常見威脅時&#xff0c;常因規則更新滯后導致誤封合法流量。例如&#xff0c;某電商平臺遭遇HTTP慢速攻擊時&#xff0c;靜態閾值過濾無法區分正常用戶與攻擊者&#xff0c;導致訂單接…

為什么在設置 model.eval() 之后,pytorch模型的性能會很差?為什么 dropout 影響性能?| 深度學習

在深度學習的世界里&#xff0c;有一個看似簡單卻讓無數開發者困惑的現象&#xff1a; “為什么在訓練時模型表現良好&#xff0c;但設置 model.eval() 后&#xff0c;模型的性能卻顯著下降&#xff1f;” 這是一個讓人抓耳撓腮的問題&#xff0c;幾乎每一個使用 PyTorch 的研究…

[爬蟲知識] http協議

相關爬蟲專欄&#xff1a;JS逆向爬蟲實戰 爬蟲知識點合集 爬蟲實戰案例 引言&#xff1a;爬蟲與HTTP的不解之緣 爬蟲作用&#xff1a;模擬瀏覽器請求網頁為何要懂HTTP&#xff1a;http是網絡通信的基石&#xff0c;爬蟲抓取數據就是通過HTTP協議進行的&#xff0c;了解http有…

《Spark/Flink/Doris離線實時數倉開發》目錄

歡迎加入《Spark/Flink/Doris離線&實時數倉開發》付費專欄&#xff01;本專欄專為大數據工程師、數據分析師及準備大數據面試的求職者量身打造&#xff0c;聚焦Spark、Flink、Doris等核心技術&#xff0c;覆蓋離線與實時數倉開發的全流程。無論你是想快速上手項目、提升技術…

事務基礎概念

事務 事務是什么&#xff1f; 事務是一種機制&#xff0c;一個操作序列&#xff0c;包含了一組數據庫操作命令&#xff0c;并且把所有命令作為一個整體一起向系統提交或者撤銷操作請求&#xff0c;即統一這組命令要么一起執行&#xff0c;要么一起不執行 簡短概況就是&#…

四、【API 開發篇 (上)】:使用 Django REST Framework 構建項目與模塊 CRUD API

【API 開發篇 】&#xff1a;使用 Django REST Framework 構建項目與模塊 CRUD API 前言為什么選擇 Django REST Framework (DRF)&#xff1f;第一步&#xff1a;創建 Serializers (序列化器)第二步&#xff1a;創建 ViewSets (視圖集)第三步&#xff1a;配置 URLs (路由)第四步…

【北京盈達科技】GEO優化中的多模態了解

多模態數據處理領域&#xff0c;“模態”指的是不同類型的數據形式&#xff0c;每種模態都具有獨特的結構和信息表達方式。以下是12種可能的模態類型&#xff0c;這些模態在實際應用中可以根據具體場景進行組合和處理&#xff1a; 1. 文本模態 描述&#xff1a;以文字形式存在…

推進可解釋人工智能邁向類人智能討論總結分享

目錄 一、探索“可解釋人工智能”&#xff1a;AI如何從“黑箱”走向“透明大師” 二、走進可解釋人工智能&#xff1a;讓AI的決策變得透明 &#xff08;一&#xff09;幾種常見的特征導向方法 &#xff08;二&#xff09;像素級方法 1. 層次相關傳播&#xff08;LRP&#…

【Qt】Qt 5.9.7使用MSVC2015 64Bit編譯器

環境 Qt版本&#xff1a;5.9.7 VS版本&#xff1a;VS2022 步驟 1、安裝VS2022 三個必選項&#xff1a; a、使用C的桌面開發 b、Windows10 SDK 版本&#xff1a;10.0.18362.0 c、MSVC v140 VS 2015 生成工具 Windows10 SDK安裝完成后&#xff0c;需要增加安裝調試器。 2…

超越OpenAI CodeX的軟件工程智能體:Jules

目前AI編碼代理&#xff08;coding agent&#xff09;領域正迅速崛起&#xff0c;Google推出了一款名為Jules的非同步編碼代理&#xff08;asynchronous coding agent&#xff09;&#xff0c;主要針對專業開發者&#xff0c;與傳統在開發環境中直接輔助編碼的Cursor或Windsurf…