- 基本上指針是 用於存儲存儲器地址的變量,這始終是
十六進制(存儲器地址),那麼爲什麼需要用於存儲地址不同的數據類型。 - EX:int * a;我們可以用這個來存儲浮點地址嗎?
回答
不是所有的指針都是(必須是)相同的大小。如果你有一個大型結構需要對齊到10 MB,編譯器可以決定它只需要8位(而不是通常的32或64)來存儲變量可能位於的所有可能的地址。
你也不要需要不同的數據類型,你可以使用void*
就好了,但你爲什麼?在C++中,這是一種代碼異味。
還有類型安全。你知道一個int*
指向一個int
,這是你的優勢。
指針算術也可以有優勢嗎? –
因爲它提供了關於如何解釋指針指向的數據的信息。
EX:int * a;我們可以用這個來存儲浮點地址嗎?
通過C類不安全功能:是的,但不是直接的,特別是在最近的編譯器和標準(這往往是更安全和更安全)
兩個原因:
在一些體系,根據指向數據的大小,指針可能有不同的格式。例如,指向
char
的指針必須能夠對單個字節進行尋址,但指向int
的指針只需要能夠尋址4個字節的組。所以後者可以使用包含字節地址除以4的格式。它允許編譯器生成正確的程序。如果您嘗試取消引用
char
指針並將其指定給int
,則需要知道它應該只從源讀取一個字節,並將其擴大到int
的大小。沒有指針類型聲明,它會讀取比適當的更多的字節。
對於初學者,我不知道指針是以十六進制存儲的指針 ;我熟悉的每臺機器在內部使用 二進制表示。 (在過去的30或40 年,至少。IIRC,在IBM 1401採用十進制無處不在。)
正如其他人所指出的那樣,並不是所有的指針做具有相同的 規模和代表性。我已經在其中char*
比其他數據指針類型更大的機器上工作,當然,具有 函數指針的不同大小和用於 的數據指針是非常常見的。
但是,真正的答案是基於C和 C++中的類型系統。如果p
是指針,那麼*p
的類型是什麼?如果我寫 類似*p + *q
,編譯器必須知道是否使用 整數算術或浮點運算。
至於你的第二個問題:通常,是的,雖然你會 可能需要reinterpret_cast
在那裏。但是, 您可以合法使用您的int*
的唯一一件事是將其 轉換回float*
;解引用它是未定義的行爲。
對於char*
和unsigned char*
有一些例外。而 在實踐中,如果你知道自己在做什麼,你可以得到的東西像走 :
float f;
int* a = reinterpret_cast<int*>(&f);
std::cout << *a << std::endl;
我真正做了某些種類的低水平 調試和編程的東西;諸如從float
中提取指數 字段。但是,此類代碼非常罕見,並且 在形式上涉及未定義的行爲,因此您必須驗證編譯器實際執行的操作,並且可能會關閉某些優化。
爲什麼我們需要不同的數據類型存儲地址
這實際上是正確的問題,答案就藏在它 - 爲什麼我們需要用來存放地址不同的數據類型。我們(程序員)需要它。機器不關心 - 一個數字就像另一個數字。
如果您將「變量」視爲某個數據的「佔位符」,則在使用數據本身和使用變量之間存在編程語言的二分法。有時候你只需要數據(例如你需要打印出來),有時你需要存儲這些數據的地址(例如,你可以修改它)。大多數語言都含有混淆這兩種情況的語法糖,並在不同的上下文中以不同的方式處理變量標識符。
這樣一個案例是這樣的:考慮語句
a = 1;
在這種情況下,編譯器查找由「A」標識的變量的地址,並寫入「1」到這個地址。標識符「a」也可能是一個指針。現在看一下不同的東西:
if (a == 1) ... ;
您是不通過比較確定一個變量的地址「一」的東西,你是比較什麼是存儲在該地址爲「1」。
爲了程序員的方便,各種「指針類型」再次存在:基本上,我們通過錯誤地訪問數據來減少錯誤。請看下面的例子:
double d;
double* dp;
int i;
int* ip;
默認情況下,C是它很放鬆,你通常可以做:
dp = ip;
或
dp = &i;
...但是! sizeof(i)== 4和sizeof(d)== 8,所以如果你解引用dp指針,你將試圖從只包含4的變量(i)中讀取8個字節。這意味着你將讀取4個不可預測的(隨機)字節在我的前四個字節之後,這絕對是你不想做的事情。
再一次,所有這些都是爲了我們的方便。機器不在乎。這兩個指針的外觀和行爲與CPU完全相同。 「
- 1. 爲什麼我不需要在C#中指定類型參數?
- 2. 爲什麼我們要傳遞指針的指針cudaMalloc
- 3. 什麼是C#指針和什麼類型的任務需要他們?
- 4. 我們需要指針嗎?
- 5. 爲什麼我們需要長型?
- 6. 爲什麼我們需要分開Apply和Applicative類型的類?
- 7. 爲什麼我們需要包裝類
- 8. 爲什麼需要類型轉換指針?
- 9. 爲什麼我們需要在MongoDB中定義數據模型
- 10. 我必須爲NULL指針的malloc?我什麼時候需要爲malloc指針?
- 11. ASP.NET MVC3,爲什麼我們需要強類型的View?
- 12. Ruby:爲什麼我們不需要`attr_accessor`?
- 13. 爲什麼有人需要一個指向指針的指針?
- 14. 爲什麼我們需要使用雙指針來訪問2-D數組?
- 15. 爲什麼我們需要在調用函數時遞減堆棧指針
- 16. 爲什麼指向char的指針與其他數據類型的指針相比表現不同
- 17. 什麼是算法中的抽象數據類型,爲什麼我們需要它們?
- 18. 爲什麼我們需要在C#中類型轉換枚舉
- 19. 爲什麼我們需要做類型轉換這一行
- 20. 使用指針指向數組時,我們要做什麼?
- 21. 爲什麼我們需要抽象類而不是虛擬類?
- 22. 什麼是仿函數,爲什麼我們需要它們?
- 23. 什麼類型的指針
- 24. 爲什麼我們在爲TSR工作時需要遠程指針?
- 25. 爲什麼我會得到「不兼容的指針類型」?
- 26. 爲什麼我得到'不兼容的指針類型'警告?
- 27. 模型中有什麼?爲什麼我們需要使用它
- 28. 爲什麼我們不傳遞指針參數在中的strstr主要功能
- 29. 爲什麼我的C++函數有不同的指針參數?
- 30. 爲什麼我們需要指向結構指針的指針來更改成員值?
」存儲器地址,總是十六進制的「否。這取決於在另一層上的表示。 – glglgl
雖然在網上搜索,我得到了[爲什麼不同類型的指針爲不同的數據類型在C](http://stackoverflow.com/questions/12530806/why-different-types-of-pointer-for-different-data-type- in-c) –
好吧,表示是永遠不可見的... –