【C語言入門】由淺入深學習指針 【第二期】

?

目錄

?1. 指針變量為什么要有類型?

2. 野指針

2.1 未初始化導致的野指針

2.2 指針越界導致的野指針

2.3 如何規避野指針?

3. 指針運算

3.1 指針加減整數

3.2 指針減指針

3.3 指針的關系運算

4. 二級指針

5. 指針數組

5.1 如何使用指針數組模擬二維數組

????????上一期已經解釋了指針和指針變量的區別以及含義,這一期我們來具體了解一下指針到底有什么作用。

?1. 指針變量為什么要有類型?

? ? ? ? 我們知道指針變量的大小是根據所在平臺決定的,若平臺是32位即x86環境,則指針變量是4個字節,若平臺是64位,則指針變量是8個字節。既然指針變量不會根據指針類型變化,那么我們為什么要區分指針變量的類型呢?換句話說char* 和 int* 都有能力存儲4個字節的地址,為什么不統一成一個自定義的指針變量例如ptr*

????????從上圖可以得知,我們把int*類型的地址強行賦給char*類型的地址,再進行取值調用的時候,會根據char*來進行賦值以至于只會將一個字節賦值成0,若是正常使用int*來接收,那么四個字節都是0 ,如下圖所示。

????????由下圖可知,雖然不同指針變量的存儲類型不影響地址的存儲,但是當直接對地址進行運算,還是會根據指針類型的不同進行運算。char*類型+1,跳過1個字節,int*類型+1,跳過4個字節。

所以我們會得到這樣的結論:指針變量的類型在存取地址的時候可有可無,在修改地址指向的內容的時候是非常有必要的,它決定了在利用地址更改值的時候需要更改多少個字節;若直接對地址進行運算,那么會根據指針變量的類型+‘1’,這個‘1’可能是char類型的一個字節,也可能是int類型的四個字節。?

使用float*和int*的時候,無論是訪問內存還是使用內存,都是4個字節,那么可不可以混用呢?

答案是:不可以

下圖是整型解引用賦值整型,我們可以看到100以16進制存入內存。

我們把100.0存入內存,發現內存存的數據發生了變化, 雖然都是100,但是浮點數存入內存的方式是不同的。

2. 野指針

? ? ? ? 指針指向的內存沒有初始化,或者已經被銷毀,此時的指針稱為野指針。

2.1 未初始化導致的野指針

2.2 指針越界導致的野指針

2.3 如何規避野指針?

①指針初始化。

②指針小心越界。

③指針指向的空間置為NULL。NULL是0,類型是void*,如果取值的話一定會報錯(默認0地址不能訪問),所以,我們可以先判斷這個指針如果不是NULL再進行取值。

④避免返回局部變量的地址,因為局部變量已經被銷毀了(沒有那塊內存空間的使用權限了)。

⑤指針使用之前檢查有效性。

3. 指針運算

3.1 指針加減整數

這里的values[N_VALUES]并不算下標越界,因為并沒有使用這段內存,只是用了一下這個地址作為判斷條件。

3.2 指針減指針

當同類型的地址減去同類型的另外一個地址,得出的結果的絕對值是兩個地址之間的元素個數

需要注意的是,兩個指針指向的必須是同一塊內存,不然毫無意義。

????????那么有同學會想,指針+指針得到的結果是什么呢,這個結果毫無意義,類似于你可以把日期相減,得到天數,但是你不能把日期相加,這樣就毫無意義

3.3 指針的關系運算

其實就是地址之間的比較,判斷兩個地址誰大誰小,從而對地址指向的內容進行操作。

4. 二級指針

? ? ? ? 簡單描述一下,就是指針變量里面存的地址,這個地址是一個指針的地址。乍一聽是不是以為在說繞口令呢?下面用一張圖來進行詮釋。

????????上圖中表示int * pa = &a;我們可以這么理解:*號表明pa的類型是一個指針類型,int表明這個指針類型指向的是int類型;那么我們是不是可以來理解一下二級指針。

? ? ? ? int* *ppa = &pa;還是將類型拆開,距離ppa最近的*表明ppa是一個指針,int* 表明ppa指向的類型是int*的類型

總結:二級指針是用來存放一級指針變量的地址

5. 指針數組

主語是數組,即存放指針的數組就是指針數組

5.1 如何使用指針數組模擬二維數組

????????首先構造出三個一維數組,所謂二維數組就是將這三個一維數組連起來;我們構造一個指針數組,分別存入之前構造的一維數組名,在之前的帖子說明,一維數組名是數組的第一個元素的地址,所以分別存入了三個地址,我們需要遍歷指針數組,得到三個一維數組的首地址,再引入一個變量j,根據指針加減法,就可以訪問一維數組中除了第一個元素的其他元素的地址,最后解引用就可以得到最后的結果。

#include <stdlib.h>int main()
{int arr1[4] = {1,2,3,4};int arr2[4] = {2,4,6,8};int arr3[4] = {3,6,9,12};
// 用一維數組模擬出二維數組的效果int* arr_sum[3] = {arr1,arr2,arr3};for(int i = 0;i < 3;i++){for(int j = 0;j < 4;j++){printf("%d ",*(arr_sum[i] + j));}printf("\n");}return(0);
}

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

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

相關文章

OpenCV 圖形API(13)用于執行兩個矩陣(或圖像)逐元素乘法操作的函數mul()

操作系統&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 編程語言&#xff1a;C11 描述 計算兩個矩陣的每個元素的縮放乘積。 mul函數計算兩個矩陣的逐元素乘積&#xff1a; dst ( I ) saturate ( scale ? src1 ( I ) ? src2 ( I ) ) …

人工智能混合編程實踐:C++調用封裝好的DLL進行圖像超分重建

人工智能混合編程實踐:C++調用封裝好的DLL進行圖像超分重建 前言相關介紹C++簡介ONNX簡介ONNX Runtime 簡介**核心特點**DLL 簡介**核心特點****創建與使用****應用場景****優點與挑戰**圖像異常檢測簡介應用場景前提條件實驗環境項目結構C++調用封裝好的DLL進行圖像超分重建C…

Linux內核之高效緩沖隊列kfifo

一、先說FIFO 隊列是常見的一種數據結構&#xff0c;簡單看來就是一段數據緩存區&#xff0c;可以存儲一定量的數據&#xff0c;先存進來的數據會被先取出&#xff0c;First In Fist Out&#xff0c;就是FIFO。 FIFO主要用于緩沖速度不匹配的通信。 例如生產者&#xff08;數…

【面試篇】Kafka

一、基礎概念類 問題&#xff1a;請簡述 Kafka 是什么&#xff0c;以及它的主要應用場景有哪些&#xff1f; 答案&#xff1a;Kafka 是一個分布式流處理平臺&#xff0c;它以高吞吐量、可持久化、可水平擴展等特性而聞名。其主要應用場景包括&#xff1a; 日志收集&#xff1a…

解釋回溯算法,如何應用回溯算法解決組合優化問題?

一、回溯算法核心原理 回溯算法本質是暴力窮舉的優化版本&#xff0c;采用"試錯剪枝"策略解決問題。其核心流程如下&#xff1a; ?路徑構建&#xff1a;記錄當前選擇路徑?選擇列表&#xff1a;確定可用候選元素?終止條件&#xff1a;確定遞歸結束時機?剪枝優化…

Vue 學習隨筆系列二十二 —— 表格高度自適應

表格高度自適應 文章目錄 表格高度自適應1、方法一2、方法二 1、方法一 根據頁面元素計算各自占比 <template><div class"main"><div class"query-form" ref"Query"><QueryFormref"QueryForm"query"query&q…

ubuntu22.04.5安裝docker,解決安裝出現的錯誤,解決Docker hello-world沒打印出來

文章目錄 前言一 安裝失敗解決1結合具體報錯分析2 首先懷疑是VPN的問題3 直接百度報錯信息4最終解決問題 二 驗證Docker hello-world沒打印出來總結 前言 先說一下前面的情況&#xff0c;使用的是公司的工作站&#xff0c;登錄公司一個帳號使用的公司網絡&#xff0c;使用網上…

idea插件(自用)

.ignore git排除文件插件&#xff1a;.ignore介紹 Grep console 自定義日志顏色&#xff1a;Grep console介紹 AceJump 光標快速定位&#xff1a;AceJump介紹 Key promoter 提示插件:Key promoter介紹 MetricsReloaded 分析代碼復雜度的插件&#xff1a;MetricsReload…

讓AI再次偉大-MCP-Client開發指南

&#x1f44f;作者簡介&#xff1a;大家好&#xff0c;我是愛吃芝士的土豆倪&#xff0c;24屆校招生Java選手&#xff0c;很高興認識大家&#x1f4d5;系列專欄&#xff1a;Spring原理、JUC原理、Kafka原理、分布式技術原理、數據庫技術、JVM原理、AI應用&#x1f525;如果感覺…

供應鏈管理:計算題 / 倒扣法

一、理解倒扣法 在供應鏈管理中&#xff0c;倒扣法是一種常用的成本計算方法&#xff0c;主要用于確定商品的成本和銷售價格&#xff0c;以確保特定的毛利率。倒扣法的基本原理是在已知售價和期望毛利率的情況下&#xff0c;逆推計算出供貨價或成本價。 二、倒扣法的計算公式…

skynet.start 的作用詳細解析

目錄 skynet.start 的作用詳細解析1. 功能概述2. 基本用法3. 關鍵作用(1) 注冊消息處理函數(2) 啟動事件循環(3) 服務生命周期管理 4. 與其他函數的協作5. 未調用 skynet.start 的后果6. 高級場景&#xff1a;何時不需要 skynet.start7. 總結 skynet.start 的作用詳細解析 在 …

基于yolo11的BGA圖像目標檢測

1.產生圖像數據的分辨率 2.產生圖像的大小 3.產生圖像是黑白或是RGB彩色 灰度圖像&#xff0c;達到識別要求&#xff0c;減少計算量 4.標注數據的精準程度 1.模型標注后&#xff0c;少量標注全部人工校驗&#xff0c;大量數據抽檢&#xff0c;部分人工檢驗 2.明確邊界框貼合…

PADS 9.5【附破解文件+安裝教程】中文激活版下載

第1步 將軟件安裝包下載到電腦本地&#xff0c;使用解壓工具進行解壓打開&#xff08;全程關閉殺毒軟件以及防火墻&#xff0c;避免破解文件被刪除&#xff09; 第2步 鼠標右鍵以管理員身份運行“PADS9.5_mib.exe” 第3步 加載片刻后&#xff0c;彈出如圖界面&#xff0c;點擊N…

電子電氣架構 --- SOC設計流程及其集成開發環境

我是穿拖鞋的漢子&#xff0c;魔都中堅持長期主義的汽車電子工程師。 老規矩&#xff0c;分享一段喜歡的文字&#xff0c;避免自己成為高知識低文化的工程師&#xff1a; 周末洗了一個澡&#xff0c;換了一身衣服&#xff0c;出了門卻不知道去哪兒&#xff0c;不知道去找誰&am…

圖撲 HT 電纜廠 3D 可視化管控系統深度解析

在當今數字化浪潮席卷制造業的大背景下&#xff0c;圖撲軟件&#xff08;Hightopo&#xff09;憑借其自主研發的強大技術&#xff0c;為電纜廠打造了一套先進的 3D 可視化管控系統。該系統基于 HT for Web 技術&#xff0c;為電纜廠的數字化轉型提供了有力支撐。 HT 技術核心架…

【數據結構】鄰接矩陣完全指南:原理、實現與稠密圖優化技巧?

鄰接矩陣 導讀一、圖的存儲結構1.1 分類 二、鄰接矩陣法2.1 鄰接矩陣2.2 鄰接矩陣存儲網 三、鄰接矩陣的存儲結構四、算法評價4.1 時間復雜度4.2 空間復雜度 五、鄰接矩陣的特點5.1 特點1解析5.2 特點2解析5.3 特點3解析5.4 特點4解析5.5 特點5解析5.6 特點6解析 結語 導讀 大…

Docker Registry 清理鏡像最佳實踐

文章目錄 registry-clean1. 簡介2. 功能3. 安裝 docker4. 配置 docker5. 配置域名解析6. 部署 registry7. Registry API 管理8. 批量清理鏡像9. 其他10. 參考registry-clean 1. 簡介 registry-clean 是一個強大而高效的解決方案,旨在簡化您的 Docker 鏡像倉庫管理。通過 reg…

UART雙向通信實現(序列機)

前言 UART&#xff08;通用異步收發傳輸器&#xff09;是一種串行通信協議&#xff0c;用于在電子設備之間進行數據傳輸。RS232是UART協議的一種常見實現標準&#xff0c;廣泛應用于計算機和外圍設備之間的通信。它定義了串行數據的傳輸格式和電氣特性&#xff0c;以確…

機器學習算法分類全景解析:從理論到工業實踐(2025新版)

一、機器學習核心定義與分類框架 1.1 機器學習核心范式 機器學習本質是通過經驗E在特定任務T上提升性能P的算法系統&#xff08;Mitchell定義&#xff09;。其核心能力體現在&#xff1a; 數據驅動決策&#xff1a;通過數據自動發現模式&#xff0c;而非顯式編程&#xff08…