C語(yǔ)言——整型相關(guān)
數(shù)據(jù)儲(chǔ)存的基本概念


類型關(guān)鍵字與字節(jié)大小
#include <stdio.h>
int main()
{
? ?signed int iValue = 9;
? ?unsigned int uiValue = 9u;
? ?long int lValue = 9l;
? ?unsigned long int ulValue = 95ul;
? ?long long int llValue = 95ll;
? ?unsigned long long int ullValue = 95ull;
? ?short int sValue = 9;
? ?unsigned short int usValue = 9u;
? ?unsigned char ucValue = 48u;
? ?
? ?//結(jié)果是 4 4 4
? ?printf("signed int 的字節(jié)數(shù)為 : %d %d %d\n",sizeof(int),sizeof(iValue),sizeof(9));
? ?
? ?//結(jié)果是 4 4 4
? ?printf("unsigned int 的字節(jié)數(shù)為 : %d %d %d\n",sizeof(unsigned int),sizeof(uiValue),sizeof(9u));
? ?
? ?//結(jié)果是 4 4 4
? ?printf("long int 的字節(jié)數(shù)為 : %d %d %d\n",sizeof(long int),sizeof(lValue),sizeof(9l));
? ?
? ?//結(jié)果是 4 4 4
? ?printf("unsigned long int 的字節(jié)數(shù)為 : %d %d %d\n",sizeof(unsigned long int), sizeof(ulValue),sizeof(95ul));
? ?
? ?//結(jié)果為 8 8 8
? ?printf("long long int 的字節(jié)數(shù)為 : %d %d %d\n",sizeof(long long int),sizeof(llValue),sizeof(95ll));
? ?
? ?//結(jié)果為 8 8 8
? ?printf("unsigned long long int 的字節(jié)數(shù)為 : %d %d %d\n",sizeof(unsigned long long int), sizeof(ullValue),sizeof(95ull));
? ?
? ?//結(jié)果為 2 2 4 ,沒(méi)有 s 這個(gè)后綴,所以 9 最小需要 4 字節(jié)的存儲(chǔ)空間
? ?printf("short int 的字節(jié)數(shù)為 : %d %d %d\n",sizeof(short int),sizeof(sValue),sizeof(9));
? ?
? ?//結(jié)果為 2 2 4
? ?printf("unsigned short int 的字節(jié)數(shù)為 : %d %d %d\n",sizeof(unsigned short int), sizeof(usValue),sizeof(9u));
? ?
? ?return 0;
}
sizof() 不是函數(shù),而是長(zhǎng)度運(yùn)算符。括號(hào)里可以填 數(shù)據(jù)類型、變量、常量。
整型常量無(wú)后綴時(shí),默認(rèn)是 int 類型的存儲(chǔ)方式。
在常數(shù)后加上不同的后綴,計(jì)算機(jī)在存儲(chǔ)時(shí)使用的空間大小也不一樣。
字面值及前后綴
字面值:即常量,指在程序中無(wú)需變量保存,可直接表示為一個(gè)具體的數(shù)字或字符串的值。
前綴:0x 或 0X 表示十六進(jìn)制,0 表示八進(jìn)制, 不帶前綴則默認(rèn)表示十進(jìn)制。
后綴:整數(shù)常量也可以帶一個(gè)后綴,后綴是 u 和 l 的組合,u 表示無(wú)符號(hào)整數(shù)(unsigned),l 表示長(zhǎng)整數(shù)(long)。后綴可以是大寫(xiě),也可以是小寫(xiě),u 和 l 的順序任意,但是后綴不可以重復(fù)。
進(jìn)制轉(zhuǎn)換
十進(jìn)制轉(zhuǎn)二進(jìn)制
整數(shù)部分:除 2 取余
小數(shù)部分:乘 2 取整
順序是離小數(shù)點(diǎn)越來(lái)越遠(yuǎn)。
存儲(chǔ)原理
原碼、反碼、補(bǔ)碼的轉(zhuǎn)換規(guī)則:
對(duì)于正數(shù):原碼 = 反碼 = 補(bǔ)碼
對(duì)于負(fù)數(shù):原碼符號(hào)位不變,其余位取反后變?yōu)榉创a。反碼再加 1 變?yōu)檠a(bǔ)碼。(1000 0000 的補(bǔ)碼還是 1000 0000)
計(jì)算機(jī)內(nèi)部是沒(méi)有減法計(jì)算的,只有加法計(jì)算:

溢出現(xiàn)象
int i = -1; i 在內(nèi)存中以補(bǔ)碼形式存放為 ff ff ff ff (這個(gè)補(bǔ)碼對(duì)于 signed 和 unsigned 來(lái)說(shuō)有什么不同呢?對(duì)于有符號(hào)整型來(lái)說(shuō) ff ff ff ff 表示 -1,而對(duì)于無(wú)符號(hào)整型來(lái)說(shuō),ff ff ff ff 表示該類型最大的數(shù))。(unsigned int a = -1; 這個(gè)操作是什么意思?合法嗎?是合法的,變量 a 首先在棧區(qū)被創(chuàng)建,而 -1 是被存儲(chǔ)在常數(shù)區(qū),代碼中所有出現(xiàn)的常數(shù)都會(huì)被保存在常數(shù)區(qū),-1 是一個(gè)負(fù)數(shù),在常數(shù)區(qū)中以補(bǔ)碼形式存儲(chǔ)為 ff ff ff ff,a 在內(nèi)存中的值不是 -1,而是 4294967295)

總結(jié):當(dāng)給一個(gè)整型變量存上 -1 的時(shí)候,系統(tǒng)會(huì)現(xiàn)在常量區(qū)創(chuàng)建 -1,然后系統(tǒng)會(huì)在棧區(qū)給變量分配一塊空間,最后將常數(shù)區(qū)的補(bǔ)碼復(fù)制一份給棧區(qū)的變量。這個(gè)過(guò)程就是賦值。
unsigned char c = -1;
unsigned short b = -1;
unsigned int a = -1;
unsigned long long d = -1;
//a 在內(nèi)存中為 ff ff ff ff,%d 表示以有符號(hào)形式打印,這時(shí)候補(bǔ)碼第一位就會(huì)被當(dāng)成符號(hào)位,結(jié)果為 -1;而 %u 表示以有符號(hào)形式打印,補(bǔ)碼第一位就不會(huì)被當(dāng)成符號(hào)位了,結(jié)果為 4294967295
printf("%d\n",a);
//結(jié)果為 4294967295 2147483647 -2147483648,這就是溢出現(xiàn)象
printf("%u %d %d\n",a,a/2,a/2+1);
//結(jié)果為 255 127 -128
printf("%u %d %d\n",c,c/2,c/2+1);
以上代碼中變量 c 為例來(lái)解釋一下溢出現(xiàn)象:變量 c 在內(nèi)存中以補(bǔ)碼形式存儲(chǔ)為 1111 1111,以 %u 的形式打印為 255。c/2 后變?yōu)?0111 1111,以 %d 的形式打印為 127。c/2-1 后變?yōu)?1000 0000,以 %d 的形式打印為 -128。

左值與右值
C/C++語(yǔ)言中可以放在賦值符號(hào)左邊的是變量,即具有對(duì)應(yīng)的可以由用戶訪問(wèn)的存儲(chǔ)單元,并且能夠由用戶去改變其值的量。
左值表示存儲(chǔ)在計(jì)算機(jī)內(nèi)存的對(duì)象,而不是常量或計(jì)算的結(jié)果?;蛘哒f(shuō)左值是代表一個(gè)內(nèi)存地址值,并且通過(guò)這個(gè)內(nèi)存地址,就可以對(duì)內(nèi)存進(jìn)行讀并且寫(xiě)(主要是能寫(xiě))操作;這也就是為什么左值可以被賦值的原因了。
相對(duì)應(yīng)的還有右值:當(dāng)一個(gè)符號(hào)或者常量放在操作符右邊的時(shí)候,計(jì)算機(jī)就讀取他們的“右值”,也就是其代表的真實(shí)值。簡(jiǎn)單來(lái)說(shuō)就是,左值相當(dāng)于地址值,右值相當(dāng)于數(shù)據(jù)值。右值指的是引用了一個(gè)存儲(chǔ)在某個(gè)內(nèi)存地址里的數(shù)據(jù)。
//下面的代碼是錯(cuò)誤的,因?yàn)?8 和 9 都存儲(chǔ)在變量區(qū),不可以修改
8 = 9;