C語(yǔ)言數(shù)據(jù)類型與sizeof關(guān)鍵字
一、前言
大家好,歡迎來(lái)到C語(yǔ)言深度解析專欄—C語(yǔ)言關(guān)鍵字詳解第三篇,在本篇中我們將會(huì)介紹C語(yǔ)言當(dāng)中的數(shù)據(jù)類型,并由此引出C語(yǔ)言當(dāng)中的另外一個(gè)重要的關(guān)鍵字 — sizeof .
第一篇:C語(yǔ)言 auto和register關(guān)鍵字
第二篇:全面了解C語(yǔ)言 static 關(guān)鍵字
二、數(shù)據(jù)類型
1、數(shù)據(jù)類型有哪些
C語(yǔ)言的數(shù)據(jù)類型包括基本類型(內(nèi)置類型)、構(gòu)造類型(自定義類型)、指針類型以及空類型
2、為什么要有數(shù)據(jù)類型
為什么要有內(nèi)置類型
我們?nèi)粘I钪袝?huì)遇到各種各樣的場(chǎng)景,而不同的場(chǎng)景需要不同數(shù)據(jù)來(lái)表示,比如我們聚餐的人數(shù)、天氣的溫度、海拔的高度等事情通常用整數(shù)來(lái)描述,而像人的身高、廣播的頻率、商品的價(jià)格則通常用小數(shù)表示,又比如我們的車牌號(hào)、樓棟的命名、服裝的尺碼則需要要用字母來(lái)表示;C語(yǔ)言作為第一門高級(jí)程序設(shè)計(jì)語(yǔ)言,為了能準(zhǔn)確描述我們生活中各種各樣的場(chǎng)景,就有了整形、浮點(diǎn)型、字符型這些內(nèi)置類型。
為什么要有自定義類型
我們以自定義類型中的數(shù)組類型和結(jié)構(gòu)體類型舉例:
數(shù)組類型:我們生活中會(huì)碰到許多相同類型的集合,比如一個(gè)學(xué)校學(xué)生的學(xué)號(hào),每一個(gè)學(xué)生的學(xué)號(hào)都是整形,那么為了表示所有學(xué)生的學(xué)號(hào),就勢(shì)必要定義幾千個(gè)整形,顯然,那樣太麻煩了,于是就產(chǎn)生了數(shù)組類型,一個(gè)數(shù)組里面的每個(gè)元素的類型都是相同的,我們?cè)诙x一個(gè)學(xué)校學(xué)生的學(xué)號(hào)時(shí),只需要定義一個(gè)有幾千個(gè)元素大小的數(shù)組即可,而不必去慢慢定義一千個(gè)整形
結(jié)構(gòu)體類型:我們生活中所要描述的對(duì)象常常是復(fù)雜數(shù)據(jù)類型的集合,拿人來(lái)說(shuō),一個(gè)人有姓名、性別、身高、體重、年齡等等,這些數(shù)據(jù)類型都是不同的,那么為了能夠系統(tǒng)的描述一個(gè)人的屬性,就產(chǎn)生了結(jié)構(gòu)體類型,它把一個(gè)人不同類型的數(shù)據(jù)都集中到一個(gè)新的類型當(dāng)中,使對(duì)象描述和使用更加方便。
3、如何看待數(shù)據(jù)類型
從前面的博客中我們知道,定義變量的本質(zhì)是在內(nèi)存中開(kāi)辟一塊空間,用來(lái)存放數(shù)據(jù),而今天我們知道不同的變量是需要定義為不同的類型的,把二者結(jié)合起來(lái),我們就不難得出:類型決定的是變量開(kāi)辟空間的大小。
這時(shí)有兩個(gè)疑問(wèn)點(diǎn),第一、為什么要根據(jù)類型來(lái)開(kāi)辟空間,我們直接開(kāi)辟一塊空間,將內(nèi)存整體使用不好嗎?答案是:不好。
原因主要有兩點(diǎn):
1、在任何時(shí)刻,你的電腦都不是只在運(yùn)行你目前所使用的那個(gè)程序,還有其他許多的程序也在同時(shí)運(yùn)行,如果把整塊都分配給了你目前運(yùn)行的程序,其他程序就崩潰了。
2、即使把整塊內(nèi)存都分配給你,你也不能保證在任何時(shí)刻都對(duì)該內(nèi)存塊全部都用完,這樣就會(huì)導(dǎo)致內(nèi)存的浪費(fèi)。
第二、我們使用部分內(nèi)存,使用多少由什么決定的?答案是:是由你的場(chǎng)景決定,你的計(jì)算場(chǎng)景,決定了你使用什么類型的變量進(jìn)行計(jì)算。你所使用的類型,決定了你開(kāi)辟多少字節(jié)的空間大小。這也是為什么C語(yǔ)言要有這么多的數(shù)據(jù)類型,就是為了滿足不同的計(jì)算場(chǎng)景。
最后,那么不同的數(shù)據(jù)類型到底在內(nèi)存開(kāi)辟多少空間呢?這就需要使用我們的關(guān)鍵字 – sizeof 來(lái)計(jì)算了。
三、sizeof – 計(jì)算不同類型變量開(kāi)辟空間的大小
1、內(nèi)置類型開(kāi)辟的空間大小
`#include<stdio.h> int main() { ?? ?printf("%d\n", sizeof(char)); ? ? ? //1 ?? ?printf("%d\n", sizeof(short)); ? ? ?//2 ?? ?printf("%d\n", sizeof(int)); ? ? ? ?//4 ?? ?printf("%d\n", sizeof(long)); ? ? ? //4 ?? ?printf("%d\n", sizeof(long long)); ?//8 ?? ?printf("%d\n", sizeof(float)); ? ? ?//4 ?? ?printf("%d\n", sizeof(double)); ? ? //8 }`
2、自定義類型開(kāi)辟的空間大小
數(shù)組大小
#include<stdio.h> int main() { ?? ?int arr1[10] = { 0 }; ? ? ? //40 ?? ?char arr2[10] = { 0 }; ? ? ?//10 ?? ?long int arr3[10] = { 0 }; ?//40 ?? ?long long arr4[10] = { 0 }; //80 ?? ?float arr5[10] = { 0 }; ? ? //40 ?? ?double arr6[10] = { 0 }; ? ?//80 ?? ?printf("%d\n", sizeof(arr1)); ?? ?printf("%d\n", sizeof(arr2)); ?? ?printf("%d\n", sizeof(arr3)); ?? ?printf("%d\n", sizeof(arr4)); ?? ?printf("%d\n", sizeof(arr5)); ?? ?printf("%d\n", sizeof(arr6)); ?? ?return 0; }
從上面的結(jié)果我們很容易得出:數(shù)組的大小 = 數(shù)組元素的類型乘以元素個(gè)數(shù)
其他自定義類型的大小
#include<stdio.h> struct Test1{ ?? ?int a; ?? ?char b; ?? ?float c; ?? ?double d; }; union Test2{ ?? ?int m; ?? ?char n; }; enum Test3 { ?? ?monday, ?? ?tuesday, ?? ?wednesday, ?? ?thursday, ?? ?frifay }; int main() { ?? ?struct Test1 test1 = { 0 }; ?? ?union Test2 test2 = { 0 }; ?? ?enum Test3 test3; ?? ?printf("%d\n", sizeof(test1)); ? //24 ?? ?printf("%d\n", sizeof(test2)); ? //4 ?? ?printf("%d\n", sizeof(test3)); ? //4 }
想必上面的結(jié)果與一些小伙伴心中的結(jié)果有所不同,確實(shí),結(jié)構(gòu)體、聯(lián)合體、枚舉這些自定義類型的大小和數(shù)組大小的求法是不相同的,其具體的求法涉及內(nèi)存對(duì)齊、大小端、內(nèi)存分配等相關(guān)知識(shí),這些知識(shí)比較復(fù)雜,我會(huì)放在自定義類型詳解模塊中為大家講解,現(xiàn)在大家不用去深究。
3、指針類型開(kāi)辟的空間大小
大家可以看到,我們上面不管指針的類型是什么(整形、字符型、浮點(diǎn)型、數(shù)組型),指針的大小始終是四個(gè)字節(jié)或者八個(gè)字節(jié)(第一張圖X86表示32位平臺(tái),結(jié)果為4,第二張圖X64表示64位平臺(tái),結(jié)果為8),所以結(jié)論就是:指針在32位平臺(tái)下是4個(gè)字節(jié),在64位平臺(tái)下是8個(gè)字節(jié)。(至于為什么是這樣,這涉及到內(nèi)存編址、地址線等相關(guān)知識(shí),這一部分我會(huì)放在指針那里來(lái)詳細(xì)講解,現(xiàn)在大家只需要記住這個(gè)結(jié)論即可)
注:第二張圖有警告是因?yàn)槲业碾娔X是32位平臺(tái)的,強(qiáng)制轉(zhuǎn)成64位會(huì)發(fā)生大小不匹配的問(wèn)題。
4、空類型開(kāi)辟的空間大小
我們可以看到雖然這里編譯器報(bào)錯(cuò)了,但它仍然打印出來(lái)了void的大小:0個(gè)字節(jié)
注:void類型的大小為0個(gè)字節(jié),這僅僅是在visual studio這個(gè)編譯器下運(yùn)行的結(jié)果,但是,這個(gè)結(jié)果在不同的編環(huán)境下跑出來(lái)可能不同,就比如在Linux環(huán)境下,void類型的大小就為1,(由于水平的限制,這里暫時(shí)不能為大家演示);而導(dǎo)致這兩者之間有差異的根本原因是不同編譯環(huán)境對(duì)C語(yǔ)言的支持程度不同。
四、對(duì)sizeof 的進(jìn)一步理解
1、sizeof 為什么不是函數(shù)
從上面我們可以看到,我們可以用 sizeof(a) 和 sizeof(int) 求一個(gè)整形的大小,這種方式也是大家所熟悉的,但是我們發(fā)現(xiàn)直接用
sizeof a 也能求出a的大小,而不需要圓括號(hào),所以說(shuō),sizeof 是關(guān)鍵字(操作符)但是不是函數(shù),因?yàn)楹瘮?shù)參數(shù)需要用 () 起來(lái)才能正常使用。
注:sizeof int 報(bào)錯(cuò)是因?yàn)?sizeof 和 int 都是關(guān)鍵字,而不能用一個(gè)關(guān)鍵字去求另一個(gè)關(guān)鍵字的大小
2、sizeof 的其他使用
這里我們定義了一個(gè)整型變量 a 和 指針變量 p ,以及數(shù)組 arr,可以看到 a 的大小為 4,arr 的大小為40,這些我們都理解,
那么剩下的sizeof § 、sizeof(&arr) 、sizeof(arr) / sizeof(arr[0]) 是什么意思呢?下面為大家解釋(涉及指針相關(guān)知識(shí))
p 是一個(gè)指針變量,里面存放的是 a 的地址,arr數(shù)組名表示arr數(shù)組首元素的地址(記憶),&arr 表示取出整個(gè)數(shù)組的地址,相當(dāng)于一個(gè)數(shù)組指針,所以sizeof§ 和 sizeof(&arr) 都是求的指針的大小,而在上面我們知道,指針在32位平臺(tái)下是4個(gè)字節(jié),所以這里結(jié)果為4。
最后,sizeof(arr) 求整個(gè)數(shù)組的大小,sizeof(arr[0]) 求第一個(gè)元素的大小,所以二者相除得到的是數(shù)組的元素個(gè)數(shù)10。
注:這里用sizeof(arr[0]) 來(lái)求一個(gè)數(shù)組元素的大小,而不是用arr[1] 、arr[2] 是因?yàn)槲覀儾恢罃?shù)組有幾個(gè)元素,所以可能arr[1] 、arr[2] 根本不存在,但是只要定義了數(shù)組,那么arr[0] 就是一定是存在的,也就是說(shuō),這樣做是為了安全。
到此這篇關(guān)于C語(yǔ)言數(shù)據(jù)類型與sizeof關(guān)鍵字的文章就介紹到這了,更多相關(guān)C語(yǔ)言 sizeof關(guān)鍵字內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Qt利用QDrag實(shí)現(xiàn)拖拽拼圖功能詳解
QDrag類為MIME-based拖拽數(shù)據(jù)轉(zhuǎn)換提供支持。本文為大家主要介紹如何利用QDrag類實(shí)現(xiàn)拖拽拼圖功能。左邊是打散的圖,拖動(dòng)到右邊進(jìn)行復(fù)現(xiàn),此外程序還支持手動(dòng)拖入原圖片,感興趣的可以了解一下2022-07-07C語(yǔ)言動(dòng)態(tài)內(nèi)存管理深入探討
動(dòng)態(tài)內(nèi)存是相對(duì)靜態(tài)內(nèi)存而言的。所謂動(dòng)態(tài)和靜態(tài)就是指內(nèi)存的分配方式。動(dòng)態(tài)內(nèi)存是指在堆上分配的內(nèi)存,而靜態(tài)內(nèi)存是指在棧上分配的內(nèi)存,本文帶你深入探究C語(yǔ)言中動(dòng)態(tài)內(nèi)存的管理2022-06-06C++統(tǒng)計(jì)軟件使用時(shí)間代碼示例
這篇文章主要介紹了C++統(tǒng)計(jì)軟件使用時(shí)間的小程序,大家可以參考使用2013-11-11C++17 使用 std::string_view避免字符串拷貝優(yōu)化程序性能
這篇文章主要介紹了C++17 使用 std::string_view避免字符串拷貝優(yōu)化程序性能,幫助大家提高程序運(yùn)行速度,感興趣的朋友可以了解下2020-10-10C語(yǔ)言菜鳥(niǎo)基礎(chǔ)教程之a(chǎn)++與++a
很多同學(xué)在學(xué)習(xí)c語(yǔ)言的時(shí)候是不是會(huì)碰到a++和++a都有甚么作用啊。今天我們就來(lái)探討下2017-10-10C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)二叉樹(shù)先序、中序、后序及層次四種遍歷
這篇文章主要介紹了C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)二叉樹(shù)先序、中序、后序及層次四種遍歷方式,具有一定的知識(shí)性參考價(jià)值,需要的小伙伴可以先看一下2022-02-02C++中實(shí)現(xiàn)線程安全和延遲執(zhí)行詳解
這篇文章主要為大家詳細(xì)介紹了C++中實(shí)現(xiàn)線程安全和延遲執(zhí)行的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,需要的小伙伴可以了解下2024-01-01