C語言關鍵字淺析-long
### C語言關鍵字淺析系列 ###
### ISO/ANSI C 關鍵字 ###
long,顧名思義是“長”的意思
在C語言中long關鍵字常見於宣告長整型變數,主要特徵就是其佔用記憶體的長度不會比int短(注意是大於等於關係,後面有解釋)
而且在C99標準中還添加了long long這樣的型別,相比較int其一個優勢就是能表示更大的資料區間
long的作用是:
宣告長整型變數。
1、長整型變數的宣告
相對於普通的int整型,長整型和短整型被稱之為“其他整數型別”,但它們宣告變數的方式是差不多的:
int number; /* int整型 */ long int longNumber; /* 長整型 */ long longNumber2; /* 長整型的另一種宣告方式 */ unsigned long uLongNumber; /* 宣告為無符號的長整型 */ long long max; /* 很長的整數型別 */
2、能表示的範圍
這裡的舉例按照Windows XP或者Macintosh PowerPC的配置,即認為int和long都是32位,long long是64位來計算:
int(4byte = 32bit):-2147483648 ~ 2147483647
unsigned int(4byte = 32bit):0 ~ 4294967295
long(4byte = 32bit):-2147483648 ~ 2147483647
unsigned long(4byte = 32bit):0 ~ 4294967295
long long(8byte = 64bit):-9223372036854775808 ~ 9223372036854775807
unsigned long long(8byte = 64bit):0 ~ 18446744073709551615
(注1:-2147483648 ~ 2147483647也是C語言標準規定的long型別的最小取值範圍)
(注2:目前比較常規的情況是,long long佔64位,long佔32位,short短整型佔16位,int佔位根據機器的自然字大小而定16/32)
3、整數溢位
由上面我們知道,計算機內用整數型別表示的資料是有取值範圍限制的,那如果存在程式計算過程中超出表示範圍的情況呢?
這種情況在計算機科學裡常稱之為“溢位”,即計算結果超出了資料型別的表示範圍,不能正確表示理論上的正確值
int max = INT_MAX; /* max是int型別能表示的最大值 */
unsigned umax = UINT_MAX; /* umax是unsigned int能表示的最大值 */
printf("%d, %d, %d\n", max, max + 1, max + 2);
/*
結果為:2147483647, -2147483648, -2147483647
*/
printf("%d, %d, %d\n", umax, umax + 1, umax + 2);
/*
結果為:4294967295, 0, 1
*/
通過觀察你也能發現,其實整數溢位的處理形式和某些計重器類似,指標轉了一圈後如果不夠表示指標還會繼續轉圈
當然C語言不同於那種會在內環再標記轉了兩圈後應該是多重的秤,C語言的整數走完“一圈”,或者說溢位後,只會從頭開始
而從頭開始的值基本取決於是有符號型別或者說無符號型別
4、long常量和long long常量
現在你見到int MONTHS = 12;就會知道,我們把MONTHS這個整型變數賦值為12
但你是否有想過,我們為什麼能這樣做,C是怎樣看待表示式中12這個部分的呢?
其實在顯式對整型變數賦值時,這個數字在C語言中被稱為整數常量
而且對於12、1024這樣的單純數字,C會預設為其是int型別,除非1000000這樣的超出了int表示範圍的數
那1000000這樣的情況會怎樣呢?其實C編譯器遇到這種情況發現int不夠了,就會用long int型別去嘗試,再不行就unsigned long再嘗試
往後會依次用long long,unsigned long long型別去嘗試(前提是機器支援這些型別)
當然我們也可以顯式地告訴編譯器把一個數值不大的常量用long或者long long等型別儲存:
/* 在支援long long型別的機器中 */
int a = 10; /* int型別常量10 */
long int b = 10L; /* long型別常量10 */
long long c = 10LL; /* long long型別常量10 */
long d = 021L; /* long型別的八進位制數021 */
long long e = 0x23LL; /* long long型別的十六進位制數0x23 */
unsigned long long f = 14LLU; /* unsigned long long型別常量14 */
unsigned long long g = 5ull; /* unsigned long long的第二種字尾 */
5、long的輸入輸出
如果你瞭解int的輸入輸出,那麼long和long long等型別的輸入輸出則是大同小異的,需要注意的就是長整型本身的幾個說明符:
long int i;
scanf("%ld", &i); /* %ld是long型別的說明符 */
printf("%lo, %lx", m, n); /* %lo和%lx分別是long型別八進位制和十六進位制 */
printf("%lu", p); /* %lu是unsigned long型別 */
printf("%lld, %llu", m, n); /* %lld是long long型別,%llu是unsigned long long型別 */
此處非常要注意的是,一定要注意變數是有符號型別輸入輸出還是無符號型別輸入輸出
如果你對同一個unsigned型別的變數用%u和%d輸出,得到的結果可能是完全不一樣的,顯然%d大概率輸出的是錯誤結果
因為計算機的儲存中,一個無符號數和一個有符號數在記憶體中的表示可能是相同的,其根本區別就在於是否把某一位看做符號位
——參考《C Primer Plus第五版》
相關文章:
C語言關鍵字淺析-short
C語言關鍵字淺析-unsigned