1. 程式人生 > 其它 >番外-->資料在計算機的儲存

番外-->資料在計算機的儲存

一些C++擴充套件知識

型別,不光出現在定義變數的時候,還有使用變數的時候。

  1. 型別決定了開闢空間的大小

存的角度,定義變數時使用何種型別就代表分配給變數多大的記憶體空間,這個變數最大能擁有多少空間。

如:int a就分配給了a變數4個位元組的空間,char就是1個位元組。

  1. 看待記憶體空間的方式

取的角度,以什麼樣的方式去看待空間裡的資料,(這邊說是取,其實有點牽強,最多說是看)

int a;unsigned int b;float c;,編譯器認為a是有符號整型,b是無符號整型,c是浮點型

int a = 10;
float b = 10.0f;

ab都是4個位元組,為何還要分你是int我是float

呢?因為看待這4個位元組的視角不一樣,編譯器認為a裡存放的整型資料,而b是浮點型變數。

建立變數的實質是在記憶體上為其開闢一塊空間,空間大小由變數型別決定。那麼資料在記憶體中到底是如何儲存的呢?

一、整型:

我們直接看程式吧:

#include <iostream>

using namespace std;


int main()
{
 
  	int a = 0x12345678;//十六進位制數
  	printf("%d\n",&a);
  
  	char *p;
  	p = (char *)&a;
  
for(int i = 0;i < 4;i++){
	
	printf("%d\n",p + i);//輸出每個位元組的地址
  	printf("%x\n\n",*(p + i));
	
	}
	
	return 0;

}

結果是:

按照一般的想法,應該是12345678才對啊,怎麼按照地址順序成了78563412了呢?這就涉及到整型資料在計算機的儲存。分為小端序和大端序。

在32位系統中,一個int為四個位元組,32位二進位制,資料在記憶體中補碼的形式儲存

==》正數的補碼是本身

==》負數的補碼等於它取反加1

我使用的Dev-C++是一個小端機,記憶體顯示是從低地址開始讀的,說到小端機,一定會有人問是不是還有大端機?

下面我們一起來看看大小端的區別:

大端機:資料低地址存放高位元組,高地址存放低位元組 例:C51微控制器

小端機:資料低地址存放低位元組,高地址存放高位元組 例:X86

一個整型的佔4個位元組 它的地址是用最低位來表示。

!!幾句程式碼檢視什麼端:

int a = 0x12345678;

short *p = (short*)&a;

printf("%#x\n", *p);//小端列印為0x5678,雖然存是低地址存低位元組,但取不一樣。所以是0x5678

一個地址佔8位,16進位制轉換為2進位制佔2個。所以78在一起,56在一起。

二、浮點型

還是直接上例子:

#include <iostream>

using namespace std;

int main()
{
	float a = 178.125;
	
	float *p = &a;	
	
	char *q = (char*)&a;
	
	for(int i = 0;i < 4;i ++){
		
		printf("地址:%d\n",q + i); 
		printf("地址值:%#x\n",*(q + i));
	}
	
	return 0;
	
	
}

結果是這樣:

我們把它轉換成二進位制看看(小端序):0100 0011 0011 0010 0010 0000 0000 0000,這是一件十分頭大的事,看起來就像天書一樣。

現在大致說一下:我們始終記得,計算機只認識二進位制,在計算機中,不管是什麼型別的資料。最終只會變成二進位制,不同的資料型別可能存的值一樣,只是取得方式不一樣。而浮點數在計算機是這樣儲存的:

//(double)1位符號位,11位指數位,52位尾數位。//

如果E為8位,它的取值範圍為0~255;如果E為11位,它的取值範圍為0~2047。但是我們知道,科學計數法中的E是可以出現負數的,所以,存入記憶體時E的真實值必須再加上一個中間數,對於8位的E,這個中間數是127

將十進位制178.125表示成機器內的32位的二進位制形式-->

1:將178.125表示成二進位制數:

(178.125)(十進位制數) = (10110010.001)(二進位制形式);

2:將二進位制形式的浮點實數轉化為規格化的形式:

10110010.001 = 1.0110010001 * 2 ^ 7 (小數點向左移7二進位制位可得)

3:符號位(1位):

該數為正數,故第31位為0,佔一個二進位制位.

4:階碼(8位):

指數為7,故其階碼為127 + 7 = 134 = (10000110)(二進位制),佔從第30到第23共8個二進位制位.

5:尾數(32 - 8 - 1 = 23位):

為小數點後的部分, 即0110010001.因為尾數共23個二進位制位,在後面補13個0,即01100100010000000000000

6:178.125在記憶體中的實際表示方式為:

0 10000110 01100100010000000000000,這是不是我們在程式中看到的場景呢!