<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
1.基本內建型別:byte,int ,char, float, double
2.構造資料型別:
陣列型別;
結構體型別:struct
共用體(聯合型別):union
列舉型別:enum
3.指標型別 :int* p,char* p,float* p,void* p
4.空型別 : void(無型別),通常用於函數的返回型別,函數引數與指標型別。
構造型別又叫自定義型別,在各自引數或者元素型別發生變化就會讓他徹頭徹尾的改變;而基本資料型別的特點就是不可以再分解為其他型別,基本型別就是自我說明,關於他們的作用就不一一贅述了。
那首先要在偵錯欄開啟記憶體視窗,並搞清楚怎麼觀察記憶體,這是必要的工具
這些密密麻麻的就是記憶體中的資料,看到這裡你可能就會疑惑,不是說記憶體裡存的都是二進位制數嗎,這些是什麼鬼?是的,沒有錯,但是記憶體視窗展示內容有限,在有限的範圍內,他只能選擇以 16 進位制的形式展示出來,僅僅是展示而已。
這個更是人不人鬼不鬼的其實是他根據記憶體的資料簡單的以文字的格式輸出其可能的內容,無價值簡直就是意義不明。
不論我們在寫程式碼時建立了個什麼東西,他不會居於虛空,存在載體就會佔用記憶體,而空間的大小是根據我們建立的資料的型別而決定的,我們要回到問題最本質的源頭,在開闢的記憶體中到底如何去儲存資料?我們不廢話直接建立倆個變數看看便知
int main() { int a = 5; int b = -5; return 0; }
記憶體視窗開啟我們可以取地址查詢 a,b 的資料儲存情況:
這裡是不是感覺很奇怪,二者為何差異這麼大?要搞清楚我們就要繼續深入研究。
說整數的二進位制有三種表示方法:原碼,反碼,二補數。
整數分為正數和負數,正負數的區別就在於他們二進位制32位元數的最高位的 0和1代表著符號位,0為正,1為負,其餘才是有效位。
正數的原反補三碼合一,和他本身是一樣的。但是負數就花哨了,負數原碼是按照一個數的正,負直接寫出來的二進位制就是原碼。反碼在原碼基礎上,除開符號位進行取反得到。這裡強調一下,之前講過一個操作符:~(按位元取反操作符),區別一下他倆,按位元取反操作符是針對二進位制數每一位全部都取反,包括符號位。二補數則是反碼的基礎上+1得到,比如 -7 這個數的原反補分別為:
10000000 00000000 00000000 00000111 (原)
111111111 111111111 111111111 111111000(反)
111111111 111111111 111111111 111111001(補)
b 的 -5 就是 00000000 00000000 00000000 00000101以二補數 11111111 11111111 11111111 11111011 每四個位元組為一位化成16 進位制就是 0xfffffff3。
既然記憶體中中儲存的是二進位制的二補數,我們現在不談現象談本質,為什麼偏偏要是二補數呢?
我們要明白一件事就是計算機算減法是相對不容易的,因為CPU裡面沒有減法器,只有加法器,要算 1-1 時只能算作 1+(-1)。計算機用二進位制去計算時,我們會發現,當用原碼或者反碼去計算根本行不通,只有二補數才可以實現。
由此看來,二補數的地位是絕對的老大哥,在計算機系統中,數值一律用二補數來儲存,主要原因是:
1.統一了零的編碼
2.將符號位和其它位統一處理
3.將減法運算轉變為加法運算
4.兩個用二補數表示的數相加時,如果最高位(符號位)有進位,則進位被捨棄
由這裡看,加法和減法可以統一起來處理,此外二補數和原碼相互轉換時,其運算過程是相同的,不需要額外的硬體電路。
之前的部落格專門講了大小端儲存模式專題,其實大小端的檢驗也可以用今天的知識來解決:
# include<stdio.h> int check_s() { int i = 1; return (*(char*)&i); } int main() { int ret = 0; ret = check_s(); if (ret == 1) { printf("小端n"); } else { printf("大端n"); } return 0;
其結果:
int main() { char a = -1; signed char b = -1; unsigned char c = -1; printf("a = %d,b=%d,c=%d",a,b,c); return 0; }
上面這個程式碼乍一看就是三個-1,仔細看就會發現char型別後面陰差陽錯跟個 -1,-1是整數啊,這時是不是感覺有一絲凌亂?-1的原碼為1000(30個0)1,取反+1得到二補數111……111(32個1),而 char 只能放 8 個位元位,就意味著會發生截斷,,a = 11111111,而我們在vs環境裡面 signed char和char是一樣的,我們不妨看看執行結果如何:
為什麼c會是 255呢?首先要明白為什麼b 會是 -1,我們 signed char b在截斷後,如果要 以%d形式進行列印,就會發生整型提升,有符號數的最高位會被認為是符號位,而整型提升時會以整型的原符號位進行提升,因為是負數就會全部補成1,再按照二補數轉原碼倒回去會發現結果就是 char a= -1。
同理,c 是無符號數,但也會發生整型提升,無符號數提升通通補 0 ,按照%d 列印時,記憶體就會認為這是一個有符號數,最高位又會被預設為符號位,最後轉換成原碼,就會得到 255。
接著上面的思路再來看看這個程式碼:
# include<stdio.h> # include<windows.h> int main() { unsigned int a ; for(a=9;i>=0;i--) { printf("%u ",i); Sleep(1000); return 0; } }
這個程式碼也是一個眼見不為實的程式碼,表面上是列印9個數,實則實在無限的死迴圈,你發現了嗎?聰明的你如果看到 判斷條件 i>=0 這個條件,就可能發現端倪,十有八九會死迴圈,因為不管什麼情況都會恆成立。我們來看看執行效果:
當我0進入後很自然的變成了-1,而-1會放到無符號整型,二補數是32位元全1,而作為無符號整型,最高位不再是符號位,所有位都是有效位,轉化為原碼是一個巨大的數位,由於滿足迴圈判斷條件於是開始歡樂死迴圈。我們可以根據這些範例總結出相應的經驗。
浮點數相對於整型,他的儲存機制會更復雜。
浮點數包括float和double,甚至long double,浮點數的表示範圍在 float.h中定義。
int main() { int n = 9; float* pFloat = (float*)&n; printf("n=%d",n); printf("*pFloat=%fn",*pFloat); *pFloat = 9.0; printf("n=%dn",n); printf("*pFloat=%fn",*pFloat); return 0; }
對上面這個程式碼,我一開始的覺得列印的是:9,9, 9.0, 9.0,後來發現是我格局小了。
如上結果我們就能明顯看出浮點數和整型儲存是不一樣的。
國際標準IEEE(電氣和電子工程協會)754標準,任意一個二進位制浮點數V都可以表示成下面的形式:
V=(-1)^S * M * 2^E
1. (-1)^s 表示符號位,s為0表示正,s為1表示負
2. M 表示有效數位,大於等於1,小於2
3. 2^E 表示指數位
對於32位元浮點數,最高符號位s,接著 8位元是指數E,剩下23位為有效數位M;而64位元浮點數,11位是指數 E,剩下的 52 位有效數位M。
這裡的M和E還有特殊的規定
IEEE 754規定,在計算機內部儲存M時,預設這個數的第1位總是1,因此可以被捨去,只儲存後面的小數部分。例如儲存1.01的時候,只儲存01,等到讀取的時候,再把第一位的1加上去。這樣做的目的,是節省1位有效數位。以32位元浮點數為例,留給M只有23位,將第一位的1捨去以後,等於可以儲存24位元有效數位。
我們會把指數位看作是無符號整數,取值在0到255,如果是11位的E,取值在0到2047,但是眾所周知,科學記數法裡面E是可以出現負數的,所以還有規定就是E在存入時會先修飾一波,給真實值加上一個中間值,對於 8位元與11位的E,這個中間數是127和1023,比如 2 的十次方,E就是10,儲存成32位元浮點數時,必須變成10+127=137,即10001001。E在全0和全1的情況下代表著接近於0的無窮小和無窮大。
我們回到最開始的問題,9的原反補三碼合一00000000 00000000 00000000 00001001,E為全0時其真實值是-126,除去S與E,小數部分M為0000……01001,而%f只能列印後6位,這就是為什麼列印0.000000。接著pFloat為9.0浮點數進入,對應的二進位制為1001.0,科學記數法1.0012^3,S=0,E=3,M=1.001,存入後變成 0 10000010 0010000000000000000000,(S E M),為了方便我們換成16進位制計算出是 0x41100000,我以%f取出就是他自己這沒什麼解釋的,困惑的可能是%d的結果,以%d列印就預設為有符號數,變成二補數轉換出來就是 1091567616。
今天就到這裡吧,摸了家人們,更多關於C語言進階資料的儲存的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45