簡體   English   中英

C中的指針:數據類型或操作

[英]Pointers in C: Data type or operation

我們會將C中的指針調用為數據類型(類型為void *),還是僅對無符號整數執行操作,使其值被解釋為虛擬內存地址? 如果是數據類型,哪些硬件和軟件因素會影響其范圍?

我認為你將兩個東西混合在一起 - 間接運算符和指針變量。

間接運算符(*) - 間接運算符是一元運算符,可用於獲取存儲在指針變量引用的內存位置的值。

指針變量 - 在C指針中是存儲地址的特定類型的變量(例如int,char,void),可以為null。

指針的大小取決於不同的因素。 你可以轉到下面的鏈接。 他們解釋得很好。

指針的大小是多少? 它究竟依賴於什么?

C認為你的整個計算機是一個巨大的字節數組。 顯然這不是很有用,但是在這個龐大的字節數組之上的C層就是那些類型的類型和大小的概念。

  • 在計算機內創建一塊內存。

  • 在該塊的開頭“指向”名稱ptr ()。

這間接意味着它需要一個類型說明符,它與它指向的數據類型相同。

是的,他們是數據類型。 void *

intptr_t整數可以存儲除函數指針之外的任何指針。 因此,您可以將這些指向數據對象的指針視為特殊整數。 (但請記住整數和指針是不同的類型。)

您的編譯器為您的目標環境生成代碼。 例如,如果使用選項-m32進行編譯,則指針大小可能為32位。 它可以在32位架構上運行,其中CPU寄存器可以存儲32位存儲器地址。 雖然64位體系結構可能仍然支持32位應用程序,但您可以使用選項-m64進行編譯,以便從更大的指針(可能是64位)中受益。

你問的很多想法。 我將嘗試盡可能地引用C標准來提供正式的想法,然后將其分解成可以消化的東西。


我們會將C中的指針調用為數據類型(類型為void *),還是僅對無符號整數執行操作,使其值被解釋為虛擬內存地址?

從C標准:

6.2.5類型

  1. 指針類型可以從函數類型,對象類型或不完整類型派生,稱為引用類型 指針類型描述一個對象,其值提供對引用類型的實體的引用。 從引用類型T派生的指針類型有時被稱為“指向T ”的指針。 從引用類型構造指針類型稱為“指針類型派生”。

6.3.2.3指針

  1. 整數可以轉換為任何指針類型。 除非先前指定,否則結果是實現定義的,可能未正確對齊,可能不指向引用類型的實體,並且可能是陷阱表示。
  2. 任何指針類型都可以轉換為整數類型。 除了之前指定的以外,結果是實現定義的。 如果結果無法以整數類型表示,則行為未定義。 結果不必在任何整數類型的值范圍內。

指針不是數據類型(至少在傳統意義上的短語)或整數 - 它是C程序員表示某個對象位置的方式。 雖然我們傾向於認為這是一個數字 - 即0xf000b3a8 - 但沒有理由它必須是一個數字。 它只需要標記特定對象的位置。 此外,它指向的對象的類型決定了它自己的指針類型 因此,類型為“ float * ”的指針等效於“指向float指針”。 不是 float類型 - 它是指針類型。

舉一個具體的例子,想想你如何整理你的卧室 - 也許你有一張床,一張桌子,一套抽屜,一個衣櫃和一個床頭櫃。 在你上床睡覺之前,你拿出一張便條並寫上“記住桌上的耳機”。 然后你把那個便利貼放在你的背包上。 粘滯便箋是指向耳機的指針 它提醒您這些耳機所在的位置 - 您的桌子, 而不是數字。

我們傾向於將指針視為整數的原因來自6.3.2.3.5和6.3.2.3.6節。 計算機 - 正如他們目前設計的那樣 - 不理解“桌子”或“壁櫥”的概念。 他們只了解數字 - 所以我們相應地組織它們。 因此,C標准規定整數必須能夠轉換為指針,反之亦然。


如果是數據類型,哪些硬件和軟件因素會影響其范圍?

同樣,指針實際上不是數據類型 - 它表示某個對象的位置(該對象又具有指示指針類型的特定類型)。 所以我們實際上無法真正談論指針的范圍 我們可以談論的是可能的內存地址范圍(以及指針可能指向的可能位置的范圍!)。

回到當天,當恐龍在地球上漫游,尼克松在辦公室時(我還是個年輕人,我能說什么),英特爾推出了英特爾8008微處理器1 這只小狗是世界上第一個8位 CPU - 也就是說,它可以對8位值執行數學運算。 假設2的補碼表示法,這允許無符號值0到2 8 -1(0到255)和有符號值-2 7到2 7 -1(-128到127)。 此外,它有一個外部14位地址總線,可以處理高達16KB的內存。 這相當於2 14 (16384)個存儲單元,每個存儲單元包含8位。 因此,整個范圍從字節0到字節16383。

快進到今天。 大多數現代台式機和筆記本電腦都運行在64位處理器上。 這些支持(理論上)2 64字節的內存 - 高達18,446,744,073,709,551,616個位置。 這相當於大約16艾字節 - 其中一個艾字節是1,000,000太字節。 據推測,谷歌將大量數據存儲在他們的數據中心 )。 但是,目前大多數架構僅使用較低的48位2

這些代表C中指針理論上指向的物理位置的總數。 實際上,由於虛擬內存的工作原理,您作為程序員將會看到的范圍更加有限。 然而,這是另一天的故事。

指針是一個變量,其值是另一個變量的地址。 一般來說,C中的指針可以指向虛擬內存中的任何地址,並且為NULL。

指針通常是變量,其值是另一個變量的地址,例如存儲器位置的直接地址 與任何變量或常量一樣,必須先聲明指針,然后才能使用它來存儲任何變量地址。

所有指針的值的實際數據類型,無論是整數,浮點數,字符還是其他,都是相同的,是表示內存地址的長十六進制數。

例如: int *ip; /* pointer to an integer */ int *ip; /* pointer to an integer */

指針值的運行時表示通常是原始內存地址(可能由字內偏移字段增強),但由於指針的類型包括指向的事物的類型,因此可以對包含指針的表達式進行類型檢查在編譯時 指針算術由指向數據類型的大小自動縮放。

AS for void指針( void * )指向未指定類型的對象,因此可以用作“通用”數據指針。 由於指向對象的大小和類型是未知的,因此無法取消引用void指針,也不允許使用指針算術,盡管它們很容易(並且在許多上下文中隱式地)轉換為任何其他對象指針類型。

見維基

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM