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

C語(yǔ)言深入探究sizeof與整型數(shù)據(jù)存儲(chǔ)及數(shù)據(jù)類(lèi)型取值范圍

 更新時(shí)間:2022年07月07日 09:13:28   作者:龍兆萬(wàn)  
在main函數(shù)中,sizeof是可以正常工作的,但是在自定義函數(shù)中就不可以了。所以本文將為大家詳細(xì)講解一下關(guān)鍵字sizeof、整型數(shù)據(jù)存儲(chǔ)深入、數(shù)據(jù)類(lèi)型取值范圍深入

1.關(guān)鍵字sizeof

sizeof 與 strlen 是我們?nèi)粘4虼a時(shí)經(jīng)常使用到的兩個(gè)“工具”。前者是求變量或者類(lèi)型的大小(單位為字節(jié)),后者是求某一字符串的長(zhǎng)度。我們很容易產(chǎn)生這樣一個(gè)誤解,即把 sizeof 和 strlen 歸為函數(shù)一類(lèi)。事實(shí)上 sizeof 并不是一個(gè)函數(shù),它是一個(gè)操作符、關(guān)鍵字。我們通過(guò)一段代碼證明它不是函數(shù):

#include <stdio.h>
int main()
{
	int n = 20;
	printf("%d\n", sizeof(n));
	printf("%d\n", sizeof(int));
	printf("%d\n", sizeof n);
	return 0;
}

我們注意到紅線部分的 sizeof 后面的變量名沒(méi)有加括號(hào)也能正常運(yùn)行:

這就證明了 sizeof 它不是一個(gè)函數(shù),而是一個(gè)操作符、關(guān)鍵字。

在這里順便復(fù)習(xí)一下關(guān)于數(shù)組的知識(shí),即數(shù)組名的兩個(gè)特例(除了這兩種情況其他任何時(shí)候數(shù)組名都表示數(shù)組首元素地址):

  • sizeof 內(nèi)單獨(dú)放數(shù)組名,其數(shù)組名表整個(gè)數(shù)組。
  • & 數(shù)組名,表取整個(gè)數(shù)組的地址。

由此也可以看出 sizeof 與函數(shù)的區(qū)別。

2.整型數(shù)據(jù)存儲(chǔ)深入

變量的作用是在內(nèi)存中開(kāi)辟一塊空間,而類(lèi)型則決定了這塊空間有多大。

我們可以與 sizeof 結(jié)合起來(lái)驗(yàn)證這個(gè)問(wèn)題:

#include <stdio.h>
int main()
{
	printf("%d\n", sizeof(char));
	printf("%d\n", sizeof(short));
	printf("%d\n", sizeof(int));
	printf("%d\n", sizeof(long));
	printf("%d\n", sizeof(long long));
	return 0;
}

我們知道,計(jì)算機(jī)只能識(shí)別二進(jìn)制,恰恰計(jì)算機(jī)系統(tǒng)又能把我們?nèi)祟?lèi)熟練使用的十進(jìn)制轉(zhuǎn)換成二進(jìn)制,并且產(chǎn)生相應(yīng)的原碼、反碼、補(bǔ)碼。設(shè)計(jì)計(jì)算機(jī)的人設(shè)計(jì)出這樣一套規(guī)則是非常巧妙的。

我們引出原碼、反碼、補(bǔ)碼如何計(jì)算以及他們之間如何轉(zhuǎn)換:

  • 原碼:將數(shù)字直接翻譯成二進(jìn)制得到的序列。
  • 反碼:在原碼的基礎(chǔ)上符號(hào)位(二進(jìn)制序列的最高位,1表負(fù)數(shù),0表負(fù)數(shù))不變,替他位按位取反得到的序列。
  • 補(bǔ)碼:在反碼的基礎(chǔ)上加1。
  • 補(bǔ)碼計(jì)算回原碼方法一:補(bǔ)碼減1,然后符號(hào)位不變,其他位按位取反得到原碼。
  • 補(bǔ)碼計(jì)算回原碼方法二:補(bǔ)碼符號(hào)位不變,其他位按位取反,然后加1。此方法與原碼計(jì)算補(bǔ)碼的方式是一樣的,這樣做的意義在于 CPU 進(jìn)行數(shù)據(jù)處理時(shí),只要設(shè)計(jì)一套計(jì)算方法就可以完成原碼、反碼、補(bǔ)碼之間的相互轉(zhuǎn)換。

那么具體的例子,在數(shù)據(jù)的存儲(chǔ)——整形篇有講到,這里就不贅述。

我們需要明白的是:數(shù)據(jù)存儲(chǔ)到變量當(dāng)中,不會(huì)受到類(lèi)型的影響。什么意思呢?我們舉個(gè)例子:

#include <stdio.h>
int main()
{
	unsigned int p = -10;
	return 0;
}

大家可以看到,我把一個(gè)負(fù)數(shù)存入到無(wú)符號(hào)的整型變量 p 中,這有些違反我們的直覺(jué),無(wú)符號(hào)類(lèi)型不是不存在負(fù)數(shù)的概念嗎?事實(shí)上,不是程序出錯(cuò),而是我們的直覺(jué)有問(wèn)題。

我們?cè)谝婚_(kāi)頭便闡述了變量的作用在內(nèi)存中開(kāi)辟一塊空間,而類(lèi)型便是決定開(kāi)辟多大的空間。就好比說(shuō),我們有 100 ,放在了我的荷包里,那我們能說(shuō)我有 100 塊嗎?就算是錢(qián),我們定義它是美元、港幣、日元了嗎?所以,我們可以把變量看成 100 ,類(lèi)型看成是美元、港幣、日元等等。

到這里,我們就可以清楚,數(shù)據(jù)的存儲(chǔ)與變量的類(lèi)型是沒(méi)有關(guān)系的,變量的作用僅僅是開(kāi)辟一塊空間讓我們的數(shù)據(jù)存儲(chǔ)進(jìn)去。聊到這里,不妨讓我們?cè)倩仡櫼幌?,整型?shù)據(jù)是如何存放在變量(內(nèi)存)里面的。我們就以上面那段代碼為例:

這里再提一嘴:雖然內(nèi)存中存放的是二進(jìn)制序列,但為了我們方便,內(nèi)存還是會(huì)以十六進(jìn)制的表現(xiàn)形式表現(xiàn)出來(lái)。

我們?cè)囂叫酝鶅?nèi)存里面看 p 變量里面存的是什么東西:

可以發(fā)現(xiàn),內(nèi)存里面的各種數(shù)據(jù)都對(duì)上了我們分析的結(jié)果,但是看起來(lái)有點(diǎn)“怪”。我們就來(lái)分析“怪”在哪里:

我們知道 int 類(lèi)型是有 4 個(gè)字節(jié)的,那么數(shù)據(jù)占了 4 個(gè)字節(jié)沒(méi)有問(wèn)題。那么如果是以 1 列的形式查看地址,可以看到從上到下的地址是遞增的。

現(xiàn)在我們以 4 列的形式查看地址,可以看到從左往右地址遞增,從上往下地址遞增。

得出一個(gè)現(xiàn)象:f6 存在了我們的低地址處。

我們似乎可以這樣做推導(dǎo):

這樣的存儲(chǔ)模式我們叫做小端存儲(chǔ)。為什么這樣的模式叫做小端存儲(chǔ)?我們使用這個(gè)案例來(lái)類(lèi)比:

所以我們得出結(jié)論,小端與大端的存儲(chǔ)模式可以定義為:

  • 權(quán)重小的數(shù)位放入內(nèi)存中的低地址處,權(quán)重大的放入內(nèi)存中的高地址處,這樣的存儲(chǔ)模式叫小端存儲(chǔ)。
  • 權(quán)重小的數(shù)位放入內(nèi)存中的高地址處,權(quán)重小的放入內(nèi)存中的低地址處,這樣的存儲(chǔ)模式叫大端存儲(chǔ)。

為什么會(huì)有這種看似復(fù)雜的存儲(chǔ)模式?我們可以舉一個(gè)例子:我們大家都吃過(guò)雞蛋,有些人剝殼喜歡往小的那一頭剝,有的人喜歡往大的那一頭剝,也就是“剝雞蛋”這個(gè)動(dòng)作,沒(méi)有統(tǒng)一的行為概念。硬件制作廠商也不例外,有的廠商想讓數(shù)據(jù)的存儲(chǔ)行為是小端,也有的廠商想讓數(shù)據(jù)以大端的模式進(jìn)行存儲(chǔ),只不過(guò)我們平時(shí)所接觸的硬件,都是以小端模式存儲(chǔ)字節(jié)序的。

我們討論了數(shù)據(jù)的存儲(chǔ),現(xiàn)在我們來(lái)討論一下數(shù)據(jù)的“取出”規(guī)則。

好比說(shuō)我們舉這個(gè)例子:

#include <stdio.h>
int main()
{
	unsigned int p = -10;
	printf("%u\n", p);
	printf("%d\n", p);
	return 0;
}

我們可以看到,對(duì)于 -10 存儲(chǔ)在內(nèi)存當(dāng)中,我們第一次使用 %u 的形式將它從內(nèi)存里拿出來(lái),第二次使用 %d 的形式將它從內(nèi)存中拿出來(lái)。

我們可以看到,對(duì)于不同類(lèi)型的使用方式就會(huì)造成不同的結(jié)果。我們似乎可以這樣斷定:數(shù)據(jù)類(lèi)型不會(huì)影響數(shù)據(jù)的存儲(chǔ),但一定會(huì)影響數(shù)據(jù)的取出(使用)。我們來(lái)分析一下為什么使用不同的類(lèi)型打印能造成不同的結(jié)果:

所以我們?cè)倏偨Y(jié)一次:變量的數(shù)據(jù)類(lèi)型不會(huì)對(duì)數(shù)據(jù)的存儲(chǔ)產(chǎn)生影響(截?cái)嘁膊荒芩愠墒且环N影響),但數(shù)據(jù)類(lèi)型一定會(huì)影響數(shù)據(jù)的取出、使用。

3.數(shù)據(jù)類(lèi)型取值范圍深入

什么叫數(shù)據(jù)類(lèi)型的取值范圍?好比說(shuō)我們有這樣一個(gè)例子:

那么我們?nèi)?C 語(yǔ)言中大小最小的數(shù)據(jù)類(lèi)型 char 來(lái)討論數(shù)據(jù)類(lèi)型的取值范圍。

我們知道,char 類(lèi)型只有 1 個(gè)字節(jié),它有 8 個(gè)比特位。無(wú)符號(hào)類(lèi)型的 char 我們就不做討論,我們重點(diǎn)討論無(wú)符號(hào)類(lèi)型的 char 。那么 8 個(gè)比特位,能有多少種排列組合?能從什么值取到什么值?

那么通過(guò)演繹推理,得出來(lái)排列組合得個(gè)數(shù),有什么意義呢?可以確定八個(gè)比特位能存放多少個(gè)數(shù)字。例如兩個(gè)比特位能存放 4 個(gè)數(shù)字,三個(gè)比特位能存放 8 個(gè)數(shù)字,八個(gè)比特位能存放 256 個(gè)數(shù)字。

現(xiàn)在我們的重點(diǎn)在于:char 類(lèi)型的八個(gè)比特位,能存哪 256 個(gè)數(shù)字?

可以看到這個(gè)結(jié)果,取值范圍似乎是 [-127,127] ,但是這個(gè)區(qū)間里面只有 255 個(gè)數(shù),那我們理論推導(dǎo)出來(lái)的結(jié)果是 256 個(gè)數(shù),是我們推導(dǎo)錯(cuò)了嗎?其實(shí)不然,我們應(yīng)該注意 1000 0000 后面的那個(gè)問(wèn)號(hào):如果這串二進(jìn)制序列真表示 0 了,那么就有兩個(gè) 0 了,但是在計(jì)算機(jī)在考慮取值范圍的時(shí)候,是不會(huì)浪費(fèi)任何一個(gè)比特位來(lái)存放相同的數(shù)字的。

那么既然沖突了,就要在兩個(gè)邊界任意一端擴(kuò)充。那么是 128 還是 -128 呢?只能是 -128 。在這里,我們就已經(jīng)踏入計(jì)算機(jī)的知識(shí)邊界了,為什么只能是 -128 它是個(gè)數(shù)學(xué)問(wèn)題,就好比為什么會(huì)設(shè)計(jì)出原碼、反碼、補(bǔ)碼一樣,我們是無(wú)法理解設(shè)計(jì)計(jì)算機(jī)的人為什么會(huì)這樣設(shè)計(jì)的。所以在這里只需記住,char 類(lèi)型的取值范圍是 [-2^7,2^7-1] 。那么我們類(lèi)比出來(lái) short 類(lèi)型的取值范圍是 [-2^15,2^15-1] , int 類(lèi)型的取值范圍是 [-2^31,2^31-1] ……

我們來(lái)看一個(gè)非常經(jīng)典的例題:

#include <stdio.h>
#include <string.h>
int main()
{
	char arr[1000];
	for (int i = 0; i < 1000; i++)
	{
		arr[i] = -1 - i;
	}
	printf("%d\n", strlen(arr));
	return 0;
}

那么這道題要我們輸出 arr 數(shù)組的長(zhǎng)度是什么意思呢?我們?cè)俸煤孟胂?strlen 。strlen 是求字符串長(zhǎng)度,我們模擬實(shí)現(xiàn)過(guò) strlen 的工作機(jī)制,知道遇到 '\0' 時(shí)就停止,返回 '\0' 之前的字符長(zhǎng)度。那么 '\0' 就是數(shù)學(xué)意義上的 0 。其 '\' 是轉(zhuǎn)義字符,如果僅僅寫(xiě) '0' 的話,那么這個(gè) '0' 并非數(shù)學(xué)意義上的 0 ,而是一個(gè)字符 0 。

好的,那我們知道這段代碼會(huì)循環(huán) 1000 次對(duì)數(shù)組賦值。實(shí)際上我們的輸出的要求是:輸出 '\0' 出現(xiàn)之前的字符長(zhǎng)度。我們可以這么運(yùn)算:

我們通過(guò)計(jì)算,可以計(jì)算出當(dāng)數(shù)組下標(biāo)為 255 時(shí),元素存儲(chǔ)的是 0 ,即代表存儲(chǔ)的是 '\0' ,那么 strlen 碰到 '\0' 時(shí)就會(huì)停止。那么數(shù)組下標(biāo)為 255 ,那數(shù)組下標(biāo) 0~255 有 256 個(gè)元素,舍棄一個(gè) '\0' ,即剩下 255 個(gè)有效字符。所以最后輸出 255 。

到此這篇關(guān)于C語(yǔ)言深入探究sizeof與整型數(shù)據(jù)存儲(chǔ)及數(shù)據(jù)類(lèi)型取值范圍的文章就介紹到這了,更多相關(guān)C語(yǔ)言sizeof內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C語(yǔ)言深入探究水仙花數(shù)與變種水仙花數(shù)代碼

    C語(yǔ)言深入探究水仙花數(shù)與變種水仙花數(shù)代碼

    求水仙花數(shù)和變種水仙花數(shù)是非常適合初學(xué)者學(xué)習(xí)的代碼,其中包含的循環(huán)和邏輯方式等知識(shí)點(diǎn)。這既能起到對(duì)以往知識(shí)的復(fù)習(xí),也可以學(xué)習(xí)到一種不同的邏輯思考方式
    2022-05-05
  • 通過(guò)“回文字算法”復(fù)習(xí)C++語(yǔ)言

    通過(guò)“回文字算法”復(fù)習(xí)C++語(yǔ)言

    這篇文章主要介紹了通過(guò)“回文字算法”復(fù)習(xí)C++語(yǔ)言的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-10-10
  • Linux網(wǎng)絡(luò)編程之socket文件傳輸示例

    Linux網(wǎng)絡(luò)編程之socket文件傳輸示例

    這篇文章主要介紹了Linux網(wǎng)絡(luò)編程之socket文件傳輸示例,對(duì)于基于Linux平臺(tái)的C程序員來(lái)說(shuō)有一定的借鑒價(jià)值,需要的朋友可以參考下
    2014-08-08
  • C++ Eigen庫(kù)計(jì)算矩陣特征值及特征向量

    C++ Eigen庫(kù)計(jì)算矩陣特征值及特征向量

    這篇文章主要為大家詳細(xì)介紹了C++ Eigen庫(kù)計(jì)算矩陣特征值及特征向量,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-06-06
  • C語(yǔ)言與C++中關(guān)于字符串使用的比較

    C語(yǔ)言與C++中關(guān)于字符串使用的比較

    字符串是我們?cè)偈煜げ贿^(guò)的東西了,任何語(yǔ)言中字符串都是基礎(chǔ)都要經(jīng)常用到,那么在不同語(yǔ)言中字符串的用法一樣嗎?下面我們來(lái)看看C語(yǔ)言與C++中字符串使用的比較
    2022-05-05
  • C語(yǔ)言結(jié)構(gòu)體內(nèi)存對(duì)齊問(wèn)題小結(jié)

    C語(yǔ)言結(jié)構(gòu)體內(nèi)存對(duì)齊問(wèn)題小結(jié)

    本文主要講解了C語(yǔ)言中結(jié)構(gòu)體的內(nèi)存對(duì)齊規(guī)則、計(jì)算方法以及影響因素,包括對(duì)齊規(guī)則的四個(gè)要點(diǎn)、內(nèi)存對(duì)齊的原因、如何修改默認(rèn)對(duì)齊數(shù)以及結(jié)構(gòu)體傳參時(shí)的注意事項(xiàng),此外,還介紹了結(jié)構(gòu)體位段的概念、內(nèi)存分配和使用注意事項(xiàng),感興趣的朋友一起看看吧
    2025-02-02
  • C語(yǔ)言實(shí)現(xiàn)的排列組合問(wèn)題的通用算法、解決方法

    C語(yǔ)言實(shí)現(xiàn)的排列組合問(wèn)題的通用算法、解決方法

    這篇文章主要介紹了C語(yǔ)言實(shí)現(xiàn)的排列組合問(wèn)題的通用算法、解決方法,本文使用C語(yǔ)言實(shí)現(xiàn)在程序中解決這個(gè)問(wèn)題,需要的朋友可以參考下
    2014-08-08
  • 一篇文章帶你了解C語(yǔ)言浮點(diǎn)數(shù)之間的比較規(guī)則

    一篇文章帶你了解C語(yǔ)言浮點(diǎn)數(shù)之間的比較規(guī)則

    這篇文章主要介紹了魔性的float浮點(diǎn)數(shù)精度問(wèn)題,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-08-08
  • opengl繪制五星紅旗

    opengl繪制五星紅旗

    這篇文章主要為大家詳細(xì)介紹了opengl繪制五星紅旗的方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-09-09
  • C語(yǔ)言實(shí)現(xiàn)學(xué)生信息管理系統(tǒng)(文件操作)

    C語(yǔ)言實(shí)現(xiàn)學(xué)生信息管理系統(tǒng)(文件操作)

    這篇文章主要介紹了C語(yǔ)言實(shí)現(xiàn)學(xué)生信息管理系統(tǒng),增加了文件操作,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-06-06

最新評(píng)論

都安| 浦县| 长沙县| 松潘县| 商洛市| 商南县| 藁城市| 洛浦县| 湟中县| 珠海市| 宜宾县| 仙桃市| 井冈山市| 宁都县| 德保县| 泾川县| 岚皋县| 上栗县| 思南县| 黄陵县| 鄱阳县| 柳江县| 招远市| 天峻县| 琼海市| 兴安县| 祁门县| 博罗县| 峡江县| 商都县| 石嘴山市| 聊城市| 舞阳县| 龙江县| 邢台市| 东莞市| 通河县| 建始县| 五指山市| 黔西县| 西平县|