最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

c語言?數(shù)據(jù)存儲與原碼?反碼?補碼詳細解析

 更新時間:2022年02月10日 16:25:37   作者:誠摯的喬治  
不知道你是否和我一樣好奇,學習編程語言的同時想,各個數(shù)據(jù)類型是怎樣在我們的內(nèi)存中儲存的呢,如果你仔細深入了解的話,你會了解其中的樂趣,了解科學家們的偉大,了解c語言

前言

學習本章你會了解:

1.數(shù)據(jù)類型詳細介紹

2.整形在內(nèi)存中的存儲:以及了解原碼、補碼、反碼

3.大小端字節(jié)序的介紹和判斷

4.浮點型在內(nèi)存中的存儲解析

1.數(shù)據(jù)的類型介紹

在學習數(shù)據(jù)儲存之前,讓我們先認識一下數(shù)據(jù)類型。以下這些數(shù)據(jù)類型是我們初學c語言時的基礎(chǔ)類型以及大小所占字節(jié)數(shù)。

比如所占字節(jié)數(shù)類型
char1//符數(shù)據(jù)的類型
shot2//短整型
int4//整形
long (規(guī)定sizeof(long)>=sizeof(int) )4//長整型
long long(部分編譯器不支持)8//更長的起整數(shù)
float4//單精度浮點數(shù)
double8//雙精度浮點數(shù)

還有構(gòu)造類型:

數(shù)組類型

結(jié)構(gòu)體類型struct

枚舉類型enum

聯(lián)合類型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;
}              //結(jié)果就會打印一個hello world

1.1整形家族

整形家族中包括int short long,還有char。

char也是整形家族中的嗎?

答案是:是的,因為char對應的字符的ascii碼值中,字符對應的就是整形。

在這些整形類型之中,還可以分為無符號整形和有符號整型:

int=signed int

short=signed short

long=signed long

那是否char 等于 signed char呢

結(jié)果又跟其他整形家族中的成員不同,在標準情況下char不是等于sign char~(但是在常規(guī)編譯器中是相等的)。

2.整形在數(shù)據(jù)內(nèi)存中的存儲

我們知道變量創(chuàng)建就是開辟空間,開辟空間的大小由數(shù)據(jù)的類型來決定。

那么數(shù)據(jù)在所在的空間是怎樣儲存的呢?

在vs2019中輸入:

int    a=20;
int    b=-10;

就代表在內(nèi)存中開辟四個字節(jié)的空間

 其中14 00 00 00 就是a十六進制對應反碼的值

和前面相同,f6 ff ff ff就是b十六進制對應反碼的值

我們都知道計算機都是以二進制來存儲信息,那為什么在內(nèi)存圖中看到的是十六進制呢?

這僅僅是便于觀察,當以十六進制儲存時,有沒有感到反碼有點長呢,如果換成二進制就更不宜觀察了,故規(guī)定以十六進制來保存。

提到這里,什么是反碼呢?為什么又反碼的出現(xiàn)呢?

2.1 原碼 反碼和補碼(三種整型數(shù)的表示方法)

原碼:原碼就是數(shù)字對應二進制的表示方法,其中最后一位數(shù)字是符號位,表示正負的,

而小字節(jié)序就是二進制對應的是數(shù)。

如a的原碼是:0000 0000 0000 0000 0000 1010 

反碼:反碼的數(shù)值就是在原碼的基礎(chǔ)之上進行轉(zhuǎn)換過來的,當數(shù)值為正數(shù)時,反碼的數(shù)據(jù)大小跟原碼相同,當數(shù)值是負數(shù)是,其反碼的值就是在原碼的基礎(chǔ)上,除了符號位,其他位都是按位取反。

補碼:補碼數(shù)值為正數(shù)時,其值大小就是原碼,為負時,其值的大小就是在反碼的基礎(chǔ)之上,在進行加一。

原碼得到補碼取反加一即可,其實補碼得到原碼也是取反加一(感興趣的可以試試)

舉個栗子:

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

那我們系統(tǒng)會出現(xiàn)原碼反碼和補碼三種表示方法呢,一種表示方法不行嗎?

我們能想到的,科學家也能想到,但一種表示方法有缺陷。

就比如說:當計算1+(-1)的時候(計算機只能實現(xiàn)加法的運算)

統(tǒng)一用原碼的結(jié)果是

0000 0000 0000 0000  0000 0001

1000 0000 0000 0000 0000  0001

結(jié)果是1000 0000 0000 0000 0000  0010

用補碼計算的結(jié)果是:

0000 0000 0000 0000 0000  0001

0111  1111  1111 1111  1111  1111

結(jié)果是1000 0000 0000 0000 0000 0000 也就是0

你是不是瞬間知道為什么要三種表示方法,為什么有補碼的存在了

有沒有g(shù)et到科學家的偉大之處

2.2大小端字節(jié)序序的介紹

大小端字節(jié)序分別是哪一種?

a在內(nèi)存中的數(shù)值44 33 22 11就是小端字節(jié)序

那大端字節(jié)序就是11 22 33 44

大小端字節(jié)序的定義是什么?

大端字節(jié)序:當一個數(shù)的低字節(jié)序放在高地址處,或者高字節(jié)序的放在低地址處時,就是我們所說的大端字節(jié)序。

小端字節(jié)序:當一個數(shù)的高字節(jié)序放在低地址處,或者低字節(jié)序的放在高地址處時,就是我們所說的小端字節(jié)序。

放在倒著就是小端字節(jié)序,記住它即可。

為什么數(shù)據(jù)要分大小端字節(jié)序呢?

大小端字節(jié)序來源于于喬納森·斯威夫特的小說《格列佛游記》,這是因為在計算機系統(tǒng)中,我們都是以字節(jié)為單位的,每個地址單元都對應著一個字節(jié),一個字節(jié)為8bit,但是在c語言中除了8bit的char之外,還有16bit的short型,32bit的long型(看具體編譯器),另外,對于位數(shù)大于8位的處理器,例外16位的或者32位的處理器,由于寄存器寬度大于一個字節(jié),那么必然存在著一個如何將多個字節(jié)序排序的問題。因此就導致了大端存儲模式,和小端存儲模式。

 那么怎么判斷大小端字節(jié)序呢?

下面由一個例題來講解:(這是百度2015年系統(tǒng)工程師的筆試題)

用代碼來判斷系統(tǒng)大小端字節(jié)序:

int a;
 
char*pa=(char*)&a;
 
if(*pa==1)
 
printf("小端字節(jié)序“);
 
else
 
printf(“大端字節(jié)序”);

2.3 練習

題一:

//輸出結(jié)果是什么
#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
}

輸出的結(jié)果分別是-1 -1 255

前面兩個很容易理解 signed char與char意思都是有符號的整數(shù),所以打印的結(jié)果都是-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(%u\n",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

再轉(zhuǎn)化成十進制:4294967169

運行證明以如下

數(shù)據(jù)的范圍是多少呢?unsigned char與char存放的數(shù)據(jù)是否相等呢?

事實證明char與unsigned char數(shù)據(jù)范圍并不一樣

char的整形數(shù)據(jù)范圍是-128~127,而unsigned char的范圍是0~255;

(short 與unsigned short的整形取值范圍也不一樣

short的整形數(shù)據(jù)范圍是-32768~32767,而unsigned short能存儲的數(shù)據(jù)范圍則是0~65535

3.浮點型在內(nèi)存中的存儲

首先列出一個常見浮點數(shù)表示方法:

1E10 可能你并不知道這是什么意思;

實際上他的意思是1.0*10^10;

3.1 先舉一個例子

#include<stdio.h>
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;
}

n的值為:9

*pFloat的值為:0.00

num的值為:1091567616

*pFloat的值為:9.000000

  這個結(jié)果是否跟你想的一樣呢?

 其實n的值與最后一個*pFloat的值可能我們很容易知道(也可能是猜的 哈哈)

在求解這道題之前讓我們先了解這個題的知識吧~

3.2 浮點數(shù)儲存的規(guī)則

IEEE(電氣和電子工程協(xié)會754標準)標準規(guī)定:

任何二進制的浮點數(shù)都可以以這種標準表示出來:

基本公式是:(-1)^S*M*2^E;(這里的E是無符號類型)

其中M是有效數(shù)子,E是指數(shù),S用來表示正負;

舉個栗子:

5.5——10進制的表示

轉(zhuǎn)化為二進制的結(jié)果是:101.1;

用公式表示為:(-1)^0 (1.011)*2^2    此時S=0,M=1.011,E=2;

 對于64位浮點數(shù),最高位1位是符號位s,接著是11位是指數(shù)E, 剩下的52位是有效數(shù)字。

如果E為八位,他的取值范圍0~255,如果E為11為,他的取值范圍0~2047;

有兩個極限 

當E為0時,此時的真實的E為1-127=-126;此時的數(shù)值根據(jù)公式,也就是無限接近與0;

當E為254時,此時的真實的E為254-127=127;此時的數(shù)值根據(jù)公式,也就是無窮大。

說到這里,你可能有一點疑惑,為什么都要減一個127,這是因為避免出現(xiàn)E為負數(shù)的情況(因為這里的E是無符號整形),在真實的E的基礎(chǔ)上加了127,所以為了得到求出真實的E,就需要減去一個127.

 現(xiàn)在回到原來的題目之上

0000 0000 0000 0000 0000 0000 0000 1001--九的原碼反碼與補碼。

這里的0 是 s;00000000為E;0000000000000000001001為m

此時(-1)^0*0.00000001*10*2^(-126)

由于float默認只打印小數(shù)點后六位,所以最終打印0.000000;

九的轉(zhuǎn)化位二進制: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

結(jié)語:

寫的很長時間,如果有用就收藏吧

到此這篇關(guān)于c語言 數(shù)據(jù)存儲與原碼 反碼 補碼詳細解析的文章就介紹到這了,更多相關(guān)c語言 數(shù)據(jù)存儲內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C語言中g(shù)etchar函數(shù)詳解看這一篇就夠了(函數(shù)功能、使用、返回值)

    C語言中g(shù)etchar函數(shù)詳解看這一篇就夠了(函數(shù)功能、使用、返回值)

    getchar讀取字符的函數(shù),今天通過本文給大家介紹C語言中g(shù)etchar函數(shù)簡介用法示例詳解,感興趣的朋友跟隨小編一起看看吧
    2023-02-02
  • C++名稱空間特性

    C++名稱空間特性

    這篇文章主要介紹了C++名稱空間特性,文章圍繞C++名稱空間特性的相關(guān)資料展開詳細內(nèi)容,需要的小伙伴可以參考一下下文具體內(nèi)容,希望對你的學習有所幫助
    2022-01-01
  • C++開放封閉原則示例解析

    C++開放封閉原則示例解析

    在如那就的設計模式中,不能修改,但可以擴展的實現(xiàn)是一條十分重要的原則,它是開放-封閉原則(The Open-Clossed Principle,簡稱OCP)或開-關(guān)閉原則
    2023-02-02
  • 深入理解二叉樹的非遞歸遍歷

    深入理解二叉樹的非遞歸遍歷

    本篇文章是對二叉樹的非遞歸遍歷進行了詳細的分析介紹,需要的朋友參考下
    2013-05-05
  • C++實現(xiàn)LeetCode(79.詞語搜索)

    C++實現(xiàn)LeetCode(79.詞語搜索)

    這篇文章主要介紹了C++實現(xiàn)LeetCode(79.詞語搜索),本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • 基于Qt編寫全能播放組件的示例代碼

    基于Qt編寫全能播放組件的示例代碼

    這篇文章主要為大家詳細介紹了如何基于Qt編寫全能播放組件,可以支持ffmpeg2/3/4/5/6/Qt4/5/6,感興趣的小伙伴可以跟隨小編一起學習一下
    2023-06-06
  • C語言實現(xiàn)俄羅斯方塊的六種模式詳程建議收藏

    C語言實現(xiàn)俄羅斯方塊的六種模式詳程建議收藏

    遲早一定會掛掉的俄羅斯方塊,為什么至今仍是世界游戲之王?它是怎么編寫的?本文將給大家詳細介紹六種模式的實現(xiàn),對大家的學習或工作具有一定的參考借鑒價值
    2022-02-02
  • 詳解C#byte數(shù)組怎么傳入C

    詳解C#byte數(shù)組怎么傳入C

    在本篇內(nèi)容里小編給大家整理了關(guān)于C#byte數(shù)組怎么傳入C的相關(guān)知識點內(nèi)容,有興趣的朋友們學習參考下。
    2019-03-03
  • c語言如何實現(xiàn)兩數(shù)之和

    c語言如何實現(xiàn)兩數(shù)之和

    這篇文章主要介紹了c語言如何實現(xiàn)兩數(shù)之和,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • c語言之char*和unsigned?char*的區(qū)別及說明

    c語言之char*和unsigned?char*的區(qū)別及說明

    這篇文章主要介紹了c語言之char*和unsigned?char*的區(qū)別及說明,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-08-08

最新評論

永春县| 扎赉特旗| 金溪县| 云安县| 姜堰市| 永德县| 普兰店市| 洮南市| 英山县| 海淀区| 嘉定区| 东山县| 平原县| 武乡县| 龙江县| 昌图县| 吉林省| 图们市| 临武县| 贺兰县| 东乌珠穆沁旗| 晋城| 萝北县| 牡丹江市| 通州市| 光泽县| 佛学| 安远县| 浮梁县| 柘城县| 临澧县| 筠连县| 洞头县| 碌曲县| 拉孜县| 丰城市| 金塔县| 山丹县| 东阳市| 石棉县| 巴林右旗|