跳轉到內容

C++ 程式設計/學習基礎

來自華夏公益教科書,為開放世界提供開放書籍
Clipboard

待辦事項
在完成出色的清理工作後,此頁面應該被挖掘出可用於C++ 程式設計/程式語言/C++/程式碼/語句/變數的內容,併合併到計算機程式設計華夏公益教科書中,而無需進行任何修改。


二進位制數系統

[編輯 | 編輯原始碼]

大多數計算機系統使用二進位制邏輯執行。計算機使用兩個電壓電平表示值,通常是 0V 表示邏輯 0,而 +3.3V 或 +5V 表示邏輯 1。這兩個電壓電平恰好表示兩個不同的值,按照慣例,這些值是。巧合的是,這兩個值對應於二進位制數系統使用的兩個數字。由於計算機使用的邏輯電平與二進位制數系統使用的兩個數字之間存在對應關係,因此計算機採用二進位制系統也就不足為奇了。

二進位制數格式

[編輯 | 編輯原始碼]

二進位制數系統使用基數 2,它只包含數字01

在美國和其他國家,每三位十進位制數字用逗號分隔,使較大的數字更容易閱讀。例如,123,456,789 比 123456789 更容易閱讀。我們對二進位制數也採用了類似的約定。為了使二進位制數更易讀,我們在小數點左側的最低有效數字開始,每四位數字新增一個空格。例如,二進位制值 1010111110110010 將寫成1010 1111 1011 0010

使用上面的示例1010 1111 1011 0010

  • 最右側的序列(0010)位於位號 0,其值為0。位號 0 稱為最低有效位,或lsb
  • 左側的每個位都分配了下一個連續的位號。位 1位 2等等...
  • 最左側的位(1010)通常稱為最高有效位,或msb,其值為1

我們通常將二進位制數寫成一系列位。不同位的大小有定義的邊界

名稱 大小(位) 示例
1 1
位元組 4 0101
位元組 8 0000 0101
16 0000 0000 0000 0101
雙字 32 0000 0000 0000 0000 0000 0000 0000 0101

在任何進制中,我們可以新增任意數量的領先零而不會改變其值,但在二進位制數系統中,新增領先零會將位調整到所需的大小。例如,我們可以將數字5表示為一個

位 101;

位元組 0101;

位元組 0000 0101;

字 0000 0000 0000 0101; 或

雙字 0000 0000 0000 0000 0000 0000 0000 0101

關於名稱的說明

[編輯 | 編輯原始碼]

字的邊界可以定義為 16 位或處理器的地址匯流排大小。因此,字和雙字不是固定大小,而是根據系統(具體取決於處理器)而有所不同。

對於 8085 和 8086 微處理器,字是一組 16 位。我們從位號 0 (b0) 到十五 (b15) 對字中的位進行編號,如下所示

b15 b14 b13 b12 b11 b10 b9 b8 b7 b6 b5 b4 b3 b2 b1 b0

請記住,b0LSBb15msb,在引用字中的其他位時,請使用它們的位號。請注意,字正好包含兩個位元組。b0-b7構成低位元組,b8-b15構成高位元組。自然,字可以進一步細分為四個位元組。位元組零是低位元組(b0-b4),位元組三是字的高位元組(b12-b15)。另外兩個位元組是“位元組一”和“位元組二”。

使用 16 位,你可以表示2^1665,536個不同的值。這些值可能是範圍為 0 => 65,535 的無符號數值、範圍為 -32,768 => +32,767 的有符號數值,或任何不超過65,536個值的任何其他資料型別。字的三種主要用途是

  • 16 位整型資料值
  • 16 位記憶體地址
  • 任何需要 16 位或更少位的進位制
雙字

雙字就是兩個字,所以雙字量是 32 位。自然,這個雙字可以細分為一個高字和一個低字,四個位元組或八個位元組。

雙字可以表示各種不同的資料

  • 範圍為 0 => 4,294,967,295 的無符號雙字
  • 範圍為 - 2,147,483,648 => +2,147,483,647 的有符號雙字
  • 32 位浮點數
  • 任何需要 32 位或更少位的資料

進位制轉換

[編輯 | 編輯原始碼]

二進位制轉十進位制

[編輯 | 編輯原始碼]

從二進位制數轉換為十進位制數非常容易。

例如,讓我們分解二進位制值1100 1010

數字 1 1 0 0 1 0 1 0
位號 b7 b6 b5 b4 b3 b2 b1 b0
基數 2 2^7 2^6 2^5 2^4 2^3 2^2 2^1 2^0

現在就像十進位制系統一樣,我們將每個數字乘以基數 2及其加權位置值,然後求和,如下所示

1(2^7) 1(128) 128
1(2^6) 1(64) 64
0(2^5) 0(32) 0
0(2^4) 0(16) 0
1(2^3) 1(8) 8
0(2^2) 0(4) 0
1(2^1) 1(2) 2
0(2^0) 0(1) 0
=202

十進位制轉二進位制

[編輯 | 編輯原始碼]

從十進位制轉換為二進位制稍微困難一些。

有兩種方法,除以 2減去加權位置值

除法方法
[編輯 | 編輯原始碼]

為此,我們將十進位制數除以 2,如果餘數是0,則寫下0。如果餘數是1,則寫下1。重複此過程,直到商為0

餘數將表示十進位制數的二進位制等效值。餘數值從最低有效數字寫入最高有效數字。因此,每個新的餘數值都寫在之前的餘數值左側

例如,考慮數字2671

除法 餘數 二進位制數
2671 / 2 1335 1 1
1335 / 2 667 1 11
667 / 2 333 1 111
333 / 2 166 1 1111
166 / 2 83 0 0 1111
83 / 2 41 1 10 1111
41 / 2 20 1 110 1111
20 / 2 10 0 0110 1111
10 / 2 5 0 0 0110 1111
5 / 2 2 1 10 0110 1111
2 / 2 1 0 010 0110 1111
1 / 2 0 1 1010 0110 1111
減法方法
[編輯 | 編輯原始碼]

從一個大於該數字的加權位置值開始。如果該數字小於加權值,則寫下0並減去0。如果該數字大於加權值,則寫下1,但要減去加權值。重複此過程,直到結果為0

在執行減法時,數字將表示從最高有效位到最低有效位的十進位制數的二進位制等效值。因此,每個新數字都寫到前一個數字的右邊

考慮相同的數字,2671

加權值 減法 餘數 二進位制數
2^12 = 4096 2671 - 0 2671 0
2^11 = 2048 2671 -2048 623 01
2^10 = 1024 623 - 0 623 010
2^9 = 512 623 - 512 111 0101
2^8 = 256 111 - 0 111 0 1010
2^7 = 128 111 - 0 111 01 0100
2^6 = 64 111 - 64 47 0 1010 01
2^5 = 32 47 - 32 15 0 1010 011
2^4 = 16 15 - 0 15 0 1010 0110
2^3 = 8 15 - 8 7 0 1010 0110 1
2^2 = 4 7 - 4 3 0 1010 0110 11
2^1 = 2 3 - 2 1 0 1010 0110 111
2^0 = 1 1 - 1 0 0 1010 0110 1111

八進位制數系

[編輯 | 編輯原始碼]

雖然這曾經是一個流行的數制,特別是在數字裝置公司 PDP/8 和其他舊的計算機系統中,但如今很少使用。八進位制系統基於二進位制系統,以 3 位為界。

八進位制系統使用基數 8,它只包含數字 0,1,2,3,4,5,6 和 7(任何其他數字都會使數字成為無效的八進位制數)。

八進位制數字的二進位制形式
八進位制數字 二進位制數
0 000
1 001
2 010
3 011
4 100
5 101
6 110
7 111
現在是每個八進位制位置的加權值
8^6 8^5 8^4 8^3 8^2 8^1 8^0
262144 32768 4096 512 64 8 1

二進位制轉換為八進位制

[編輯 | 編輯原始碼]

將二進位制值轉換為八進位制數很容易。

首先,將二進位制數從LSBMSB分成 3 位的節,然後將 3 位的二進位制數轉換為它的八進位制等效值。

讓我們分解二進位制值1010111110110010

3 位 001 010 111 110 110 010
MSB LSB
八進位制數字 1 2 7 6 6 2

八進位制轉換為二進位制

[編輯 | 編輯原始碼]

從八進位制數轉換為二進位制值也很容易。

將十進位制數轉換為它的 3 位二進位制等效值,然後合併 3 位的節。

讓我們以上面的八進位制數127662為例,將其分解

八進位制數字 3 位
1 001
2 010
7 111
6 110
6 110
2 010

這將產生二進位制數001010111110110010,或者以更易讀的格式表示為0000 1010 1111 1011 0010

八進位制轉換為十進位制

[編輯 | 編輯原始碼]

要將八進位制轉換為十進位制,請將每個位置的值乘以其八進位制權重,然後將每個值加起來。

同樣,讓我們以八進位制值127662為例

1(8^5) 1(32768) 32768
2(8^4) 2(4096) 8192
7(8^3) 7(512) 3584
6(8^2) 6(64) 384
6(8^1) 6(8) 48
2(8^0) 2(1) 2
=44978

十進位制轉換為八進位制

[編輯 | 編輯原始碼]

將十進位制轉換為八進位制稍微困難一些。

將十進位制轉換為八進位制的典型方法是重複除以 8。對於此方法,將十進位制數除以 8,並將餘數寫在旁邊作為最低有效位。透過將商除以 8 並寫入餘數,直到商為 0,繼續此過程。在執行除法時,將表示十進位制數的八進位制等效值的餘數從最低有效位(右邊)開始寫入,並將每個新數字寫入到前一個數字的下一個更高有效位(左邊)。考慮數字 44978。

除法 餘數 八進位制數
44978 / 8 5622 2 2
5622 / 8 702 6 62
702 / 8 87 6 662
87 / 8 10 7 7662
10 / 8 1 2 27662
1 / 8 0 1 127662

如您所見,我們又回到了原來的數字。

十六進位制數系

[編輯 | 編輯原始碼]

二進位制系統的一個大問題是冗長。例如,表示值 202 需要 8 個二進位制數字,而十進位制版本只需要 3 個十進位制數字。特別是對於較大的值,二進位制數變得過於笨拙。十六進位制記數系統解決了這些問題。

十六進位制數非常緊湊,並且易於從十六進位制轉換為二進位制,以及從二進位制轉換為十六進位制。由於我們經常需要將十六進位制數輸入計算機系統,因此我們需要一種不同的機制來表示十六進位制數,因為您無法輸入下標來表示相關值的基數。

十六進位制系統基於二進位制系統,使用一個位元組或 4 位為界。在組合語言程式設計中,大多數彙編器要求十六進位制數的第一個數字為0,並且我們在數字末尾放置一個H來表示數字基數。

十六進位制數系使用基數 16,它只包含數字09以及字母A、B、C、D、EF

此表提供了從 0 到 16 的十進位制值的所有資訊,您可以將其用於將一種數制轉換為任何其他數制。

十進位制 十六進位制 二進位制 八進位制
00 00H 0000 00Q
01 01H 0001 01Q
02 02H 0010 02Q
03 03H 0011 03Q
04 04H 0100 04Q
05 05H 0101 05Q
06 06H 0110 06Q
07 07H 0111 07Q
08 08H 1000 10Q
09 09H 1001 11Q
10 0AH 1010 12Q
11 0BH 1011 13Q
12 0CH 1100 14Q
13 0DH 1101 15Q
14 0EH 1110 16Q
15 0FH 1111 17Q
16 10H 1 0000 20Q

十六進位制轉換為二進位制

[編輯 | 編輯原始碼]

要將十六進位制數轉換為二進位制數

1. 將十六進位制數分解為每個單獨的十六進位制數字

2. 替換每個十六進位制數字對應的二進位制值

3. 每個二進位制值從MSB(左邊)開始到LSB(右邊)寫入

例如,要將0ABCDH轉換為二進位制值,只需根據上面的表格轉換每個十六進位制數字。

十六進位制數字 二進位制值
0 0000
A 1010
B 1011
C 1100
D 1101
0ABCDH = 0000 1010 1011 1100 1101

二進位制轉換為十六進位制

[編輯 | 編輯原始碼]

將二進位制數轉換為十六進位制格式幾乎同樣容易。

例如,給定二進位制數1011001010,第一步是在MSB位置新增兩個零,使其包含 12 位。然後將二進位制值分成 4 位一組,因此修改後的二進位制值變為0010 1100 1010。然後我們在上面的表格中查詢二進位制值並替換相應的十六進位制數字

0010 2
1100 C
1010 A

因此0010 1100 1010 = 2CA

另一個例子,1010111110110010 轉換為 AFB2

十六進位制轉換為十進位制轉換

[編輯 | 編輯原始碼]

每個位置的加權值如下所示

16^0 1
16^1 16
16^2 256
16^3 4096

要將十六進位制轉換為十進位制,請將每個位置的值乘以其加權值,然後加起來。使用上面的表格和前面的例子,0AFB2H,我們預計將獲得十進位制值44978

A(16^3) 10(4096) 40960
F(16^2) 15(256) 3840
B(16^1) 11(16) 176
2(16^0) 2(1) 2
=44978

十進位制轉換為十六進位制

[編輯 | 編輯原始碼]

將十進位制轉換為十六進位制稍微困難一些。典型方法是重複除以 16

雖然我們也可以使用重複減去加權位置值,但這對於較大的十進位制數而言更困難。

除法方法

將十進位制數除以 16,並將餘數寫在旁邊作為最低有效位。繼續此過程,直到商為0。在執行除法時,將表示十進位制數的十六進位制等效值的餘數從最低有效位(右邊)開始寫入,並將每個新數字寫入到前一個數字的下一個更高有效位(左邊)。考慮數字 44978。

除法 餘數 十六進位制數
44978 / 16 2811 2 2
2811 / 16 175 11 B2
175 / 16 10 15 FB2
10 / 16 0 10 0AFB2
44978 = 0AFB2

在 8085 程式中使用十六進位制數時,彙編器通常要求最高有效位十六進位制數字為 0,即使此數字位數超過暫存器的大小。這是彙編器要求,您的值將被正確地彙編。

十六進位制加法

[編輯 | 編輯原始碼]

像十進位制數一樣加法,但:

如果單個數字是 A 到 F,我們必須將其轉換為十進位制等效值(上面的表格中的值),然後加起來。

例如

求 D + C 的和

0DH = 13 以及 0CH = 12 所以;

13 + 12 = 25 因此;

D + C = 25 但是;

如果和大於或等於 16,我們將和替換為和減 16 並進位 1。

例如

25 - 16 = 9;然後

D + C = 19;最後

3) 如果和介於 10 到 15(十進位制)之間,我們將用等效的十六進位制數字替換和,例如

進位 --> 1 1
DF6D
+ 246C
溢位 --> 1 03D9

二進位制和十六進位制加法的更多示例:

進位 --> 11111
111011
+ 100111
溢位 --> 1 100010
進位 --> 1 1
11001
+ 01101
溢位 --> 1 00110
1235
+ 567A
無溢位 --> 68AF
進位 --> 111
A9876
+ FDCA0
溢位 --> 1 A7516

不同數制之間的轉換

[編輯 | 編輯原始碼]

位置數制

[編輯 | 編輯原始碼]

我們的十進位制數制被稱為位置數制,因為數字的值取決於數字的位置。例如,數字 123 與 321 不同,即使使用了相同的數字。其他古代數制使用額外的符號來表示更大的值,但在位置數制中,每個數字的值由它在整個數字中的位置決定。最低位值是右邊的位置,每個連續的左邊的位置具有更高的位值。最右邊的位置代表“個位”列,下一個位置代表“十位”列,下一個位置代表“百位”等。因此,數字 123 代表 1 個百和 2 個十和 3 個一,而數字 321 代表 3 個百和 2 個十和 1 個一。

每個位置的值對應於數制基數的冪。因此,對於我們的十進位制數制,它使用基數 10,位值對應於 10 的冪

10^0 = 1
10^1 = 10
10^2 = 100
10^3 = 1000

從其他進位制轉換到十進位制

[編輯 | 編輯原始碼]

其他數制使用不同的基數。二進位制數制使用基數 2,因此二進位制數字的數字的位值對應於 2 的冪。

例如,二進位制數 10011 的值是透過計算 該數字的每個二進位制位 的位值來確定的

1 0 0 1 1 二進位制數
(2^4) (2^3) (2^2) (2^1) (2^0) 位值

因此,二進位制數 10011 代表值

1 (2^4) + 0(2^3) + 0 (2^2) + 1 (2^1) +1 ( 2^0)
= 16 + 0 + 0 + 2 + 1
= 19

相同的原理適用於任何進位制。例如,數字 2132(以 5 為基) 對應於

2 1 3 2 以 5 為基的數字
(5^3) (5^2) (5^1) (5^0 位值

因此,數字 2132(以 5 為基) 的值是

2(5^3) +1(5^2) +3(5^1) +2(5^0)
=2(125) +1(25) +3(5) +2(1)
= 250 +25 +15 +2
= 292

從十進位制轉換到其他進位制

[編輯 | 編輯原始碼]

為了將十進位制數轉換為不同的進位制,我們必須能夠用其他進位制的冪來表示該數字。要將十進位制數 100 轉換為 4 進位制,我們必須弄清楚如何將 100 表示為 4 的冪之和,例如

100= 1(64) + 2(16) + 1(4) + 0(1)
= 1(4^3) + 2(4^2) + 1(4^1) + 0(4^0)

然後我們使用 4 的冪的係數來形成以 4 進製表示的數字

100 = 1 2 1 0 4 進位制

另一種方法是重複地將十進位制數除以要轉換到的進位制,直到商為零。當數字被除時,餘數 - 反向順序 - 形成數字在其他進制中的數字。例如

將十進位制數 82 轉換為 6 進位制

82/6 = 13 餘數 4
13/6 = 2 餘數 1
2/6 = 0 餘數 2

答案是透過反向順序取餘數 形成的:2 1 4(以 6 為基)

數制之間的轉換示例

十進位制 二進位制 十六進位制
255 1111 1111 FF
93 0101 1101 5D

定長二進位制數

[編輯 | 編輯原始碼]

計算機算術是在儲存在定長記憶體位置中的資料上執行的,通常為 8 位、16 位或 32 位。

操作定長數字會遇到特殊問題。數字 280(以 10 為基)大於最大 8 位數;這會導致二進位制表示中超過 8 位的進位,以及十六進位制表示中超過兩位的進位。在使用定長數字進行算術運算時,這些進位可能會丟失。

十進位制 二進位制 十六進位制
201 11001001 C9
+79 +01001111 +4F
280 1 00011000 1 18

符號位- 使用一位表示符號,7 位表示數字。

示例:-1(在 8 位系統中)可以是 1000 0001(以 2 為基)

補碼(在計算中最常使用)

示例:表示 -1(在 8 位系統中)的補碼數字為 1111 1111(以 2 為基)

考慮腳踏車上的里程錶數字:考慮腳踏車上的里程錶數字

十進位制示例里程錶數字可用於帶符號數字的加法和減法(補碼)。- 2 + 998 + 3 + 003 + 1 1 001

在第二個示例中,正確的結果只是 +001;溢位在定長補碼算術中被忽略。使用補碼將減法視為加法,即 A - B = A + (-B) 重要提示:計算 -B 並相加比直接減法更容易。示例:- 005 + 995 + 003 + 997 + 008 1 992

請注意,995 和 997 以正常方式相加,溢位被忽略,結果為 992,它可以從補碼(或里程錶)系統轉換回 -8,即正確答案。

signed   3-bit complement
    +3   003
    +2   002
    +1   001
     0   000
    -1   999
    -2   998
    -3   997
    -4   996
    -5   995
    -6   994
    -7   993
    -8   992

十進位制 補碼 二進位制

  +127   01111111
  +126   01111110
  +125   01111101
   ...   ........
    +2   00000010
    +1   00000001
     0   00000000
    -1   11111111
    -2   11111110
   ...   ........
  -127   10000001
  -128   10000000

在 8 位定長補碼數制中,有 256 個數字。為什麼這些數字被稱為補碼?M - N = M + (-N),其中 -N 是 N 的補碼。

示例:十進位制

   + 1   =     00000001
   - 1   =   + 11111111
     0   =   1 00000000

它不等於 2^8 或 256;忽略溢位,正確答案為零。現在我們需要一種簡單的方法來執行補碼運算。

示例:-27(以 10 為基)在補碼 8 位表示法中的表示是什麼?

 2^8 - 1     11111111

- 27 - 00011011

             11100100   corresponds to flipping all the bits;
                        also known as 1's complement
   add 1   + 00000001
  result     11100101   -27 in 2's complement representation

這種方法是必要的,因為:1. 計算機中儲存的數字的定長特性 2. 實現快速加法器比實現加法器和減法器更有效率 ________________________________________ 補碼數字運算示例 補碼形式的加法和減法 • 加法:要計算 N1 + N2,將 N1 加到 N2 • 減法:要計算 N1 - N2,將 N1 加到 -N2 示例:十進位制 二進位制 十六進位制

   11   =     00001011   =     000B
 + 21   =   + 00010101   =   + 0015
   32   =     00100000   =     0020
   21   =     00010101   =     0015
 - 11   =   + 11110101   =   + FFF5
   10   =     00001010   =     000A
   11   =     00001011   =     000B
 - 21   =   + 11101011   =   + FFEB
 - 10   =     11110110   =     FFF6
 - 11   =     11110101   =     FFF5
 - 21   =   + 11101011   =   + FFEB
 - 32   =   1 11100000   =     FFE0

我們如何得到 -11 和 -21 的補碼

11     00001011

~11 - 11110100 1 的補碼 + 1 + 00000001 加 1 -11 11110101 補碼錶示

演算法 1. 儲存 N。2. 獲取 ~N,即 N 的 1 的補碼,方法是在數字的二進位制表示中(逐位)將每個 0 替換為 1,反之亦然。3. 加 1 並忽略第八位後的任何進位。注意:此演算法在十六進位制中有效,方法是將每個數字 x 替換為其十六進位制補碼,即 15 - x。示例:11 的十六進位制等效值為 $000B;然後其十六進位制補碼為 $FFF4,其中每個數字都計算為 $F - x。將 $FFF4 加 1 會得到 $FFF5,即 11 的補碼。(在數字前面使用美元符號 ($) 表示它是 16 進位制。)示例:在二進位制中

N     0000 0110 0100 0111

~N - 1111 1001 1011 1000 1 的補碼 +1 + 0000 0000 0000 0001 加 1 -N 1111 1001 1011 1001 補碼錶示

在十六進位制中

N     0647

~N - F9B8 1 的補碼 +1 + 0001 加 1 -N F9B9 補碼錶示

計算器將始終直接為您提供補碼。最高有效位 (MSB) 是對應於 2 的最大冪的二進位制位,對於負補碼數字,它始終為 1。因此,它通常被稱為符號位。在補碼中,-0 = +0。從技術上講,0 是其自身的補碼。

N     00000000

~N - 11111111 1 的補碼 +1 + 00000001 加 1 -N 00000000 補碼錶示

________________________________________ 定長算術問題 溢位和下溢 對於 16 位定長數制,

新增帶符號數字很容易超過這些限制。第一位

      0011   $3000
      0110   $6000
      1001   $9000

此結果,來自在數制中新增兩個正數,結果為 $9000,它大於 $7FFF,即允許的最大正數。實際上,$9000 等於 1001 0000 0000 0000,它是一個負數。結果的符號與運算元的符號不同。規則:如果在新增兩個正補碼數字時發生符號變化,則發生了溢位。我們可以將這些規則推廣到帶符號的加法和減法。

符號擴充套件 如果數字的長度不同怎麼辦?十進位制 補碼 二進位制

         3-bit 4-bit  8-bit
    +3   011   0011   00000011
    +2   010   0010   00000010
    +1   001   0001   00000001
     0   000   0000   00000000
    -1   111   1111   11111111
    -2   110   1110   11111110
    -3   101   1101   11111101
    -4   100   1100   11111100

要將補碼數字擴充套件到更多的二進位制位,您只需將符號位向左繼續擴充套件。示例:將 $9B 擴充套件到 16 位。$9B = 1001 1011 = 1111 1111 1001 1011 = $FF9B

將 $5F 擴充套件到 16 位。$5F = 0101 1111 = 0000 0000 0101 1111 = $005F

新增兩個不同長度的補碼數字 43A0 43A0

 9B     FF9B   need to sign extend; you can't just add zeros.

???? 1 433B

請注意,8 位 $9B 和 16 位 $FF9B 在各自的數制中都表示 -101。

華夏公益教科書