摘要:還不清楚原碼反碼補(bǔ)碼的可以到語言從入門到入土操作符篇中的移位操作符處學(xué)習(xí)一下。比如原碼反碼補(bǔ)碼原碼顯示值補(bǔ)碼數(shù)據(jù)存放內(nèi)存中其實(shí)存放的是補(bǔ)碼補(bǔ)碼的表示與存儲(chǔ)在計(jì)算機(jī)系統(tǒng)中,數(shù)值一律用補(bǔ)碼來表示和存儲(chǔ)。
前言:
這一篇我們來深度剖析數(shù)據(jù)在內(nèi)存中的存儲(chǔ),讓我們走進(jìn)數(shù)據(jù)在內(nèi)存中到底是任何進(jìn)行存儲(chǔ)的,不同的數(shù)據(jù)類型有何差異。
基本內(nèi)置類型(即為C語言本身具有的類型):
我們先前學(xué)到的這幾類基本類型:
數(shù)據(jù)類型 | 說明 |
---|---|
char | 字符數(shù)據(jù)類型 |
short | 短整型 |
int | 整形 |
long | 長(zhǎng)整型 |
long long | 更長(zhǎng)的整形 |
float | 單精度浮點(diǎn)數(shù) |
double | 雙精度浮點(diǎn)數(shù) |
ps:一些較為老的編譯器中沒有l(wèi)ong long類型。
類型的兩個(gè)重要意義:
對(duì)于第一個(gè)意義,我們可以拆開來看待:
1.這么多種類型又如何分類?
我們可以歸類一下,因?yàn)閏har字符在底層存儲(chǔ)的時(shí)候是ASCII碼值,ASCII碼值為整數(shù),所有也算屬于整形。所以上面的char到long long 都屬于整形家族,float和double為浮點(diǎn)數(shù)家族。
2.而為什么要有整形浮點(diǎn)型的劃分呢?
因?yàn)槲覀兩钪械教幎际钦麛?shù)和小數(shù)。
3.為什么要有如短整型長(zhǎng)整形,單精度雙精度之分呢?
這是因?yàn)槲覀冊(cè)趧?chuàng)建類型的內(nèi)存大小直接影響我們所能存儲(chǔ)的范圍大小,簡(jiǎn)單來說就是能使用適當(dāng)?shù)目臻g去存儲(chǔ)適當(dāng)?shù)闹担恢劣谔蟮目臻g浪費(fèi)或越界溢出。
而第二個(gè)意義中,就是類似于同一種事務(wù)以不同的看法去看待它和對(duì)待它。
比如下面代碼:
int main(){ int a = 10; float b = 10.0f; return 0;}
在這里,a和b所創(chuàng)建的類型都是4個(gè)字節(jié),而不同的是類型,當(dāng)你用int類型創(chuàng)建的時(shí)候,a的創(chuàng)建,存取都是按照整形來操作;同理在創(chuàng)建b的時(shí)候,就是完全按照float類型來了。
具體有什么不同,我們接著往下看就知道了。
ps:[ ]內(nèi)可省略,如 signed short int
可寫為signed short
,或者short int
也可以寫為short
。
類型 | 類別 |
---|---|
char | unsigned char signed char |
short | unsigned short [int] signed short [int] |
int | unsigned int signed int |
long | unsigned long [int] signed long [int] |
我們可以看到在整形家族中,每個(gè)類型分為有無符號(hào)兩種,而一般我們?cè)诰幾g過程中,定義一個(gè)整形的時(shí)候并沒有在前面寫有無符號(hào),這時(shí)一般默認(rèn)為有符號(hào)。如:int a = 10;
定義的a就是有符號(hào)的,short和long同樣適用。
但char 在定義的時(shí)候,默認(rèn)符號(hào)取決于編譯器,大多數(shù)編譯器中char是有符號(hào)的char,即為signed char。
即:
#include int main(){ //有無符號(hào)? char a;//取決于編譯器 short b;//等于 signed short int c;//等于 signed int long d;//等于 signed long return 0;}
那么有符號(hào)和無符號(hào)有什么區(qū)別呢?
我們知道,整數(shù)有原反補(bǔ)三種編碼方式,原碼為顯示數(shù)值的形式,補(bǔ)碼為在內(nèi)存中存儲(chǔ)的形式。
有符號(hào)的原碼中,最高位為符號(hào)位,即0代表正號(hào),1代表符號(hào),其他位是有效(數(shù)值)位。而無符號(hào)的原碼中,全部為有效(數(shù)值)位。
我們來看這一段代碼:
int main(){ unsigned char c1 = 255; signed char c2 = 255; char c3 = 255; printf("%d/n", c1); printf("%d/n", c2); printf("%d/n", c3); //三個(gè)輸出分別是多少? return 0;}
答案是: 255 ,-1 , -1 。
還不清楚原碼反碼補(bǔ)碼的可以到 【C語言】從入門到入土(操作符篇)中的移位操作符處學(xué)習(xí)一下。也可以先看下面也有介紹。
當(dāng)我們將255儲(chǔ)存的時(shí)候,其原碼為11111111,因?yàn)檎龜?shù)原反補(bǔ)碼相同,所有在內(nèi)存中存儲(chǔ)的時(shí)候也是11111111。不清楚我們可以打開內(nèi)存中查看。在vs2019中 F10運(yùn)行起來,然后點(diǎn)擊調(diào)試——窗口——內(nèi)存——內(nèi)存1,然后輸入地址就可以看見了。
這里是十六進(jìn)制顯示,一個(gè)f就是15,也就是二進(jìn)制中1111,兩個(gè)f所以就是11111111,證明我們的原碼是正確的。那這里為什么有255和-1兩個(gè)結(jié)果呢?答案就在符號(hào)位那里:
int main(){ unsigned char c1 = 255; signed char c2 = 255; char c3 = 255; //存進(jìn)去時(shí),都是 11111111 printf("%d/n", c1); //取c1的時(shí)候,c1無符號(hào),都是有效位,值為255 printf("%d/n", c2); //取c2的時(shí)候,c2有符號(hào),第一位符號(hào)位,是負(fù)數(shù),需要算出原碼再得值 //補(bǔ)碼11111111 反碼11111110 原碼10000001 所以c2= -1 printf("%d/n", c3); //與c2同理得-1 return 0;}
當(dāng)有符號(hào)和無符號(hào)存進(jìn)去的時(shí)候都是255,但取出來的時(shí)候就在判斷有無符號(hào)的時(shí)候產(chǎn)生了差異,這里既然同一個(gè)數(shù)存儲(chǔ)取出的時(shí)候有不同,那有無符號(hào)的范圍也是有所不同的。
有符號(hào)char因?yàn)橛胸?fù)數(shù)域,所以范圍是 -128~127。
無符號(hào)char因?yàn)闊o符號(hào),所以范圍是0~255,沒有負(fù)數(shù)。
而從char中,我們也可以延申計(jì)算出short,int,long等有無符號(hào)的范圍,這里就不一一計(jì)算了,有興趣的可以自己算一下。
float
double
浮點(diǎn)型家族中有單精度浮點(diǎn)型和雙精度浮點(diǎn)型,什么時(shí)候用單精度什么時(shí)候用雙精度取決于你需要精度多高,你需要更高精度用double,不需要就用float,在float足夠用時(shí)用double的話會(huì)浪費(fèi)內(nèi)存空間。
構(gòu)造類型就是自己能夠創(chuàng)造的類型,自定義類型。
數(shù)組類型
結(jié)構(gòu)體類型 struct
枚舉類型 enum
聯(lián)合類型 union
1.數(shù)組也是有類型的。
int main(){ int a = 0; //整形類型 int arr[10] = { 0 }; //數(shù)組,arr為數(shù)組名 //去掉數(shù)組名就是數(shù)組類型,在這里數(shù)組類型是int return 0;}
我們可以驗(yàn)證一下,當(dāng)我們創(chuàng)建類型后需要計(jì)算類型大小的時(shí)候,我們可以用變量名來進(jìn)行計(jì)算,也可以用類型來計(jì)算。
int main(){ int a = 0; int arr[10] = { 0 }; printf("%d/n", sizeof(a));//4 printf("%d/n", sizeof(int));//4 printf("%d/n", sizeof(arr));//40 printf("%d/n", sizeof(int [10]));//40 //答案是一樣的,說明數(shù)組除去數(shù)組名就是數(shù)組類型 return 0;}
2.關(guān)于結(jié)構(gòu)體
關(guān)于結(jié)構(gòu)體可以查看操作符篇中的詳解。
3.枚舉類型
枚舉類型定義的一般形式為:
enum 枚舉名{ 枚舉值表 };
在枚舉值表中應(yīng)羅列出所有可用值。這些值也稱為枚舉元素。
4.聯(lián)合類型
在后面的博客中再做詳解。
int *pi;char *pc;float* pf;void* pv;
指針也是有類型的。
當(dāng)我們需要將一個(gè)變量的地址保存起來的時(shí)候,我們就需要用到指針,例如下面這段代碼中,p就把num
的地址儲(chǔ)存了起來,p就是指針變量:
int num = 10;p = #
而指針的定義方式是: type + * ,如char * p
;
其實(shí):
char*
類型的指針是為了存放char
類型變量的地址。short*
類型的指針是為了存放short
類型變量的地址。int*
類型的指針是為了存放int
類型變量的地址。
而指針類型的意義就在于確定了該指針的類型,就決定了指針向前或者向后走一步有多大(距離)。
void 表示空類型(無類型)
通常應(yīng)用于函數(shù)的返回類型、函數(shù)的參數(shù)、指針類型。
我們看下面兩段代碼:
void fun(){ printf("hello!");}int main(){ fun(); fun(10086); //正常運(yùn)行,輸出hello!hello! return 0;}
void fun(void){ printf("hello!");}int main(){ fun(); fun(10086); //能運(yùn)行,但錯(cuò)誤列表中提示錯(cuò)誤,輸出hello!hello! return 0;}
當(dāng)我們調(diào)用自定義函數(shù)時(shí),我們不設(shè)傳參,但在主函數(shù)中有值傳過去,結(jié)果也是不影響的,因?yàn)閒un函數(shù)根本沒有接收這個(gè)傳參,我們也可以直接在函數(shù)后寫上void拒絕接收。
我們可以直接在vs2019中去輸入下列代碼,然后點(diǎn)擊INT_MAX
,轉(zhuǎn)到定義,就可以查看int的最大值和最小值了,同時(shí)還可以看到其他整形的最大最小值。
#include //整形限制大小頭文件INT_MAX;
當(dāng)一個(gè)變量創(chuàng)建的時(shí)候是要在內(nèi)存中開辟空間的。空間的大小是根據(jù)不同的類型而決定的。
那數(shù)據(jù)在空間中是任何開辟的呢?
比如int a = -1
,創(chuàng)建這個(gè)整形變量之后,內(nèi)存中會(huì)如何變化,我們來觀察觀察。
這里我們創(chuàng)建了一個(gè)變量a,F(xiàn)10代碼走起來之后,我們點(diǎn)擊查看內(nèi)存中的變化,地址寫&a,我們會(huì)發(fā)現(xiàn)當(dāng)執(zhí)行完int a = -1
后,&a處地址的值變成了ff ff ff ff,我們知道一個(gè)f就是4個(gè)1(十六進(jìn)制轉(zhuǎn)二進(jìn)制),那-1為什么會(huì)儲(chǔ)存中是8個(gè)f呢,這里就引進(jìn)數(shù)據(jù)在儲(chǔ)存是有原反補(bǔ)三種編碼方式了。
計(jì)算機(jī)中的有符號(hào)數(shù)有三種表示方法,即原碼、反碼和補(bǔ)碼。三種表示方法均有符號(hào)位和數(shù)值位兩部分,符號(hào)位都是用0表示“正”,用1表示“負(fù)”,而數(shù)值位三種表示方法各不相同。正數(shù)的原、反、補(bǔ)碼都相同,負(fù)數(shù)則按下面規(guī)則進(jìn)行運(yùn)算。
原碼:
直接將二進(jìn)制按照正負(fù)數(shù)的形式翻譯成二進(jìn)制就可以。
反碼:
將原碼的符號(hào)位不變,其他位依次按位取反就可以得到了。
補(bǔ)碼:
反碼+1就得到補(bǔ)碼。
比如:
int main(){ int a = -1; //原碼:1 0000000 00000000 00000000 00000001 //反碼:1 1111111 11111111 11111111 11111110 //補(bǔ)碼:1 1111111 11111111 11111111 11111111 //原碼:顯示值 //補(bǔ)碼:數(shù)據(jù)存放內(nèi)存中其實(shí)存放的是補(bǔ)碼 return 0;}
在計(jì)算機(jī)系統(tǒng)中,數(shù)值一律用補(bǔ)碼來表示和存儲(chǔ)。
原因在于,使用補(bǔ)碼,可以將符號(hào)位和數(shù)值域統(tǒng)一處理; 同時(shí),加法和減法也可以統(tǒng)一處理(CPU只有加法器)此外,補(bǔ)碼與原碼相互轉(zhuǎn)換,其運(yùn)算過程是相同的,不需要額外的硬件電路。
單純理解可能有點(diǎn)困難,我們可以舉例理解:
int main(){ int a = 1; int b = -1; int c = a - b; //c是怎么計(jì)算的呢 return 0;}
由于CPU只有加法器,所以表示為1+(-1)。
假設(shè)是用原碼計(jì)算(二進(jìn)制運(yùn)算):
a:00000000 00000000 00000000 00000001
b:10000000 00000000 00000000 00000001
—————————————————————
c:10000000 00000000 00000000 00000010
結(jié)果為-2,但是1-1應(yīng)該等于0呀。
用補(bǔ)碼計(jì)算:
a:00000000 00000000 00000000 00000001
b:11111111 11111111 11111111 11111111
—————————————————————
c:100000000 00000000 00000000 00000000
最前面的1會(huì)舍棄,保留后面的0得:
c:00000000 00000000 00000000 00000000
結(jié)果為0,這才是正確的答案。
所以說使用補(bǔ)碼,可以將符號(hào)位和數(shù)值域統(tǒng)一處理。
而最后一句,補(bǔ)碼與原碼相互轉(zhuǎn)換,其運(yùn)算過程是相同的,不需要額外的硬件電路。就是說上面原碼轉(zhuǎn)反碼,反碼轉(zhuǎn)補(bǔ)碼的過程,還有倒回去也是成立的,不需要其他算法。
之前我們認(rèn)識(shí)的原反補(bǔ)轉(zhuǎn)換:
而這句話中的原反補(bǔ)轉(zhuǎn)換:
也就是怎么從原碼轉(zhuǎn)換補(bǔ)碼,也可以以同樣的方式按順序從補(bǔ)碼轉(zhuǎn)換為原碼。
我們?cè)倏纯矗瑪?shù)據(jù)存儲(chǔ)中有什么地方值得我們關(guān)注的,內(nèi)存中有什么秘密,我們看一下這張圖:
圖中我們創(chuàng)建了兩個(gè)變量,一正一負(fù),然后我們算出a和b在存儲(chǔ)中的十六進(jìn)制表現(xiàn)形式,發(fā)現(xiàn)和內(nèi)存中倒了過來,我們明明得出a是00 00 00 ff,而在內(nèi)存中顯示為ff 00 00 00,這就涉及到大小段的概念了。
大端(存儲(chǔ))模式,是指數(shù)據(jù)的低位保存在內(nèi)存的高地址中,而數(shù)據(jù)的高位,保存在內(nèi)存的低地址中;
小端(存儲(chǔ))模式,是指數(shù)據(jù)的低位保存在內(nèi)存的低地址中,而數(shù)據(jù)的高位,,保存在內(nèi)存的高地址中。
為什么會(huì)有大小端:
因?yàn)樵谟?jì)算機(jī)系統(tǒng)中,我們是以字節(jié)為單位的,每個(gè)地址單元都對(duì)應(yīng)著一個(gè)字節(jié),一個(gè)字節(jié)為
8bit
。但是在C語言中除了8bit
的char之外,還有16bit
的short型,32bit
的long型(要看具體的編譯器),另外,對(duì)于位數(shù)大于8位的處理器,例如16位或者32位的處理器,由于寄存器寬度大于一個(gè)字節(jié),那么必然存在著一個(gè)如果將多個(gè)字節(jié)安排的問題。因此就導(dǎo)致了大端存儲(chǔ)模式和小端存儲(chǔ)模式。
例如一個(gè) 16bit
的 short 型 x ,在內(nèi)存中的地址為 0x0010
, x 的值為 0x1122
,那么 0x11
為高字節(jié), 0x22
為低字節(jié)。對(duì)于大端模式,就將 0x11
放在低地址中,即 0x0010
中, 0x22
放在高地址中,即 0x0011
中。小端模式,剛好相反。我們常用的 X86 結(jié)構(gòu)是小端模式,而 KEIL C51 則為大端模式。很多的ARM,DSP都為小端模式。有些ARM處理器還可以由硬件來選擇是大端模式還是小端模式。
我們來看一個(gè)更詳細(xì)的例子:
0x表示以十六進(jìn)制表示值,這樣子我們就很直觀的看見。我們所存儲(chǔ)的變量,在內(nèi)存中恰恰反著存儲(chǔ)了過來。
其實(shí),數(shù)據(jù)在內(nèi)存中存儲(chǔ)時(shí),我們可以選擇千奇百怪的存儲(chǔ)方式,我們可以存進(jìn)去時(shí)為11 33 22 44
,也可以是22 33 11 44
,但是為了規(guī)整統(tǒng)一,存取方便,我們就把其他的都除去了,留下了大小端這兩種存儲(chǔ)方式。
大小端圖示:
其實(shí)大小端儲(chǔ)存模式就是牽扯到數(shù)據(jù)存儲(chǔ)到內(nèi)存時(shí)字節(jié)順序的一個(gè)問題,而我們當(dāng)前的vs2019就是小段字節(jié)序。
3.14159 ,1E10 (即為1.0乘以10的10次方),浮點(diǎn)數(shù)家族包括: float、double、long double 類型。
① 查看浮點(diǎn)數(shù)的大小范圍與整形的查看類似,float.h
頭文件就是浮點(diǎn)數(shù)限制大小發(fā)文件。寫出下列代碼,然后點(diǎn)擊FLT_MAX
,轉(zhuǎn)到定義,就可以查看了。
#include FLT_MAX;
②也可以在電腦中直接搜索float.h文件,然后把他拖到vs編譯器里面,也可以查看,直接用此電腦查看估計(jì)比較緩慢,這里推薦一個(gè)查找器everything(基于名稱快速定位文件和文件夾。)。
快速查找定位文件和文件夾:
整形與浮點(diǎn)型存儲(chǔ)方式是不是一樣的呢?
我們可以用一個(gè)代碼來試驗(yàn)一下就知道了,我們存一個(gè)整形以浮點(diǎn)型的形式取出,存浮點(diǎn)型以整形的形式取出,看看數(shù)值是否正確便知。
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;}
結(jié)果是不一樣的!以整形存儲(chǔ)進(jìn)去浮點(diǎn)型拿出的9得到的是0.00000,而浮點(diǎn)型存進(jìn)去整形拿出的9.0竟然成了1091567616。
所以我們要重新理解浮點(diǎn)型是如何存儲(chǔ)的。
根據(jù)國際標(biāo)準(zhǔn)IEEE(電氣和電子工程協(xié)會(huì)) 754,任意一個(gè)二進(jìn)制浮點(diǎn)數(shù)V可以表示成下面的形式:
- (-1)^S * M * 2^E
- (-1)^s表示符號(hào)位,當(dāng)s=0,V為正數(shù);當(dāng)s=1,V為負(fù)數(shù)。
- M表示有效數(shù)字,大于等于1,小于2。
- 2^E表示指數(shù)位。
舉例來說:
在這里,十進(jìn)制小數(shù)點(diǎn)前面的,均按照二進(jìn)制換算進(jìn)行,而小數(shù)點(diǎn)后面的,則不是直接換算,而是小數(shù)點(diǎn)后面每一位,對(duì)應(yīng)著2的負(fù)n次方的值,比如上面的5.5轉(zhuǎn)換后是101.1,小數(shù)點(diǎn)后面第一位表示的就是2的負(fù)一次方,即為0.5,小數(shù)點(diǎn)后面第二位就是0.25。但不要糾結(jié)如3.3的數(shù)字,這類數(shù)是比較難以保存的。
同理,當(dāng)浮點(diǎn)數(shù)為負(fù)數(shù)的時(shí)候,s就是1,其他的不變。比如十進(jìn)制的-5.0,寫成二進(jìn)制是 -101.0 ,相當(dāng)于 -1.01×2^2 。那么,s=1,M=1.01,E=2。
所以根據(jù)上述IEEE754規(guī)定,浮點(diǎn)數(shù)存儲(chǔ)的時(shí)候只需要存儲(chǔ)S,M,E三個(gè)數(shù)就可以了。
而存儲(chǔ)時(shí)空間的分配:
對(duì)于32位的浮點(diǎn)數(shù),最高的1位是符號(hào)位s,接著的8位是指數(shù)E,剩下的23位為有效數(shù)字M。
對(duì)于64位的浮點(diǎn)數(shù),最高的1位是符號(hào)位S,接著的11位是指數(shù)E,剩下的52位為有效數(shù)字M。
IEEE 754對(duì)有效數(shù)字M和指數(shù)E,還有一些特別規(guī)定!
①有效數(shù)字M:
前面說過, 1≤M<2 ,也就是說,M可以寫成 1.xxxxxx 的形式,其中xxxxxx表示小數(shù)部分。
IEEE 754規(guī)定,在計(jì)算機(jī)內(nèi)部保存M時(shí),默認(rèn)這個(gè)數(shù)的第一位總是1,因此可以被舍去,只保存后面的xxxxxx部分。比如保存1.01的時(shí)候,只保存01,等到讀取的時(shí)候,再把第一位的1加上去。這樣做的目的,是節(jié)省1位有效數(shù)字。以32位浮點(diǎn)數(shù)為例,留給M只有23位,將第一位的1舍去以后,等于可以保存24位有效數(shù)字。
也就是說,所有的浮點(diǎn)數(shù)都可以化為(-1)^S * M * 2^E
這樣的形式,小數(shù)也不例外,比如0.5,化為0.1,也就是(-1)^0*1.0*2^(-1)
。
②指數(shù)E:
1.首先,E為一個(gè)無符號(hào)整數(shù)(unsigned int)
這意味著,如果E為8位,它的取值范圍為0~255
;如果E為11位,它的取值范圍為0~2047
。但是我們上面的0.5轉(zhuǎn)換時(shí)就已經(jīng)發(fā)現(xiàn),E是有可能為負(fù)數(shù)的。所以IEEE754又規(guī)定了:
存入內(nèi)存時(shí)E的真實(shí)值必須再加上一個(gè)中間數(shù),對(duì)于8位的E,這個(gè)中間數(shù)是127;對(duì)于11位的E,這個(gè)中間數(shù)是1023。比如,2^10
的E是10,所以保存成32位浮點(diǎn)數(shù)時(shí),必須保存成10+127=137,即10001001;而2^(-1)
存進(jìn)去時(shí),保存的便是-1+127=126,011111110。
2.那存進(jìn)去的形式有了,取出的時(shí)候如何呢?
指數(shù)E從內(nèi)存中取出還可以再分成三種情況:
這時(shí),浮點(diǎn)數(shù)就采用下面的規(guī)則表示,即指數(shù)E的計(jì)算值減去127(或1023),得到真實(shí)值,再將有效數(shù)字M前加上第一位的1,即為怎么存的就怎么取。
當(dāng)E全為0時(shí),浮點(diǎn)數(shù)的指數(shù)E等于1-127(或者1-1023)即為真實(shí)值,是一個(gè)非常小的數(shù)!所以有效數(shù)字M不再加上第一位的1,而是還原為
0.xxxxxx
的小數(shù)。這樣做是為了表示±0,以及接近于0的很小的數(shù)字。
與E為全0一樣,當(dāng)E為全1的時(shí)候,是一個(gè)非常非常大的數(shù)字,再加上正負(fù)號(hào),就類似接進(jìn)于正負(fù)無窮大。所以這時(shí),如果有效數(shù)字M全為0,表示±無窮大(正負(fù)取決于符號(hào)位s)。
知道了浮點(diǎn)數(shù)的存取,我們重新來打量一下這段代碼:
int main(){ int n = 9; //整形理解:00000000 00000000 00000000 00001001 //浮點(diǎn)型理解:0 00000000 0000000000000000001001 float* pFloat = (float*)&n; printf("n的值為:%d/n", n);//9 printf("*pFloat的值為:%f/n", *pFloat);//0 //所以按照上面的浮點(diǎn)型理解,E還要減去127,得出為 //(-1)^0 * 1.001*2^(-126) 接近為 0,所以顯示為0.000000 //默認(rèn)打印小數(shù)點(diǎn)后六位 *pFloat = 9.0; printf("num的值為:%d/n", n); printf("*pFloat的值為:%f/n", *pFloat); return 0;}
而下面那一段也是同樣的道理,按照浮點(diǎn)型存儲(chǔ),9.0應(yīng)該存儲(chǔ)為1001.0
所以為(-1)^0 * 1.001*2^3
,而且E要加上127,然后轉(zhuǎn)化為二進(jìn)制數(shù)列就是
浮點(diǎn)型理解:0 10000010 00100000000000000000000
整形理解:01000001000100000000000000000000
我們可以用計(jì)算機(jī)算一下:
的確和程序運(yùn)行起來一樣的數(shù)字,所以證明上面的說法都是正確的。
好啦,本篇的內(nèi)容就到這里,小白制作不易,有錯(cuò)的地方還請(qǐng)xdm指正,互相關(guān)注,共同進(jìn)步。
還有一件事:
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/119103.html
摘要:基于許可的開源平臺(tái),創(chuàng)始人是的項(xiàng)目架構(gòu)師,它特色是提供了插件,開發(fā)人員可以通過插件直接繪畫出業(yè)務(wù)流程圖。二工作流引擎對(duì)象,這是工作的核心。五總結(jié)工作流的概念就先介紹這么多了,更多的去官網(wǎng)查看,下一節(jié)將用一個(gè)入門的實(shí)例來對(duì)工作流進(jìn)行講解。 文章源碼托管:https://github.com/OUYANGSIHA...歡迎 star !!! 一、activiti介紹 Activiti5是由...
摘要:在位機(jī)器上,如果有個(gè)地址線,那一個(gè)指針變量的大小是個(gè)字節(jié),才能存放一個(gè)地址。就是一個(gè)指針變量,也有自己的類型,指針變量的類型我們可以發(fā)現(xiàn)指針的定義方式是類型星號(hào)。也就是說存儲(chǔ)什么變量類型就用什么指針變量類型。 ...
摘要:代碼修正后修改后,我們可以排列無限個(gè)數(shù)字這樣,一個(gè)冒泡排序就完成了。,數(shù)組名表示整個(gè)數(shù)組。 首先感謝一位博主: 原來45 他寫的博客內(nèi)容十分詳細(xì),為我創(chuàng)造博客提供了莫大的幫助,也為我解決了很多困難。 先貼出2篇他的文章 C語言從入門到入土(入門篇)(數(shù)組p1)_原來45的博客-CSDN博客 ...
摘要:二環(huán)境準(zhǔn)備編譯器選擇這里我們使用進(jìn)行工作流開發(fā),雖然對(duì)于工作流的友好度不是很好,因?yàn)闀?huì)有一些小的,但是,對(duì)于的開發(fā)還是非常的好的。新建后出現(xiàn)下面的編輯頁面到現(xiàn)在,編輯插件就準(zhǔn)備好了。 文章源碼托管:https://github.com/OUYANGSIHA...歡迎 star !!! 一、前言 在上一節(jié)中我們對(duì)activiti進(jìn)行了基本的介紹activiti進(jìn)行了基本的介紹,同時(shí)介紹了...
摘要:文章源碼托管歡迎一前言在上一節(jié)中,通過一個(gè)入門程序,把的環(huán)境準(zhǔn)備好了,這一節(jié),將整合,并且部署一個(gè)最簡(jiǎn)單的流程圖。測(cè)試結(jié)果四總結(jié)這一節(jié)通過整合,繪制簡(jiǎn)單的文件,然后成功部署了文件。 文章源碼托管:https://github.com/OUYANGSIHA...歡迎 star !!! 一、前言 在上一節(jié)中,通過一個(gè)入門程序,把a(bǔ)ctiviti的環(huán)境準(zhǔn)備好了,這一節(jié),將整合spring,并...
閱讀 1378·2021-11-24 09:38
閱讀 2086·2021-09-22 15:17
閱讀 2340·2021-09-04 16:41
閱讀 3450·2019-08-30 15:56
閱讀 3510·2019-08-29 17:19
閱讀 1939·2019-08-28 18:09
閱讀 1248·2019-08-26 13:35
閱讀 1711·2019-08-23 17:52