程序詩篇里的靈動筆觸:指針繪就數據的夢幻藍圖(水文,勿三)

在這里插入圖片描述

大家好啊,我是小象?(?òωó?)?
我的博客:Xiao Xiangζ?????

很高興見到大家,希望能夠和大家一起交流學習,共同進步
在這里插入圖片描述
這一節我們來學習指針的相關知識,學習內存和地址,指針變量和地址,包括取地址操作符,指針變量和解引用操作符,指針變量類型的意義,指針變量的大小,指針的解引用,指針±整數,void指針

文章目錄

  • 一、內存和地址
    • 1.1 內存
    • 1.2 如何理解編址
  • 二、指針變量和地址
    • 2.1 取地址操作符(&)
    • 2.2 指針變量和解引用操作符(*)
      • 2.2.1 指針變量
      • 2.2.2 如何拆解指針類型
      • 2.2.3 解引用操作符
    • 2.3 指針變量的大小
  • 三、指針變量類型的意義
    • 3.1 指針的解引用
    • 3.2 指針+-整數
    • 3.3 void指針
  • 四、結尾

一、內存和地址

1.1 內存

在 C 語言中,內存是程序運行的基礎,用于存儲程序中的數據和代碼。
我們來舉一個生活中的例子:假設有?棟宿舍樓,把你放在樓里,樓上有100個房間,但是房間沒有編號,你的一個朋友來找你玩,如果想找到你,就得挨個房子去找,這樣效率很低,但是我們如果根據樓層和樓層的房間的情況,給每個房間編上號,如:

?樓:101102103...
?樓:201202203...
...

有了房間號,如果你的朋友得到房間號,就可以快速的找房間,找到你。
同理,我們在買電腦的時候也會發現電腦的內存有8GB、16GB、32GB等,那這些內存空間如何高效的管理呢?其實一樣也是把內存劃分為一個個的內存單元,每個內存單元的大小取1個字節。
PS:計算機中的常見單位:一個比特位可以存儲一個2進制的位1或者0

bit - ?特位
Byte - 字節
KB
MB
GB
TB
PB
1Byte = 8bit
1KB = 1024Byte
1MB = 1024KB
1GB = 1024MB
1TB = 1024GB
1PB = 1024TB

其中,每個內存單元,相當于一個學生宿舍,一個字節空間里面能放8個比特位,就好比同學們住的八人間,每個人是一個比特位。每個內存單元也都有一個編號(這個編號就相當于宿舍房間的門牌號),有了這個內存單元的編號,CPU就可以快速找到一個內存空間。生活中我們把門牌號也叫地址,在計算機中我們
把內存單元的編號也稱為地址。C語言中給地址起了新的名字叫做:指針。
在這里插入圖片描述

所以我們可以理解為:
內存單元的編號=地址=指針

1.2 如何理解編址

編址是計算機系統中一個關鍵的概念,它涉及為計算機中的各種存儲單元或設備分配唯一標識符,以便能夠對它們進行準確的訪問和管理。
CPU訪問內存中的某個字節空間,必須知道這個字節空間在內存的什么位置,?因為內存中字節很多,所以需要給內存進而編址(就如同宿舍很多,需要給宿舍編號一樣)。計算機中的編址,并不是把每個字節的地址記錄下來,而是通過硬件設計完成的。鋼琴、吉他上面沒有寫上“剁、來、咪、發、唆、拉、西”這樣的信息,但演奏者照樣能夠準確找到每一個琴弦的每?個位置,這是為何?因為制造商已經在樂器硬件層面上設計好了,并且所有的演奏者都知道。本質是一種約定出來的共識!
首先,必須理解,計算機內是有很多的硬件單元,而硬件單元是要互相協工作的。所謂的協同,至少相互之間要能夠進行數據傳遞。但是硬件與硬件之間是互相獨立的,那么如何通信呢?答案很簡單,用"線"連起來。而CPU和內存之間也是有大量的數據交互的,所以,兩者必須也用線連起來。不過,我們今天關心一組線,叫做地址總線。硬件編址也是如此我們可以簡單理解,32位機器有32根地址總線,每根線只有兩態,表示0,1【電脈沖有無】,那么一根線,就能表示2種含義,2根線就能表示4種含義,依次類推。32根地址線,就能表示2^32種含義,每?種含義都代表?個地址。地址信息被下達給內存,在內存上,就可以找到該地址對應的數據,將數據在通過數據總線傳入CPU內寄存器。

在這里插入圖片描述
舉個例子,如果我們想要訪問某個地址,首先控制總線會發出指令,如何根據地址總線找到內存中對應的位置,接著在通過數據總線傳遞回來。

二、指針變量和地址

2.1 取地址操作符(&)

在 C 語言中,取地址操作符是“&”。它用于獲取一個變量的內存地址。例如,如果有一個變量 int a; ,那么 &a 就表示變量 a 的地址。

在這里插入圖片描述
PS:變量創建的本質其實是:在內存中申請空間,向內存申請4個字節的空間,存放10
比如,上述的代碼就是創建了整型變量a,內存中申請4個字節,用于存放整數10,其中每個字節都有地址,上圖中4個字節的地址分別是:

0x004FF9D4  
0x004FF9D5  
0x004FF9D6  
0x004FF9D7

那我們如何能得到a的地址呢?
這里就得學習一個操作符(&)——取地址操作符

#include<stdio.h>
int main ()
{int a = 10;printf("%p\n", &a);return 0;
}

在這里插入圖片描述
注意:&a取出的是a所占4個字節中地址較小的字節的地址。
實際上,地址也是二進制的,只是為了在vs容易表示寫成了16進制

雖然整型變量占用4個字節,我們只要知道了第一個字節地址,順藤摸瓜訪問到4個字節的數據也是可行的。

2.2 指針變量和解引用操作符(*)

2.2.1 指針變量

在C語言中,指針變量是一種特殊的變量,它存儲的是內存地址,而不是普通的數據值。
我們通過取地址操作符(&)拿到的地址是一個數值,比如:0x004FF9D4,這個數值有時候也是需要存儲起來,方便后期再使用的,那我們把這樣的地址值存放在哪里呢?答案是:指針變量中。

#include <stdio.h>
int main()
{int a = 10;int* pa = &a; //取出a的地址并存儲到指針變量pa中return 0
}

指針變量也是一種變量,這種變量就是用來存放地址的,存放在指針變量中的值都會理解為地址。

2.2.2 如何拆解指針類型

我們看到pa的類型是 int * ,我們該如何理解指針的類型呢?

int a = 10;
int * pa = &a;

這里pa左邊寫的是 int* , * 是在說明pa是指針變量,而前面的 int 是在說明pa指向的是整型(int)類型的對象。

那如果有一個char類型的變量ch,ch的地址,要放在什么類型的指針變量中呢?
很顯然,自然是放在char類型的指針變量中。

2.2.3 解引用操作符

在現實生活中,我們使用地址要找到一個房間,在房間里可以拿去或者存放物品。
C語言中其實也是?樣的,我們只要拿到了地址(指針),就可以通過地址(指針)找到地址(指針)
指向的對象,這里必須學習一個操作符叫解引用操作符(*)。
解引用操作符用于訪問指針所指向的內存位置的值。也就是說,當你有一個指針變量,它存儲了某個變量的內存地址,通過解引用操作符,你可以獲取或修改該內存地址中存儲的值。

舉個例子:

#include<stdio.h>
int main()
{int a = 100;int* pa = &a;*pa = 0;return 0;
}

第五行中定義了一個指向整型的指針變量 pa。int* 表示指針的類型,即該指針指向的是一個整型變量。& 是取地址運算符,&a 表示獲取變量 a 的內存地址。因此,這行代碼將變量 a 的地址賦值給指針 pa,使得 pa 指向了變量 a。
而第六行就有了解引用操作符的使用,*pa 表示訪問 pa 所指向的變量,也就是變量 a。這行代碼將 0 賦值給 *pa,實際上就是將 0 賦值給變量 a,從而修改了變量 a 的值。
有同學肯定在想,這里如果目的就是把a改成0的話,寫成 a = 0;不就完了,為啥非要使用指針呢?
其實這里是把a的修改交給了pa來操作,這樣對a的修改,就多了一種的途徑,寫代碼就會更加靈活,
后期慢慢就能理解了。

2.3 指針變量的大小

前面的內容我們了解到,32位機器假設有32根地址總線,每根地址線出來的電信號轉換成數字信號后
是1或者0,那我們把32根地址線產生的2進制序列當做一個地址,那么一個地址就是32個bit位,需要4
個字節才能存儲。
如果指針變量是用來存放地址的,那么指針變的大小就得是4個字節的空間才可以。
同理64位機器,假設有64根地址線,一個地址就是64個二進制位組成的二進制序列,存儲起來就需要
8個字節的空間,指針變量的大小就是8個字節。

#include <stdio.h>
//指針變量的大小取決于地址的大小
//32位平臺下地址是32個bit位(即4個字節)
//64位平臺下地址是64個bit位(即8個字節)
int main()
{printf("%zd\n", sizeof(char*));printf("%zd\n", sizeof(short*));printf("%zd\n", sizeof(int*));printf("%zd\n", sizeof(double*));return 0;
}

結論:
? 32位平臺下地址是32個bit位,指針變量大小是4個字節
? 64位平臺下地址是64個bit位,指針變量大小是8個字節
? 注意指針變量的大小和類型是無關的,只要指針類型的變量,在相同的平臺下,大小都是相同的

三、指針變量類型的意義

指針變量的大小和類型無關,只要是指針變量,在同?個平臺下,大小都是?樣的,為什么還要有各
種各樣的指針類型呢?
其實指針類型是有特殊意義的,我們接下來繼續學習。

3.1 指針的解引用

C 語言指針解引用是通過指針訪問其指向內存地址中存儲值的操作,使用星號 * 作為解引用操作符。它主要用于訪問和修改數據,以及對動態分配的內存進行讀寫。 代碼應用場景包括基本指針解引用、指針與數組結合的解引用和多級指針的解引用。使用時要注意進行空指針檢查,避免對 NULL 指針解引用導致程序崩潰,同時防止使用未正確初始化或指向已釋放內存的野指針,以免引發未定義行為。

對比下面兩段代碼:

//代碼1
#include <stdio.h>
int main()
{int n = 0x11223344;int* pi = &n;*pi = 0;return 0;
}
//代碼2
#include <stdio.h>
int main()
{int n = 0x11223344;char* pc = (char*)&n;*pc = 0;return 0;
}

調試我們可以看到,代碼1會將n的4個字節全部改為0,但是代碼2只是將n的第一個字節改為0。
結論:指針的類型決定了,對指針解引?的時候有多大的權限(一次能操作幾個字節)。
比如: char* 的指針解引用就只能訪問一個字節,而int* 的指針的解引用就能訪問四個字節。

3.2 指針±整數

先看一段代碼,調試觀察地址的變化。

#include <stdio.h>
int main()
{int n = 10;char* pc = (char*)&n;int* pi = &n;printf("%p\n", &n);printf("%p\n", pc);printf("%p\n", pc + 1);printf("%p\n", pi);printf("%p\n", pi + 1);return 0;
}

我們可以看出, char* 類型的指針變量+1跳過1個字節, int* 類型的指針變量+1跳過了4個字節。
這就是指針變量的類型差異帶來的變化。指針+1,其實跳過1個指針指向的元素。指針可以+1,那也可
以-1。
結論:指針的類型決定了指針向前或者向后走一步有多大(距離)。

3.3 void指針

void 指針也被稱為通用指針,其類型聲明為 void *。它可以指向任意類型的數據,也就是說,void 指針可以存儲任何類型變量的地址,但它本身并不明確所指向數據的具體類型。

這種類型的指針可以用來接受任意類型地址。但是也有局限性, void*類型的指針不能直接進行指針的±整數和解引用的運算。
舉個例子:

#include<stdio.h>int main(){int a = 10;int* pa = &a;char* pc = &a;return 0;}

在上面的代碼中,將一個int類型的變量的地址賦值給一個char類型的指針變量。編譯器給出了一個警
告(如下圖),是因為類型不兼容。而使用void
類型就不會有這樣的問題。
使用void*類型的指針接收地址:

#include <stdio.h>
int main()
{int a = 10;void* pa = &a;void* pc = &a;*pa = 10;*pc = 0;return 0;
}

這里我們可以看到, void* 類型的指針可以接收不同類型的地址,但是無法直接進行指針運算。
那么 void* 類型的指針到底有什么用呢?

一般 void * 類型的指針是使用在函數參數的部分,用來接收不同類型數據的地址,這樣的設計可以實現泛型編程的效果,后面我們會繼續講解viod指針。

四、結尾

這一課的內容就到這里了,下節課繼續學習操作符的其他一些知識
如果內容有什么問題的話歡迎指正,有什么問題也可以問我!
在這里插入圖片描述

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

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

相關文章

【實用技巧】RAGFlow+DeepSeek搭建私人Ai助理

前言 滿血版DeepSeek雖然很好用&#xff0c;但仍然有三個主要缺陷&#xff1a; 聯網的DeepSeek無法解決數據安全問題&#xff0c;如果使用&#xff0c;數據將傳輸到其服務器&#xff0c;數據隱私性無法保證。上傳的文件存在限制&#xff0c;無法解決有多個文件的問題。回答的…

Storm實時流式計算系統(全解)——中

storm編程的基本概念-topo-spout-bolt 例如下&#xff1a; storm 編程接口-spout的結構及組件實現 storm編程案例-spout組件-實現 這是我的第一個組件&#xff08;spout組件繼承BaseRichSput&#xff09;所有重寫內部的三個方法&#xff0c;用于接收數據&#xff08;這里數據是…

【tplink】校園網接路由器如何單獨登錄自己的賬號,wan-lan和lan-lan區別

老式路由器TPLINK&#xff0c;接入校園網后一人登錄&#xff0c;所有人都能通過連接此路由器上網&#xff0c;無法解決遂上網搜索&#xff0c;無果&#xff0c;幸而偶然看到一個帖子說要把信號源網線接入路由器lan口&#xff0c;開啟新世界。 一、wan-lan&#xff0c;lan-lan區…

Qt常用控件之旋鈕QDial

旋鈕QDial QDial 表示一個旋鈕控件。 1. QDial屬性 屬性說明value當前數值。minimum最小值。maximum最大值。singleStep按下方向鍵時改變的步長。pageStep按下 pageUp/pageDown 的時候改變的步長。sliderPosition界面上旋鈕顯示的初始位置。tracking外觀是否會跟蹤數值變化&…

微服務筆記 2025/2/15

微服務是一種軟件架構風格&#xff0c;它是以專注于單一職責的很多小型項目為基礎&#xff0c;組合出復雜的大型應用。 微服務是一種架構。 微服務是一種架構。 微服務是一種架構。 以前自己做項目最常用的架構是單體架構。單體項目不適合開發大型項目。 學習微服務技術來解…

7-1JVMCG垃圾回收

一、GC的作用與原理 ?核心功能? 自動識別并回收堆內存中不再被引用的對象&#xff0c;釋放內存空間。 避免手動管理內存的復雜性&#xff08;如C/C中的delete/free操作&#xff09;&#xff0c;降低內存泄漏風險。 ?判斷對象可回收的方法? ?可達性分析算法&#xff1a;…

yunedit-post ,api測試比postman更好

postman應該是大家最熟悉的api測試軟件了&#xff0c;但是由于它是外國軟件&#xff0c;使用它的高端功能注冊和繳費都比較麻煩。生成在線文檔分享也經常無法訪問被攔截掉。 這里可以推薦一下yunedit-post&#xff0c;該有的功能都有。 https://www.yunedit.com/postdetail …

010 rocketmq批量消息

文章目錄 批量消息BatchProducer.javaBatchConsumer.java 批量消息 批量發送可以提?發送性能&#xff0c;但有?定的限制&#xff1a; topic 相同 waitStoreMsgOK 相同 &#xff08;?先我們建設消息的iswaitstoremsgoktrue(默認為true), 如果沒有異常,我們將始終收到"O…

6.6.6 嵌入式SQL

文章目錄 2個核心問題識別SQL語句主語言和SQL通信完整導圖 2個核心問題 SQL語句嵌入高級語言需要解決的2個核心問題是&#xff1a;如何識別嵌入語句&#xff1f;如何讓主語言&#xff08;比如C,C語言&#xff09;和SQL通信&#xff1f; 識別SQL語句 為了識別主語言中嵌入的SQL…

Windows安裝sql server2017

看了下官網的文檔&#xff0c;似乎只有ubuntu18.04可以安裝&#xff0c;其他debian系的都不行&#xff0c;還有通過docker的方式安裝的。 雙擊進入下載的ISO&#xff0c;點擊執行可執行文件&#xff0c;并選擇“是” 不要勾選 警告而已&#xff0c;不必理會 至少勾選這兩…

RuoYi框架介紹,以及如何基于Python使用RuoYi框架

若依框架&#xff08;RuoYi&#xff09;是一款基于Spring Boot和Vue.js的開源快速開發平臺&#xff0c;廣泛應用于企業級應用開發。它提供了豐富的功能模塊和代碼生成工具&#xff0c;幫助開發者快速搭建后臺管理系統。 主要特點 前后端分離&#xff1a;前端采用Vue.js&#x…

從零搭建Tomcat:深入理解Java Web服務器的工作原理

Tomcat是Java生態中最常用的Web服務器之一&#xff0c;廣泛應用于Java Web應用的部署和運行。本文將帶你從零開始搭建一個簡易的Tomcat服務器&#xff0c;深入理解其工作原理&#xff0c;并通過代碼實現一個基本的Servlet容器。 1. Tomcat的基本概念 Tomcat是一個開源的Servl…

京東云DeepSeek-R1模型一鍵部署教程,基于智算GCS【成本2元】

使用京東云智算一鍵部署DeepSeek-R1模型&#xff0c;京東云智算服務AI平臺GCS支持DeepSeek-R1模型預裝環境&#xff0c;支持1.5B、7B、32B及70B參數模型環境&#xff0c;用戶可在GCS中快速啟動&#xff0c;使用ChatbotUI或者Open-WebUI作為用戶界面&#xff0c;進行測試并接入業…

Jenkins 自動打包項目鏡像部署到服務器 ---(前端項目)

Jenkins 新增前端項目Job 指定運行的節點 選擇部署運行的節點標簽&#xff0c;dev標簽對應開發環境 節點的遠程命令執行配置 jenkins完整流程 配置源碼 拉取 Credentials添加 觸發遠程構建 配置后可以支持遠程觸發jenkins構建&#xff08;比如自建的CICD自動化發布平臺&…

7.2 - 定時器之計算脈沖寬度實驗

文章目錄 1 實驗任務2 系統框圖3 軟件設計 1 實驗任務 本實驗任務是通過CPU私有定時器來計算按鍵按下的時間長短。 2 系統框圖 參見7.1。 3 軟件設計 注意事項&#xff1a; 定時器是遞減計數的&#xff0c;需要考慮StartCount&#xff1c;EndCount的情況。 /***********…

雙機熱備旁掛組網實驗

1拓撲圖 2.要求 1 、 SW3 的流量 正常情況下&#xff1a; SW1_VRF-->FW1--->SW1_Public--->R5 故障情況下&#xff1a; SW2_VRF-->FW2--->SW2_Public--->R6 2 、 SW4 的流量 正常情況下&#xff1a; SW2_VRF-->FW2--->SW2_Public--->R6 故障情…

2025春新生培訓數據結構(樹,圖)

教學目標&#xff1a; 1&#xff0c;清楚什么是樹和圖&#xff0c;了解基本概念&#xff0c;并且理解其應用場景 2&#xff0c;掌握一種建圖&#xff08;樹&#xff09;方法 3&#xff0c;掌握圖的dfs和樹的前中后序遍歷 例題與習題 2025NENU新生培訓&#xff08;樹&#…

HTML 日常開發常用標簽

文章目錄 HTML 日常開發常用標簽1、基本結構標簽2、內容標簽3、多媒體標簽4、表單標簽5、列表和定義標簽6、表格標簽7、鏈接和圖像8、元數據9、語義化標簽&#xff08;HTML5新增&#xff09;10、框架和內聯11、交互12、過時或不推薦使用的標簽 HTML 日常開發常用標簽 1、基本結…

7.1.1 計算機網絡的組成

文章目錄 物理組成功能組成工作方式完整導圖 物理組成 計算機網絡是將分布在不同地域的計算機組織成系統&#xff0c;便于相互之間資源共享、傳遞信息。 計算機網絡的物理組成包括硬件和軟件。硬件中包含主機、前端處理器、連接設備、通信線路。軟件中包含協議和應用軟件。 功…

【AI論文】MedVLM-R1:通過強化學習激勵視覺語言模型(VLMs)的醫療推理能力

摘要&#xff1a;推理是推進醫學影像分析的關鍵前沿領域&#xff0c;其中透明度和可信度對于贏得臨床醫生信任和獲得監管批準起著核心作用。盡管醫學視覺語言模型&#xff08;VLMs&#xff09;在放射學任務中展現出巨大潛力&#xff0c;但大多數現有VLM僅給出最終答案&#xff…