文章目錄🚀write in front🚀
📝個(gè)人主頁(yè):認(rèn)真寫博客的夏目淺石.
🎁歡迎各位→點(diǎn)贊👍 + 收藏?? + 留言📝
📣系列專欄:凡人修C傳
💬總結(jié):希望你看完之后,能對(duì)你有所幫助,不足請(qǐng)指正!共同學(xué)習(xí)交流 🖊
??如果無(wú)聊的話,就來(lái)逛逛我的博客棧吧stack-frame.cn
好久沒(méi)更新了,主要最近事情很多,非常忙,直到今天才給大家更新出來(lái)第一篇博客—深度刨析數(shù)據(jù)在內(nèi)存中的存儲(chǔ)
??本節(jié)學(xué)習(xí)的重點(diǎn):
之前的學(xué)習(xí)過(guò)程當(dāng)中我們認(rèn)識(shí)了許多的數(shù)據(jù)類型以及他們所占存儲(chǔ)空間的大小,例如:
char //字符數(shù)據(jù)類型 1個(gè)字節(jié)
short //短整型 2個(gè)字節(jié)
int //整形 4個(gè)字節(jié)
long //長(zhǎng)整型 4個(gè)字節(jié)
long long //更長(zhǎng)的整形 8個(gè)字節(jié)
float //單精度浮點(diǎn)數(shù)
double //雙精度浮點(diǎn)數(shù)
類型的意義:
整形家族:
char
unsigned char
signed char
short
unsigned short [int]
signed short [int]
int
unsigned int
signed int
long
unsigned long [int]
signed long [int]
浮點(diǎn)數(shù)家族:
float
double
構(gòu)造類型:
>數(shù)組類型
>結(jié)構(gòu)體類型 struct
>枚舉類型 enum
>聯(lián)合類型 union
指針類型:
int *pi;
char *pc;
float* pf;
void* pv;
空類型:
void
二、整形在內(nèi)存中的存儲(chǔ)通常應(yīng)用于函數(shù)的返回類型、函數(shù)的參數(shù)、指針類型。
我們之前講過(guò)一個(gè)變量的創(chuàng)建是要在內(nèi)存中開(kāi)辟空間的
??臻g的大小是根據(jù)不同的類型
而決定的。
所以數(shù)據(jù)到底是怎么存儲(chǔ)的呢?
所以就給大家介紹一下數(shù)據(jù)的存儲(chǔ)
計(jì)算機(jī)中的整數(shù)有三種2進(jìn)制表示方法,即原碼、反碼和補(bǔ)碼。
三種表示方法均有符號(hào)位和數(shù)值位兩部分,符號(hào)位都是用0表示“正”
,用1表示“負(fù)”
,而數(shù)值位
正數(shù)的原、反、補(bǔ)碼都相同
負(fù)整數(shù)的三種表示方法各不相同
原碼
直接將數(shù)值按照正負(fù)數(shù)的形式翻譯成二進(jìn)制就可以得到原碼。
反碼
將原碼的符號(hào)位不變,其他位依次按位取反就可以得到反碼。
補(bǔ)碼
反碼+1就得到補(bǔ)碼。
對(duì)于整形來(lái)說(shuō):數(shù)據(jù)存放內(nèi)存中其實(shí)存放的是補(bǔ)碼。
對(duì)于這段代碼進(jìn)行分析:
#includeint main()
{int a = 20;
int b = -10;
return 0;
}
根據(jù)vs2019的調(diào)試
發(fā)現(xiàn):a在內(nèi)存中的存儲(chǔ)是:14 00 00 00
?????? ??發(fā)現(xiàn):b在內(nèi)存中的存儲(chǔ)是: f6 ff ff ff
我們可以看到對(duì)于a和b分別存儲(chǔ)的是補(bǔ)碼。但是我們發(fā)現(xiàn)順序有點(diǎn)不對(duì)勁。
這是又為什么?
下面就介紹大小端的知識(shí)點(diǎn)。
什么大端小端:
大端(存儲(chǔ))模式,是指數(shù)據(jù)的低位保存在內(nèi)存的高地址中,而數(shù)據(jù)的高位,保存在內(nèi)存的低地址中;
小端(存儲(chǔ))模式,是指數(shù)據(jù)的低位保存在內(nèi)存的低地址中,而數(shù)據(jù)的高位,,保存在內(nèi)存的高地址中。
下面設(shè)計(jì)一些程序來(lái)實(shí)現(xiàn)大小端的判斷:
思路:
設(shè)計(jì)方案一:
#includeint main()
{int a=1;
//分析:00000000000000000000000000000001 - 正數(shù)的原,反,補(bǔ)是一樣的
//寫成16進(jìn)制數(shù)字---小端存儲(chǔ):0x 01 00 00 00
//寫成16進(jìn)制數(shù)字---大端存儲(chǔ):0x 00 00 00 01
//所以:判斷機(jī)器是大端存儲(chǔ)還是小端存儲(chǔ),只需要看第一個(gè)數(shù)字是1還是0.
char *p=(char *)&a;
if(*p==1)
{printf("小端存儲(chǔ)\n");
}
else printf("大端存儲(chǔ)\n");
return 0;
}
圖示:
設(shè)計(jì)方案二:
#includeint check()
{int i=1;
return (*(char *)&i);
}
int main()
{ int ret=check();
if(ret==1) printf("小端存儲(chǔ)\n");
else printf("大端存儲(chǔ)\n");
return 0;
}
圖示:
練習(xí)1.
1.
//輸出什么?
#includeint main()
{char a= -1;
signed char b=-1;
unsigned char c=-1;
printf("a=%d,b=%d,c=%d",a,b,c);
return 0;
}
下面就是我的分析:
首先看到了char a=-1;
所以就是:
1.先寫出-1的原,反,補(bǔ)
1000000000000000000000000000001 - 原碼
1111111111111111111111111111110 - 反碼
1111111111111111111111111111111 - 補(bǔ)碼
2.放到了char 的類型當(dāng)中,所以不難想到要進(jìn)行截?cái)嗖僮? 11111111 - a
3.發(fā)現(xiàn)a是以%d的形式進(jìn)行打印的:
所以對(duì)a進(jìn)行整形提升:
對(duì)于整形提升我又有一些知識(shí)想講:
-1.對(duì)于有符號(hào)數(shù)是補(bǔ)符號(hào)位.
-2.對(duì)于無(wú)符號(hào)數(shù)是補(bǔ)0.
4.所以:1111111111111111111111111111111 - a - 補(bǔ)碼
所以printf 為-1;
同理:b也一樣-1
對(duì)于c的分析:
10000000000000000000000000000001 - -1的原碼
11111111111111111111111111111110 - -1的反碼
11111111111111111111111111111111 - -1的補(bǔ)碼
00000000000000000000000011111111 - 截?cái)嗪蟀凑諢o(wú)符號(hào)數(shù)
進(jìn)行整形提升
所以打印就是255
練習(xí)2.
2.
#includeint main()
{char a = -128;
printf("%u\n",a);
return 0;
}
下面就是我的分析:
10000000000000000000000010000000
11111111111111111111111101111111 -128的反碼
11111111111111111111111110000000 -128的補(bǔ)碼
10000000 - a --截?cái)?
11111111111111111111111110000000 -整形提升
答案:4294967168
第三題:
3.
#includeint main()
{char a = 128;
printf("%u\n",a);
return 0;
}
下面就是我的分析:
答案與上一個(gè)題目一模一樣。
第四道題:
4.
#includeint main()
{int i= -20;
unsigned int j = 10;
printf("%d\n", i+j);
return 0;
}
下面就是我的分析:
第五道題:
5.
unsigned int i;
for(i = 9; i >= 0; i--)
{printf("%u\n",i);
}
下面就是我的分析:
無(wú)符號(hào)數(shù)一定大于等于0.
第六道題目:
6.
int main()
{char a[1000];
int i;
for(i=0; i<1000; i++)
{a[i] = -1-i;
}
printf("%d",strlen(a));
return 0;
}
下面就是我的分析:
第七道題:
7.
#includeunsigned char i = 0;
int main()
{for(i = 0;i<=255;i++)
{printf("hello world\n");
}
return 0;
}
下面就是我的分析:
四、 浮點(diǎn)型在內(nèi)存中的存儲(chǔ) 4.1 浮點(diǎn)數(shù)存儲(chǔ)規(guī)則unsigned char 類型的范圍是0~255所以就是死循環(huán)打印。
根據(jù)國(guó)際標(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ù)位。
這里我認(rèn)為大家可以把浮點(diǎn)數(shù)的存儲(chǔ)作為一個(gè)了解即可,其實(shí)目前用處并沒(méi)有整形用處大
總結(jié)??寫到這里,深度剖析數(shù)據(jù)在內(nèi)存中的存儲(chǔ)
算是講完了,但是奈不住我講的不好或者同學(xué)們沒(méi)聽(tīng)懂,我的建議是給我提意見(jiàn)或者仔細(xì)多看幾遍,這樣才能學(xué)明白數(shù)據(jù)的內(nèi)存存儲(chǔ)。
??我是夏目淺石,希望和你一起學(xué)習(xí)進(jìn)步,刷題無(wú)數(shù)?。?!希望各位大佬
能一鍵三連支持一下博主
,hhhh~我們下期見(jiàn)嘍
如果無(wú)聊的話,就來(lái)逛逛我的博客棧吧stack-frame.cn
? 原創(chuàng)不易,還希望各位大佬支持一下 \textcolor{blue}{原創(chuàng)不易,還希望各位大佬支持一下} 原創(chuàng)不易,還希望各位大佬支持一下
👍 點(diǎn)贊,你的認(rèn)可是我創(chuàng)作的動(dòng)力! \textcolor{9c81c1}{點(diǎn)贊,你的認(rèn)可是我創(chuàng)作的動(dòng)力!} 點(diǎn)贊,你的認(rèn)可是我創(chuàng)作的動(dòng)力!
?? 收藏,你的青睞是我努力的方向! \textcolor{ed7976}{收藏,你的青睞是我努力的方向!} 收藏,你的青睞是我努力的方向!
?? 評(píng)論,你的意見(jiàn)是我進(jìn)步的財(cái)富! \textcolor{98c091}{評(píng)論,你的意見(jiàn)是我進(jìn)步的財(cái)富!} 評(píng)論,你的意見(jiàn)是我進(jìn)步的財(cái)富!
你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級(jí)服務(wù)器適合批量采購(gòu),新人活動(dòng)首月15元起,快前往官網(wǎng)查看詳情吧