1. 程式人生 > >C語言中的整數(short,int,long)

C語言中的整數(short,int,long)

整數是程式設計中常用的一種資料,C語言中有三種整數型別,分別為 short、int 和 long。int 稱為整型,short 稱為短整型,long 稱為長整型,它們的長度(所佔位元組數)關係為:

short <= int <= long

它們具體佔用幾個位元組C語言並沒有規定,C語言只做了寬泛的限制:
  • short 至少佔用2個位元組。
  • int 建議為一個機器字長。32位環境下機器字長為4位元組,64位環境下機器字長為8位元組。
  • short 的長度不能大於 int,long 的長度不能小於 int。

這就意味著,short 並不一定真的”短“,long 也並不一定真的”長“,它們有可能和 int 佔用相同的位元組數。
決定整數長度的因素很多,包括硬體(CPU和資料匯流排)、作業系統、編譯器等。

在16位環境下,short 為2個位元組,int 為2個位元組,long 為4個位元組。16位環境多用於微控制器和低階嵌入式系統,在PC和伺服器上基本都看不到了。

對於32位的 Windows、Linux 和 OS X,short 為2個位元組,int 為4個位元組,long 也為4個位元組。PC和伺服器上的32位系統佔有率也在慢慢下降,嵌入式系統使用32位越來越多。

在64位環境下,不同的作業系統會有不同的結果,如下所示(長度以位元組計):
作業系統 short int long
Win64 2 4 4
類Unix系統(包括 Unix、Linux、OS X、BSD、Solaris 等) 2 4 8

目前我們使用較多的PC系統為 Win XP、Win 7、Win 8、Win 10、Mac OS X、Linux,short 和 int 的長度都是固定的,分別為2和4,大家可以放心使用,long 的長度在 Win64 和類Unix系統下會有所不同,使用時要注意移植性。

獲取某個資料型別的長度可以使用 sizeof 操作符,如下所示:
  1. #include <stdio.h>
  2. int main()
  3. {
  4. short a = 10;
  5. int b = 100;
  6. long c = 1000;
  7. char d = 'X';
  8. int a_length = sizeof a;
  9. int b_length = sizeof(int);
  10. printf("a=%d, b=%d, c=%d, d=%d\n", a_length, b_length, sizeof(c), sizeof(char));
  11. return 0;
  12. }
在Win7下的執行結果為:
a=2, b=4, c=4, d=1

sizeof 用來獲取某個資料型別或變數所佔用的位元組數,如果後面跟的是變數名稱,那麼可以省略 ( ),如果跟的是資料型別,就必須帶上 ( )。

需要注意的是,sizeof 是C語言中的操作符,不是函式,所以可以不帶 ( ),後面會詳細講解。

符號位

在數學中,數字有正負之分。在C語言中也是一樣,short、int、long 都可以帶上符號,例如:
  1. short a = -10; //負數
  2. int b = +10; //正數
  3. long c = (-9) + (+12); //負數和正數相加
如果不帶正負號,預設就是正數。

符號也要在記憶體中體現出來。符號只有正負兩種情況,用1位就足以表示,這1位就是最高位。以 int 為例,它佔用32位的記憶體,0~30位表示數值,31 位表示正負號。如下圖所示:
在程式語言中,計數往往是從0開始,例如字串 "abc123",我們稱第 0 個字元是 a,第 1 個字元是 b,第 5 個字元是 3。這和我們平時從 1 開始計數的習慣不一樣,大家要慢慢適應,培養程式設計思維。
在符號位中,用0表示正數,用1表示負數。例如 short 型別的 -10、+16 在記憶體中的表示如下:

如果不希望設定符號位,可以在資料型別前面加 unsigned,如下所示:
  1. unsigned short a = 12;
  2. unsigned int b = 1002;
  3. unsigned long c = 9892320;
這樣,short、int、long 中就沒有符號位了,所有的位都用來表示數值。也就意味著,使用了 unsigned 只能表示正數,不能表示負數了。

如果是unsigned int,那麼可以省略 int ,只寫 unsigned,例如:
unsigned n = 100;
它等價於:
unsigned int n = 100;
輸出無符號數使用%u,程式碼如下:
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. int main()
  4. {
  5. int a=1234;
  6. unsigned a1=1234;
  7. int b=0x7fffffff;
  8. int c=0x80000000; // 0x80000000 = 0x7fffffff + 0x1
  9. int d=0xffffffff;
  10. unsigned e=0xffffffff;
  11. printf("a=%d, a(u)=%u\n", a, a);
  12. printf("a1=%d, a1(u)=%u\n", a1, a1);
  13. printf("b=%d, b(u)=%u\n", b, b);
  14. printf("c=%d, c(u)=%u\n", c, c);
  15. printf("d=%d, d(u)=%u\n", d, d);
  16. printf("e=%d, e(u)=%u\n", e, e);
  17. system("pause");
  18. return 0;
  19. }
輸出結果:
a=1234, a(u)=1234
a1=1234, a1(u)=1234
b=2147483647, b(u)=2147483647
c=-2147483648, c(u)=2147483648
d=-1, d(u)=4294967295
e=-1, e(u)=4294967295

可以發現,無論變數宣告為有符號數還是無符號數,只有當以 %u 格式輸出時,才會作為無符號數處理;如果宣告為 unsigned,卻以 d% 輸出,那麼也是有符號數。
d、e 的輸出值之所以為 -1,與它們在記憶體中的儲存形式有關,我們將在《C語言整數在記憶體中的儲存》一節中詳細介紹。

取值範圍和資料溢位

short、int、long 佔用的位元組數不同,所能表示的數值範圍也不同。以32位平臺為例,下面是它們的取值範圍:
資料型別 所佔位元組數 取值範圍
short 2 -32768~32767,即 -215~(215-1)
unsigned short 2 0~65535,即 0~(216-1)
int 4 -2147483648~2147483647,即 -231~(231-1)
unsigned int 4 0~4294967295,即0~(232-1)
long 4 -2147483648~2147483647,即 -231~(231-1)
unsigned long 4 0~4294967295,即0~(232-1)

當數值過大或過小時,有限的幾個位元組就不能表示,就會發生溢位。發生溢位時,最高位會被截去。請看下面的例子:
  1. #include <stdio.h>
  2. int main()
  3. {
  4. unsigned int a = 0x100000000;
  5. printf("a=%u\n", a);
  6. return 0;
  7. }
執行結果:
a=0

變數 a 為 int 型別,佔用4個位元組(32位),能表示的最大值為 0xFFFFFFFF,而 0x100000000 = 0xFFFFFFFF + 1,佔用33位,已超出 a 所能表示的最大值,會發生溢位,最高位被截去,剩下的32位都是0。也就是說,在 a 被輸出前,其值已經變成了 0。

整數的字首

在程式中是根據字首來區分十進位制、八進位制和十六機制的。

1) 十進位制數由 0~9 十個數字組成,沒有字首。例如:
  • 合法的十進位制數:237、-568、65535、1627;
  • 不合法的十進位制數:023(不能有前導0)、23D(含有非十進位制數碼)。

2) 八進位制數由 0~7 八個數字組成,必須以0開頭,即以0作為八進位制數的字首。例如:
  • 合法的八進位制數:015(十進位制為13)、-0101(十進位制為-65)、0177777(十進位制為65535);
  • 不合法的八進位制數:256(無字首0)、03A2(包含了非八進位制數碼)。
注意字首是數字0,而不是字母o。
3) 十六進位制數由數字0~9、字母A~F或a~f組成,字首為0X或0x。例如:
  • 合法的十六進位制數:0X2A(十進位制為42)、-0XA0(十進位制為-160)、0xffff(十進位制為65535);
  • 不合法的十六進位制數:5A(無字首0X)、0X3H(含有非十六進位制數碼)。
在C語言中不能直接表示二進位制,它沒有特定的字首。

整數的字尾

1) 可以用字尾Ll來表示長整型數。例如:
  • 十進位制長整型數:158L、358000L;
  • 八進位制長整型數:012L、077L、0200000L;
  • 十六進位制長整型數:0X15L (十進位制為21)、0XA5L、0X10000L。

長整型數158L和基本整型數158 在數值上並無區別,但由於 158L 是長整型數,編譯器將為它分配 sizeof(long) 位元組的儲存空間。

2) 可以用字尾Uu來表示無符號數,例如 358u、0x38Au等。

字首、字尾可以同時使用以表示各種型別的整數。例如 0XA5Lu 表示十六進位制無符號長整型數 A5,其十進位制為165。
實際開發中經常使用字首,但較少使用字尾,因為將整數賦值給變數時就確定了它是否為 long 型別、是否為 unsigned 型別。

各種整數的輸出

在使用 printf 輸出整數時,不同的控制字元會有不同的輸出格式。

1) 輸出 int 使用%d,輸出 short 使用 %hd,輸出 long 使用 %ld。

使用 %d 輸出 short,或使用 %ld 輸出 int、short 時由於不會發生溢位,所以能夠正確輸出。而使用 %d 輸出 long、或使用 %hd 輸出 int、long 時可能會發生資料溢位,導致輸出錯誤。請看下面的例子:
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. int main()
  4. {
  5. unsigned short a = 100, b = 0x10000;
  6. long c = 0x10, d = 0x10000;
  7. printf("a=%d, b=%d\n", a, b);
  8. printf("c=%hd, d=%hd\n", c, d);
  9. system("pause");
  10. return 0;
  11. }
執行結果:
a=100, b=0
c=16, d=0

變數a、b為 unsigned short 型別,佔用2個位元組,能表示的最大值為 0XFFFF。a 在輸出時使用 %d,能容納的數值比 a 大,自然不會發生溢位。而 b 被賦值 0x10000,0x10000>0xFFFF,在賦值時就已經發生了溢位,其值為 0,所以 %d 也輸出 0。

變數 c、d 為 long 型別,佔用4個位元組,能表示的最大值為 0XFFFFFFFF,它們在賦值時都沒有溢位。當以 %hd 輸出時,會截去較高的兩個位元組,只輸出較低兩個位元組中的內容。c 的值為 0x10,儲存在較低的兩個位元組中,所以 %hd 能夠正確輸出。而 d 的值為 0x10000,較低的兩個位元組全部為0,輸出時它的值也就為 0。
實際開發中使用 %d 和 %ld 足以,幾乎不使用 %hd。

2) 輸出無符號數使用%u。上面已經講過,不再贅述。

3) 輸出十進位制使用%d,輸出八進位制使用%o,輸出十六進位制使用%x或%X。如果希望帶上字首,可以加#,例如 %#d、%#o、%#x、%#X。請看下面的例子:
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. int main()
  4. {
  5. int a = 100, b = 0270, c = 0X2F;
  6. printf("a(d)=%d, d(#d)=%#d\n", a, a);
  7. printf("a(o)=%o, d(#o)=%#o\n", b, b);
  8. printf("c(x)=%x, c(#x)=%#x, c(X)=%X, c(#X)=%#X\n", c, c, c, c);
  9. system("pause");
  10. return 0;
  11. }
執行結果:
a(d)=100, d(#d)=100

相關推薦

C語言整數short,int,long

整數是程式設計中常用的一種資料,C語言中有三種整數型別,分別為 short、int 和 long。int 稱為整型,short 稱為短整型,long 稱為長整型,它們的長度(所佔位元組數)關係為: short <= int <= long 它們具體佔用幾個位元

GUN ARM彙編標號的引用在彙編和C語言區別monitor_flash_len = _bss_start

u-boot/cpu/xx/start.S中: _TEXT_BASE:  .word TEXT_BASE /*uboot映像在SDRAM中的重定位地址,我設定為0xa170 0000 */  .globl _armboot_start  _armboot_start:  .w

問答關於C語言共同體聯合體的問題

 原問答是這樣的: “ #include main() { union data { long w; float x; char c; }; 執行下列語句後a的十進位制值是多少? union d

c語言整數溢位的概念

在編寫程式時,如果整數的值太大,超出了所定義的整數型別的範圍會怎麼樣? 下面分別將有符號型別好無符號型別整數設定為最大允許值加略大一些的值,看一看結果是是什麼。    //printf函式使用%u說明符顯示unsigned  int型別的值 程式段 #include &l

C 語言異常處理五十二

異常處理 C 中的異常處理 if...else... setjmp() longjmp() 我們今天來看下異常處理,在看 C++ 的異常處理之前,先來看看 C 語言中的異常處理。那麽什麽是異常呢?在程序運行過程中可能會產生異常,異常(Exception)與 Bug 的區別是

1012 - C語言程式設計教程第三版課後習題6.2

1012 - C語言程式設計教程(第三版)課後習題6.2 時間限制:1秒 記憶體限制:128兆 題目描述 輸入一行字元,分別統計出其中英文字母、空格、數字和其他字元的個數。 輸入 一行字元 輸出 統計值 樣例輸入 aklsjflj123 sadf918u324 asdf91u32oa

1011 - C語言程式設計教程第三版課後習題6.1

1011 - C語言程式設計教程(第三版)課後習題6.1 時間限制:1秒 記憶體限制:128兆 題目描述 輸入兩個正整數m和n,求其最大公約數和最小公倍數。 輸入 兩個整數 輸出 最大公約數,最小公倍數 樣例輸入 5 7 樣例輸出 1 35 最大公約數求法我是用的是輾轉相除法進行

1010 - C語言程式設計教程第三版課後習題5.8

1010 - C語言程式設計教程(第三版)課後習題5.8 時間限制:1秒 記憶體限制:128兆 題目描述 企業發放的獎金根據利潤提成。利潤低於或等於100000元的,獎金可提10%; 利潤高於100000元,低於200000元(100000<I≤200000)時,低於100000元的部

1047 - C語言程式設計教程第三版課後習題10.5

1047 - C語言程式設計教程(第三版)課後習題10.5 時間限制:1秒 記憶體限制:128兆 題目描述 有n人圍成一圈,順序排號。從第1個人開始報數(從1到3報數),凡報到3的人退出圈子,問最後留下的是原來的第幾號的那位。 輸入 初始人數n 輸出 最後一人的初始編號 樣例輸入

1022 - C語言程式設計教程第三版課後習題7.1

1022 - C語言程式設計教程(第三版)課後習題7.1 時間限制:1秒 記憶體限制:128兆 題目描述 用篩法求之N內的素數。 輸入 N 輸出 0~N的素數 樣例輸入 100 樣例輸出 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47

1008 - C語言程式設計教程第三版課後習題5.6

1008 - C語言程式設計教程(第三版)課後習題5.6 時間限制:1秒 記憶體限制:128兆 題目描述 給出一百分制成績,要求輸出成績等級‘A’、‘B’、‘C’、‘D’、‘E’。 90分以上為A 80-89分為B 70-79分為C 60-69分為D 60分以下為E 輸入 一個整數0

1007 - C語言程式設計教程第三版課後習題5.5

007 - C語言程式設計教程(第三版)課後習題5.5 時間限制:1秒 記憶體限制:128兆 描述 有一個函式 y={ x x<1 | 2x-1 1<=x<10 \ 3x-11 x>=10 寫一段程式,輸入x,輸出y 輸入 一個數x 輸出 一個數y 樣例輸

1006 - C語言程式設計教程第三版課後習題5.4

1006 - C語言程式設計教程(第三版)課後習題5.4 時間限制:1秒 記憶體限制:128兆 描述 有三個整數a b c,由鍵盤輸入,輸出其中的最大的數。 輸入 一行陣列,分別為a b c 輸出 a b c其中最大的數 樣例輸入 10 20 30 樣例輸出 30 提示 max ?

1005 - C語言程式設計教程第三版課後習題4.9

1005 - C語言程式設計教程(第三版)課後習題4.9 時間限制:1秒 記憶體限制:128兆 題目描述 輸入一個華氏溫度,要求輸出攝氏溫度。公式為 c=5(F-32)/9 輸出要求有文字說明,取位2小數。 輸入 一個華氏溫度,浮點數 輸出 攝氏溫度,浮點兩位小數 樣例輸入 -4

1003 - C語言程式設計教程第三版課後習題3.7

1003 - C語言程式設計教程(第三版)課後習題3.7 時間限制:1秒 記憶體限制:128兆 提交 題目描述 要將"China"譯成密碼,譯碼規律是:用原來字母后面的第4個字母代替原來的字母.例如,字母"A"後面第4個字母是"E".“E"代替"A”。因此,“China"應譯

1002 - C語言程式設計教程第三版課後習題1.6

1002 - C語言程式設計教程(第三版)課後習題1.6 時間限制:1秒 記憶體限制:128兆 題目描述 編寫一個程式,輸入a、b、c三個值,輸出其中最大值。 輸入 一行陣列,分別為a b c 輸出 a b c其中最大的數 樣例輸入 10 20 30 樣例輸出

1014 - C語言程式設計教程第三版課後習題6.4

1014 - C語言程式設計教程(第三版)課後習題6.4 時間限制:1秒 記憶體限制:128兆 題目描述 求Sn=1!+2!+3!+4!+5!+…+n!之值,其中n是一個數字。 輸入 n 輸出 和 樣例輸入 5 樣例輸出 153 題求一個數的階乘和,本身並不是一個難想的思路,

資料結構C語言第二版53頁作業

#include<iostream> using namespace std; typedef struct //定義順序表 { int *elem; int length; }SqList; typedef struct LNode //定義單向連結串列 { int dat

C語言入門經典第四版.pdf

《C語言入門經典(第4版)》的目標是使你在C語言程式設計方面由一位初學者成為一位稱職的程式設計師。讀者基本不需要具備任何程式設計知識,即可通過《C語言入門經典(第4版)》從頭開始編寫自己的C程式。研讀《C語言入門經典(第4版)》,你就可以成為一位稱職的C語言程式設計師。從許多方面來說,C語言

1015 - C語言程式設計教程第三版課後習題6.5

1015 - C語言程式設計教程(第三版)課後習題6.5 時間限制:1秒 記憶體限制:128兆 題目描述 求以下三數的和,保留2位小數 1~a之和 1~b的平方和 1~c的倒數和 輸入 a b c 輸出 1+2+…+a + 1 ^ 2 + 2 ^ 2+…+b ^ 2 + 1/1+1/2+…+