91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C語言不同類型數據在內存中怎么存儲

發布時間:2022-08-26 14:50:00 來源:億速云 閱讀:166 作者:iii 欄目:開發技術

這篇文章主要講解了“C語言不同類型數據在內存中怎么存儲”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“C語言不同類型數據在內存中怎么存儲”吧!

數據類型的介紹

在我們之前的學習當中我們已經介紹了基本的內置類型

char 字符數據類型

short 短整型

int 整形

long 長整型

long long 更長的整形

float 單精度浮點數

double 雙精度浮點數

這些類型的意義是:

1.使用這個類型開辟內存空間的大小,大小決定了使用范圍

2.如何看待內存空間的視角。

類型的基本歸類

整形

整形中分為有符號整形和無符號整形,因為我們生后中有些數值需要有正數和負數之分,例如溫度我們就可以使用有符號整形,但是有些不需要負數的數值例如身高,我們就可以使用無符號整形。

char

unsigned char

signed char

short

unsigned short [int]

signed short [int]

int

unsigned int

signed int

long

unsigned long [int]

signed long [int]

浮點型

float

double

構造類型

數組類型

結構體類型 struct

枚舉類型 enum

聯合類型 union

指針類型

int pi;

char pc;

float pf;

void pv;

空類型

void表示空類型(無類型)

通常應用于函數的返回類型,函數的參數、指針類型

整形在內存中的存儲

我們都知道,創建一個變量需要在內存中開辟空間,那變量究竟是怎么在內存當中存儲的呢。我們又要提到原碼、反碼、補碼的概念了。

在計算機中整數有三種表示方式即原碼、反碼、補碼,他們都有符號位和數值位,符號位用0表示正數,用1表示負數。

正整數的原碼、反碼、補碼相同,都是直接將屬豬按照正負數的形式翻譯成二進制形式就可以得到原碼。

負整數的原碼、反碼、補碼

原碼

直接將數值按照正負數的形式翻譯成二進制形式就可以得到原碼

反碼

將原碼的符號位不變,其他位一次按位取反就可以得到反碼

補碼

反碼+1就是補碼

對于一個整形,數據在內存當中存放的其實是他的補碼。那么為什么是補碼而是不是原碼呢,原因是使用補碼,可以將符號位和數值域統一處理,同時加法和減法也可以統一處理,我們的cpu只有加法器,此外,補碼與原碼相互轉換,其運算過程是相同的,不需要額外的硬件電路。

例如:

1 - 1
因為cpu中只有加法器,所以我們需要將減法轉化為加法,1+ (-1)如果內存中存儲的是原碼,那么他們相加的結果為
00000000 00000000 00000000 00000001 1的原碼
10000000 00000000 00000000 00000001 -1的原碼
10000000 00000000 00000000 00000010 相加為-2
我們運算的答案是錯誤的,但是當我們存儲的是補碼時:
00000000 00000000 00000000 00000001 1的補碼
11111111 11111111 11111111 11111111 -1的補碼
00000000 00000000 00000000 00000000 相加0
使用補碼運算時,得到正確的答案

int main()
{
	int a = 20;
	int b = -10;
	return 0;
}

C語言不同類型數據在內存中怎么存儲

如上圖編譯器為了方便顯示的是16進制數,其實對于一個整形,數據在內存當中存放的還是他的補碼,我們可以是嘗試還原一下。

例如**-10**
原碼:10000000 00000000 00000000 00001010
反碼:11111111 11111111 11111111 11110101
補碼:11111111 11111111 11111111 11110110
將他的補碼轉換成16進制就變成了ff ff ff f6,跟我們通過調試看到的內容一樣

但是我們通過對比發現雖然存儲的是補碼,但是存儲的順序好像不一樣,這是怎么回事呢?

大小端介紹

當我們的數據大于一個字節時,數據的存儲就有了順序問題。例如:一個十六進制數0x11223344,我們說11為數據的高位,44為數據的低位。

大端存儲模式:是指數據的低位保存在高地址中,而數據的高位,保存在內存的低地址處。

小端存儲模式:是指數據的低位保存在低地址中,而數據的高位,保存在內存的高地址處。

int main()
{
	int a = 0x11223344;
	return 0;
}

C語言不同類型數據在內存中怎么存儲

我們通過調試得出,在vs2019中為小端存儲模式,因為數據的低位44存儲在地址處,高位11存儲在高地址處。

一道筆試題

我們通過一道筆試題來鞏固一下我們剛才所總結的知識。題目:請簡述大端字節序和小端字節序的概念,設計一個小程序來判斷當前機器的字節序。

小端字節序存儲

把數據的低位存儲在內存的低地址處,高位字節的內容,存儲在內存的高地址處 大端字節序存儲 把數據的低字節的內容,存放到內存的高地址處,高字節內容,存放在低地址處

int check_sys()
{
	int a = 1;
	return *(char*)&a;
}
int main()
{
	if (check_sys() == 1)
	{
		printf("小端存儲\n");
	}
	else
	{
		printf("大端存儲\n");
	}
	return 0;
}

C語言不同類型數據在內存中怎么存儲

浮點數在內存中的存儲

首先我們通過一段代碼來觀察浮點數在內存中的存儲

int main()
{
	int n = 9;
	float* pFloat = (float*)&n;
	printf("n的值為:%d\n", n);
	printf("*pFloat的值為:%f\n", *pFloat);
	*pFloat = 9.0;
	printf("num的值為:%d\n", n);
	printf("*pFloat的值為:%f\n", *pFloat);
	return 0;
}

以我們的認識,使用%d打印應該打印9使用%f打印應該打印9.0,但事實是這樣的嘛

C語言不同類型數據在內存中怎么存儲

我們將代碼跑起來發現,并非我們所認識的,那這說明了什么,說明了浮點型與整形在內存當中的存儲規則是不一樣的,那我們先了解一下浮點數究竟怎么儲存的。

浮點數存儲規則

根據國際標準IEEE(電氣和電子工程協會)754,任意一個二進制浮點數v可以表示成下面的形式:

(-1)^S * M * 2^E

(-1)^S表示符號位,當S=0,V為正數;當S=1,V為負數。

M表示有效數字,大于等于1,小于2。

2^E表示指數位。

例如:十進制5.0,寫成二進制是101.0,相當于1.0122

所以s = 0,m = 1.01, e = 2。

IEEE 754規定:

對于32位的浮點數,最高的1位是符號位s,接著的8位是指數E,剩下的23位為有效數字M。對于64位的浮點數,最高的1位是符號位S,接著的11位是指數E,剩下的52位為有效數字M。

IEEE 754對有效數字M和指數E,還有一些特別規定:

前面說過, 1&le;M<2 ,也就是說,M可以寫成 1.xxxxxx 的形式,其中xxxxxx表示小數部分。IEEE 754規定,在計算機內部保存M時,默認這個數的第一位總是1,因此可以被舍去,只保存后面的xxxxxx部分。比如保存1.01的時候,只保存01,等到讀取的時候,再把第一位的1加上去。這樣做的目的,是節省1位有效數字。以32位浮點數為例,留給M只有23位,將第一位的1舍去以后,等于可以保存24位有效數字。

至于指數E,情況就比較復雜:

首先,E為一個無符號整數(unsigned int)這意味著,如果E為8位,它的取值范圍為0 ~ 255;如果E為11位,它的取值范圍為0 ~ 2047。但是,我們知道,科學計數法中的E是可以出現負數的,所以IEEE 754規定,存入內存時E的真實值必須再加上一個中間數,對于8位的E,這個中間數是127;對于11位的E,這個中間數是1023。比如,2^10的E是10,所以保存成32位浮點數時,必須保存成10+127=137,即10001001。

既然我們可以將浮點數存儲,我們就可以將他們取出來,但是指數E從內存中取出分為三種情況:

E不全為0或不全為1

這時,浮點數就采用下面的規則表示,即指數E的計算值減去127(或1023),得到真實值,再將 有效數字M前加上第一位的1。

E全為0

這時,浮點數的指數E等于1-127(或者1-1023)即為真實值,有效數字M不再加上第一位的1,而是還原為0.xxxxxx的小數。這樣做是為了表示&plusmn;0,以及接近于0的很小的數字。

E全為1

這時,如果有效數字M全為0,表示&plusmn;無窮大(正負取決于符號位s)

剖析題目

這些就是浮點數在內存當中的存儲規則,了解了這些后讓我們回到最開始的那道題,我們進行分析。

首先我們創建了一個整形變量,那么他在內存中存儲的是什么呢?是他的補碼00000000000000000000000000001001,當我們將他看作一個浮點數打印時,我們可以得到S = 0,M = 000 0000 0000 0000 0000 1001,E = 00000000。所以經過計算(-1)^ 0 &times; 0.00000000000000000001001&times;2 ^ (-126) = 1.001&times;2 ^ (-146), 所以根據規則他是一個非常接近0的數,使用浮點數打印就是0.000000

筆試題的第二部分,我們將一個浮點型使用整形打印,同樣的道理,我們先將9.0用浮點數的方式存進內存當中,9.0寫成二進制為1001.0,可以寫成(-1)^0 * 1.001*2^3,我們可以推出二進制形式:0 10000010 001 0000 0000 0000 0000 0000,所以將他作為一個整形打印時就會是一個非常大的數為1091567616

感謝各位的閱讀,以上就是“C語言不同類型數據在內存中怎么存儲”的內容了,經過本文的學習后,相信大家對C語言不同類型數據在內存中怎么存儲這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

盈江县| 思南县| 西平县| 虞城县| 离岛区| 五常市| 阿城市| 巴彦淖尔市| 长治县| 襄汾县| 永年县| 斗六市| 梅州市| 本溪市| 子长县| 栾川县| 高邑县| 汕尾市| 西盟| 东阿县| 丹凤县| 潞城市| 咸宁市| 九寨沟县| 鹿邑县| 阿合奇县| 青冈县| 井冈山市| 京山县| 双桥区| 海南省| 青海省| 塔城市| 西乌| 镇原县| 太白县| 平利县| 周至县| 渝中区| 黄平县| 沂南县|