計算機上的值的表示可以在“文化”上因架構而異,或者由程式員賦予值的型別決定。因此,如果我們想撰寫可移植的代碼,我們應該嘗試主要針對值而不是表示進行推理。
指定值。我們已經看到了幾種可以指定數字常量(文字)的方法: 123 十進制整數常量。077 八進制整數常量。0xFFFF 十六進制整數常量。等等
問題 - 十進制整數常量和十六進制整數常量是“表示”值的不同方式還是它們本身的值?如果是后者,在不同架構上表示它們的不同方式是什么?
上述內容的來源是 Jens Gustedt 所著的“Modern C”一書,該書可在線免費獲取,來自
https://hal.inria.fr/hal-02383654/document
特別是從第頁。第 38 頁 46.
uj5u.com熱心網友回復:
在這里可以在兩種不同的背景關系中使用“代表”一詞。
一種是當我們(程式員)指定整數常量時。例如,值 37 在 C 代碼中可以表示為37or0x25或045。無論我們選擇哪種表示形式,C 編譯器都會在生成二進制代碼時將其解釋為相同的值。因此,這些陳述句都生成相同的代碼:
int a = 37;
int a = 0x25;
int a = 045;
另一個背景關系是編譯器如何選擇在37內部存盤值。C 標準規定了一些要求(例如, 的表示int必須至少能夠表示范圍內的值-32767到 32767)。在 C 標準的規則內,編譯器將使用位表示,目標系統的 CPU 的本地語言可以有效地操作該位表示。有符號整數最常見的表示是二進制補碼,通常一個有符號整數將占用 2 或 4 個位元組,每個位元組為 8 位。
但是,C 標準足夠靈活以允許其他內部表示(例如,多于 8 位的位元組或帶符號整數的One's 補碼表示)。不同系統上多位元組整數表示的一個常見區別是使用不同的位元組順序。
C 標準主要關注標準操作的結果。例如,5 6必須不管執行哪個平臺表達上給出相同的結果,但如何5,6以及11在給定的平臺上表示,很大程度上取決于編譯器來決定。
uj5u.com熱心網友回復:
十進制整數常量和十六進制整數常量是“表示”值的不同方式還是它們本身的值?
這就是哲學!它們是表示值的不同方式,例如:
0x2 means 2 (for a C compiler)
two means 2 (english language)
a couple means 2 (for an english speaker)
zwei means 2 (...)
AC 編譯器將“某種形式的人類可以理解的語言”翻譯成“一種機器可以理解的非常精確的形式”:從各種形式中唯一保留的是親密的含義(值!)。
碰巧 C 為了更友好,讓你以兩種不同的方式指定整數,十進制和十六進制(好吧,甚至八進制,最近還有二進制表示法)。C 編譯器感興趣的是值,正如評論中已經指出的那樣,在 C “理解”該值之后,“0xC”或“12”之間不再有區別。從那時起,編譯器必須讓機器理解值 12,使用目標機器使用的表示,同樣重要的是值。
最有可能的是,這句話
我們應該嘗試主要針對價值觀而不是表現進行推理
邀請程式員選擇正確的資料型別和值,但不僅如此:還為型別和變數等提供有用的名稱。一個不太好的例子是:即使我們知道換行符(通常)由 10 位小數表示,我們也應該使用 LF 或“\n”或類似的,這是我們想要的值,而不是它的表示。
關于資料型別,尤其是整數,與其他允許您根據可能的值定義型別的語言相比,C 并不是特別出色(例如使用“-3 .. 5”表示法,它指出可能的值來自 - 3 到 5,并讓編譯器選擇表示范圍 -3 到 5所需的位數)。
uj5u.com熱心網友回復:
對于每個 C 程式員來說,理解C 是一個抽象層,使您免受底層硬體的影響至關重要。這項服務是語言存在的理由,也是開發它的原因。除此之外,該語言使您免受用于在不同平臺上保存相同值的不同內部位元組模式的影響:您撰寫一個值并對其進行操作,編譯器將負責生成正確的代碼。這在匯編程式中會有所不同,在那里您密切關注記憶體布局、暫存器大小等。
以防它不明顯:我強調這一點是因為當我學習 C 時,我自己也在努力解決這些概念。
首先要強調的是,C 程式代碼是文本。我們在這里處理的是值的文本表示,一連串(最有可能的)ASCII 代碼,就像您給祖母寫了一封信一樣。
諸如 0443(不太常見的八進制格式)、0x0123 或 291 之類的整數文字只是相同值的不同字串表示形式。在這里和標準中,“值”是數學意義上的值。就像我們想的那樣“哦,C!” 當我們看到“0x0123”時,無非是寫下291的數學值。這就是“值”的意思,例如當標準規定“整數常量的型別是對應的第一個型別時”可以表示其值的串列。” 編譯器必須在程式記憶體中創建該值的二進制表示。這意味著它必須找出它是什么值(在所有情況下都是 291),然后為其生成正確的位元組模式。無論你選擇寫它的字串表示升降底座10,底座16或基地8.特別做0x0123并不意味著兩個位元組01,并23會在編譯程式的任何地方,或以何種順序。1
為了演示抽象,考慮運算式(0x0123 << 4) == 0x1230,它在所有機器上都應該是真的。兩種十六進制文字都屬于int此處型別。十六進制代碼的美妙之處在于它使 4 的倍數的位操作非常容易計算。
在典型的當代 Intel 架構上,int有 4 個位元組,并且組織為“小端優先”,或簡稱為“小端”:如果我們按升序檢查記憶體,則最低值位元組在前。0x123 表示為 00100011-00000001-00000000-00000000(因為對于這么小的數字,兩個最高值位元組為零)。因此,0x1230 是 00110000-00010010-00000000-00000000。硬體上沒有發生任何左移(但也沒有右移!)。位移運算子的語意是一種抽象:“想象一個常規的二進制數,遵循從最高值數字開始的古老阿拉伯時尚,然后移位想象的二進制數。" 它是一種與硬體上發生的任何事情都零相似性的抽象,編譯器只是將這種抽象操作轉換為適合該特定硬體的正確操作。
1現在誠然,它們可能就在那里,但在您流行的 x86 平臺上,它們的順序將被顛倒,如下假設。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/364738.html
上一篇:C中指標的地址是什么?
下一篇:檢查字串是否包含特定單詞
