<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
學習本章你會了解:
1.資料型別詳細介紹
2.整形在記憶體中的儲存:以及瞭解原碼、二補數、反碼
3.大小端位元組序的介紹和判斷
4.浮點型在記憶體中的儲存解析
在學習資料儲存之前,讓我們先認識一下資料型別。以下這些資料型別是我們初學c語言時的基礎型別以及大小所佔位元組數。
比如 | 所佔位元組數 | 型別 |
char | 1 | //符資料的型別 |
shot | 2 | //短整型 |
int | 4 | //整形 |
long (規定sizeof(long)>=sizeof(int) ) | 4 | //長整型 |
long long(部分編譯器不支援) | 8 | //更長的起整數 |
float | 4 | //單精度浮點數 |
double | 8 | //雙精度浮點數 |
還有構造型別:
陣列型別
結構體型別struct
列舉型別enum
聯合型別union
指標型別:
int* pa;
char* pb;
float* pc;
void* pd;
除了以上型別,實際上還有布林型別:_Bool(專門用來表示真假的型別)
舉個栗子(在c99中可用)
#include<stdio.h> #include<stdbool> main() { _bool flag=true; if(flat) printf("hello world") return 0; } //結果就會列印一個hello world
整形家族中包括int short long,還有char。
char也是整形家族中的嗎?
答案是:是的,因為char對應的字元的ascii碼值中,字元對應的就是整形。
在這些整形型別之中,還可以分為無符號整形和有符號整型:
int=signed int
short=signed short
long=signed long
那是否char 等於 signed char呢
結果又跟其他整形家族中的成員不同,在標準情況下char不是等於sign char~(但是在常規編譯器中是相等的)。
我們知道變數建立就是開闢空間,開闢空間的大小由資料的型別來決定。
那麼資料在所在的空間是怎樣儲存的呢?
在vs2019中輸入:
int a=20; int b=-10;
就代表在記憶體中開闢四個位元組的空間
其中14 00 00 00 就是a十六進位制對應反碼的值
和前面相同,f6 ff ff ff就是b十六進位制對應反碼的值
我們都知道計算機都是以二進位制來儲存資訊,那為什麼在記憶體圖中看到的是十六進位制呢?
這僅僅是便於觀察,當以十六進位制儲存時,有沒有感到反碼有點長呢,如果換成二進位制就更不宜觀察了,故規定以十六進位制來儲存。
提到這裡,什麼是反碼呢?為什麼又反碼的出現呢?
原碼:原碼就是數位對應二進位制的表示方法,其中最後一位數位是符號位,表示正負的,
而小位元組序就是二進位制對應的是數。
如a的原碼是:0000 0000 0000 0000 0000 1010
反碼:反碼的數值就是在原碼的基礎之上進行轉換過來的,當數值為正數時,反碼的資料大小跟原碼相同,當數值是負數是,其反碼的值就是在原碼的基礎上,除了符號位,其他位都是按位元取反。
二補數:二補數數值為正數時,其值大小就是原碼,為負時,其值的大小就是在反碼的基礎之上,在進行加一。
原碼得到二補數取反加一即可,其實二補數得到原碼也是取反加一(感興趣的可以試試)
舉個栗子:
a的原碼 反碼 二補數
原:0000 0000 0000 0000 0001 0100
反:0000 0000 0000 0000 0001 0100
補:0000 0000 0000 0000 0001 0100
b的原碼 反碼 二補數
原:1000 0000 0000 0000 0000 1010
反:1111 1111 1111 1111 1111 0101
補:1111 1111 1111 1111 1111 0110
那我們系統會出現原碼反碼和二補數三種表示方法呢,一種表示方法不行嗎?
我們能想到的,科學家也能想到,但一種表示方法有缺陷。
就比如說:當計算1+(-1)的時候(計算機只能實現加法的運算)
統一用原碼的結果是
0000 0000 0000 0000 0000 0001
1000 0000 0000 0000 0000 0001
結果是1000 0000 0000 0000 0000 0010
用二補數計算的結果是:
0000 0000 0000 0000 0000 0001
0111 1111 1111 1111 1111 1111
結果是1000 0000 0000 0000 0000 0000 也就是0
你是不是瞬間知道為什麼要三種表示方法,為什麼有二補數的存在了
有沒有get到科學家的偉大之處
大小端位元組序分別是哪一種?
a在記憶體中的數值44 33 22 11就是小端位元組序
那大端位元組序就是11 22 33 44
大小端位元組序的定義是什麼?
大端位元組序:當一個數的低位元組序放在高地址處,或者高位元組序的放在低地址處時,就是我們所說的大端位元組序。
小端位元組序:當一個數的高位元組序放在低地址處,或者低位元組序的放在高地址處時,就是我們所說的小端位元組序。
放在倒著就是小端位元組序,記住它即可。
為什麼資料要分大小端位元組序呢?
大小端位元組序來源於於喬納森·斯威夫特的小說《格列佛遊記》,這是因為在計算機系統中,我們都是以位元組為單位的,每個地址單元都對應著一個位元組,一個位元組為8bit,但是在c語言中除了8bit的char之外,還有16bit的short型,32bit的long型(看具體編譯器),另外,對於位數大於8位元的處理器,例外16位元的或者32位元的處理器,由於暫存器寬度大於一個位元組,那麼必然存在著一個如何將多個位元組序排序的問題。因此就導致了大端儲存模式,和小端儲存模式。
那麼怎麼判斷大小端位元組序呢?
下面由一個例題來講解:(這是百度2015年系統工程師的筆試題)
用程式碼來判斷系統大小端位元組序:
int a; char*pa=(char*)&a; if(*pa==1) printf("小端位元組序「); else printf(「大端位元組序」);
題一:
//輸出結果是什麼 #include<stdio.h> 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 -1 255
前面兩個很容易理解 signed char與char意思都是有符號的整數,所以列印的結果都是-1.
都是對於無符號來說這時候就要進行整形提升了
當char型以整形來列印時過程如下:
原碼:10000001
反碼:11111110
二補數:11111111
unsigned整形提升後:0000 0000 0000 0000 1111 1111
這是的二補數同樣也是: 0000 0000 0000 0000 1111 1111
就是最終c的值。
題二:
#include<stdio.h> int main() { char a=-128; printf(%un",a); //u就是以無符號的型別列印出來 return 0; }
-128的原碼: 1000 0000 0000 0000 1000 0000
反碼1111 1111 1111 1111 0111 1111
二補數1111 1111 1111 1111 1000 0000
因為是char型 二補數提取後:10000000
正進行整形提升,因為char是無符號整形,所以提升後:
1111 1111 1111 1111 1000 0000
再以無符號整形形式列印後原反補相同即:1111 1111 1111 1111 1000 0000
再轉化成十進位制:4294967169
執行證明以如下
資料的範圍是多少呢?unsigned char與char存放的資料是否相等呢?
事實證明char與unsigned char資料範圍並不一樣
char的整形資料範圍是-128~127,而unsigned char的範圍是0~255;
(short 與unsigned short的整形取值範圍也不一樣
short的整形資料範圍是-32768~32767,而unsigned short能儲存的資料範圍則是0~65535
首先列出一個常見浮點數表示方法:
1E10 可能你並不知道這是什麼意思;
實際上他的意思是1.0*10^10;
#include<stdio.h> int main() { int n=9; float*pFloat=(float*)&n; printf("n的值為:%dn",n); printf("*pFloat的值為:%fn",pFloat); *pFloat=9.0; printf("num的值為:%dn",n); printf("*pFloat的值為:%fn",*pFloat); return 0; }
n的值為:9
*pFloat的值為:0.00
num的值為:1091567616
*pFloat的值為:9.000000
這個結果是否跟你想的一樣呢?
其實n的值與最後一個*pFloat的值可能我們很容易知道(也可能是猜的 哈哈)
在求解這道題之前讓我們先了解這個題的知識吧~
IEEE(電氣和電子工程協會754標準)標準規定:
任何二進位制的浮點數都可以以這種標準表示出來:
基本公式是:(-1)^S*M*2^E;(這裡的E是無符號型別)
其中M是有效數子,E是指數,S用來表示正負;
舉個栗子:
5.5——10進位制的表示
轉化為二進位制的結果是:101.1;
用公式表示為:(-1)^0 (1.011)*2^2 此時S=0,M=1.011,E=2;
對於64位元浮點數,最高位1位是符號位s,接著是11位是指數E, 剩下的52位是有效數位。
如果E為八位,他的取值範圍0~255,如果E為11為,他的取值範圍0~2047;
有兩個極限
當E為0時,此時的真實的E為1-127=-126;此時的數值根據公式,也就是無限接近與0;
當E為254時,此時的真實的E為254-127=127;此時的數值根據公式,也就是無窮大。
說到這裡,你可能有一點疑惑,為什麼都要減一個127,這是因為避免出現E為負數的情況(因為這裡的E是無符號整形),在真實的E的基礎上加了127,所以為了得到求出真實的E,就需要減去一個127.
現在回到原來的題目之上
0000 0000 0000 0000 0000 0000 0000 1001--九的原碼反碼與二補數。
這裡的0 是 s;00000000為E;0000000000000000001001為m
此時(-1)^0*0.00000001*10*2^(-126)
由於float預設只列印小數點後六位,所以最終列印0.000000;
九的轉化位二進位制:1.001;
1.001*2^3
=0 M=1.001 E=3;
0100 0001 0001 0000 0000 0000 0000 0000
再以整形的形式列印的話,此時的值就是0100 0001 0001 0000 0000 0000 0000 0000就是num的二補數,由於符號位是0,所以最終的原碼等於二補數。也就是1091567616
如果以浮點型列印的話也就是9.000000
結語:
寫的很長時間,如果有用就收藏吧
到此這篇關於c語言 資料儲存與原碼 反碼 二補數詳細解析的文章就介紹到這了,更多相關c語言 資料儲存內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援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