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

C語言深入探究sizeof與整型數據存儲及數據類型取值范圍

 更新時間:2022年07月07日 09:13:28   作者:龍兆萬  
在main函數中,sizeof是可以正常工作的,但是在自定義函數中就不可以了。所以本文將為大家詳細講解一下關鍵字sizeof、整型數據存儲深入、數據類型取值范圍深入

1.關鍵字sizeof

sizeof 與 strlen 是我們日常打代碼時經常使用到的兩個“工具”。前者是求變量或者類型的大小(單位為字節(jié)),后者是求某一字符串的長度。我們很容易產生這樣一個誤解,即把 sizeof 和 strlen 歸為函數一類。事實上 sizeof 并不是一個函數,它是一個操作符、關鍵字。我們通過一段代碼證明它不是函數:

#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 后面的變量名沒有加括號也能正常運行:

這就證明了 sizeof 它不是一個函數,而是一個操作符、關鍵字。

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

  • sizeof 內單獨放數組名,其數組名表整個數組。
  • & 數組名,表取整個數組的地址。

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

2.整型數據存儲深入

變量的作用是在內存中開辟一塊空間,而類型則決定了這塊空間有多大。

我們可以與 sizeof 結合起來驗證這個問題:

#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;
}

我們知道,計算機只能識別二進制,恰恰計算機系統(tǒng)又能把我們人類熟練使用的十進制轉換成二進制,并且產生相應的原碼、反碼、補碼。設計計算機的人設計出這樣一套規(guī)則是非常巧妙的。

我們引出原碼、反碼、補碼如何計算以及他們之間如何轉換:

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

那么具體的例子,在數據的存儲——整形篇有講到,這里就不贅述。

我們需要明白的是:數據存儲到變量當中,不會受到類型的影響。什么意思呢?我們舉個例子:

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

大家可以看到,我把一個負數存入到無符號的整型變量 p 中,這有些違反我們的直覺,無符號類型不是不存在負數的概念嗎?事實上,不是程序出錯,而是我們的直覺有問題。

我們在一開頭便闡述了變量的作用在內存中開辟一塊空間,而類型便是決定開辟多大的空間。就好比說,我們有 100 ,放在了我的荷包里,那我們能說我有 100 塊嗎?就算是錢,我們定義它是美元、港幣、日元了嗎?所以,我們可以把變量看成 100 ,類型看成是美元、港幣、日元等等。

到這里,我們就可以清楚,數據的存儲與變量的類型是沒有關系的,變量的作用僅僅是開辟一塊空間讓我們的數據存儲進去。聊到這里,不妨讓我們再回顧一下,整型數據是如何存放在變量(內存)里面的。我們就以上面那段代碼為例:

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

我們試探性往內存里面看 p 變量里面存的是什么東西:

可以發(fā)現(xiàn),內存里面的各種數據都對上了我們分析的結果,但是看起來有點“怪”。我們就來分析“怪”在哪里:

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

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

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

我們似乎可以這樣做推導:

這樣的存儲模式我們叫做小端存儲。為什么這樣的模式叫做小端存儲?我們使用這個案例來類比:

所以我們得出結論,小端與大端的存儲模式可以定義為:

  • 權重小的數位放入內存中的低地址處,權重大的放入內存中的高地址處,這樣的存儲模式叫小端存儲。
  • 權重小的數位放入內存中的高地址處,權重小的放入內存中的低地址處,這樣的存儲模式叫大端存儲。

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

我們討論了數據的存儲,現(xiàn)在我們來討論一下數據的“取出”規(guī)則。

好比說我們舉這個例子:

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

我們可以看到,對于 -10 存儲在內存當中,我們第一次使用 %u 的形式將它從內存里拿出來,第二次使用 %d 的形式將它從內存中拿出來。

我們可以看到,對于不同類型的使用方式就會造成不同的結果。我們似乎可以這樣斷定:數據類型不會影響數據的存儲,但一定會影響數據的取出(使用)。我們來分析一下為什么使用不同的類型打印能造成不同的結果:

所以我們再總結一次:變量的數據類型不會對數據的存儲產生影響(截斷也不能算成是一種影響),但數據類型一定會影響數據的取出、使用。

3.數據類型取值范圍深入

什么叫數據類型的取值范圍?好比說我們有這樣一個例子:

那么我們取 C 語言中大小最小的數據類型 char 來討論數據類型的取值范圍。

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

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

現(xiàn)在我們的重點在于:char 類型的八個比特位,能存哪 256 個數字?

可以看到這個結果,取值范圍似乎是 [-127,127] ,但是這個區(qū)間里面只有 255 個數,那我們理論推導出來的結果是 256 個數,是我們推導錯了嗎?其實不然,我們應該注意 1000 0000 后面的那個問號:如果這串二進制序列真表示 0 了,那么就有兩個 0 了,但是在計算機在考慮取值范圍的時候,是不會浪費任何一個比特位來存放相同的數字的。

那么既然沖突了,就要在兩個邊界任意一端擴充。那么是 128 還是 -128 呢?只能是 -128 。在這里,我們就已經踏入計算機的知識邊界了,為什么只能是 -128 它是個數學問題,就好比為什么會設計出原碼、反碼、補碼一樣,我們是無法理解設計計算機的人為什么會這樣設計的。所以在這里只需記住,char 類型的取值范圍是 [-2^7,2^7-1] 。那么我們類比出來 short 類型的取值范圍是 [-2^15,2^15-1] , int 類型的取值范圍是 [-2^31,2^31-1] ……

我們來看一個非常經典的例題:

#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 數組的長度是什么意思呢?我們再好好想想 strlen 。strlen 是求字符串長度,我們模擬實現(xiàn)過 strlen 的工作機制,知道遇到 '\0' 時就停止,返回 '\0' 之前的字符長度。那么 '\0' 就是數學意義上的 0 。其 '\' 是轉義字符,如果僅僅寫 '0' 的話,那么這個 '0' 并非數學意義上的 0 ,而是一個字符 0 。

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

我們通過計算,可以計算出當數組下標為 255 時,元素存儲的是 0 ,即代表存儲的是 '\0' ,那么 strlen 碰到 '\0' 時就會停止。那么數組下標為 255 ,那數組下標 0~255 有 256 個元素,舍棄一個 '\0' ,即剩下 255 個有效字符。所以最后輸出 255 。

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

相關文章

  • C語言深入探究水仙花數與變種水仙花數代碼

    C語言深入探究水仙花數與變種水仙花數代碼

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

    通過“回文字算法”復習C++語言

    這篇文章主要介紹了通過“回文字算法”復習C++語言的相關資料,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2016-10-10
  • Linux網絡編程之socket文件傳輸示例

    Linux網絡編程之socket文件傳輸示例

    這篇文章主要介紹了Linux網絡編程之socket文件傳輸示例,對于基于Linux平臺的C程序員來說有一定的借鑒價值,需要的朋友可以參考下
    2014-08-08
  • C++ Eigen庫計算矩陣特征值及特征向量

    C++ Eigen庫計算矩陣特征值及特征向量

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

    C語言與C++中關于字符串使用的比較

    字符串是我們再熟悉不過的東西了,任何語言中字符串都是基礎都要經常用到,那么在不同語言中字符串的用法一樣嗎?下面我們來看看C語言與C++中字符串使用的比較
    2022-05-05
  • C語言結構體內存對齊問題小結

    C語言結構體內存對齊問題小結

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

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

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

    一篇文章帶你了解C語言浮點數之間的比較規(guī)則

    這篇文章主要介紹了魔性的float浮點數精度問題,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-08-08
  • opengl繪制五星紅旗

    opengl繪制五星紅旗

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

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

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

最新評論

班戈县| 阿瓦提县| 左贡县| 漯河市| 邹平县| 岱山县| 桦甸市| 明水县| 基隆市| 漾濞| 平武县| 周口市| 怀集县| 寿宁县| 尼勒克县| 江城| 舞阳县| 讷河市| 剑川县| 呼玛县| 阳朔县| 卢氏县| 博湖县| 龙海市| 云龙县| 新河县| 武城县| 鹿泉市| 靖安县| 雅安市| 门源| 凌云县| 泾源县| 黄浦区| 新安县| 潞西市| 海晏县| 云浮市| 伊宁市| 深州市| 盘锦市|