1.简介
整数类型用来表示较大的整数,类型声明使用int关键字。
1 |
int a; |
上面示例声明了一个整数变量a
。
不同计算机的int
类型的大小是不一样的。比较常见的是使用4个字节(32位)存储一个int
类型的值,但是2个字节(16位)或8个字节(64位)也有可能使用。它们可以表示的整数范围如下。
- 16位:-32,768 到 32,767。
- 32位:-2,147,483,648 到 2,147,483,647。
- 64位:-9,223,372,036,854,775,808 到 9,223,372,036,854,775,807。
2. signed,unsigned
C 语言使用signed
关键字,表示一个类型带有正负号,包含负值;使用unsigned
关键字,表示该类型不带有正负号,只能表示零和正整数。
对于int
类型,默认是带有正负号的,也就是说int
等同于signed int
。由于这是默认情况,关键字signed
一般都省略不写,但是写了也不算错。
1 2 |
signed int a; // 等同于 int a; |
int类型也可以不带正负号,只表示非负整数。这时就必须使用关键字unsigned声明变量。
1 |
unsigned int a; |
整数变量声明为unsigned
的好处是,同样长度的内存能够表示的最大整数值,增大了一倍。比如,16位的signed int
最大值为32,767,而unsigned int
的最大值增大到了65,535。
unsigned int
里面的int
可以省略,所以上面的变量声明也可以写成下面这样。
1 |
unsigned a; |
字符类型char也可以设置signed和unsigned。
1 2 |
signed char c; // 范围为 -128 到 127 unsigned char c; // 范围为 0 到 255 |
注意,C 语言规定char
类型默认是否带有正负号,由当前系统决定。这就是说,char
不等同于signed char;
它有可能是signed char
,也有可能是unsigned char
。
这一点与int
不同,int
就是等同于signed int
。
3.整数的子类型
如果int
类型使用4个或8个字节表示一个整数,对于小整数,这样做很浪费空间。另一方面,某些场合需要更大的整数,8个字节还不够。为了解决这些问题,C 语言在int
类型之外,又提供了三个整数的子类型。这样有利于更精细地限定整数变量的范围,也有利于更好地表达代码的意图。
short int
(简写为short
):占用空间不多于int
,一般占用2个字节(整数范围为-32768~32767)。long int
(简写为long
):占用空间不少于int
,至少为4个字节。long long int
(简写为long long
):占用空间多于long
,至少为8个字节。
1 2 3 |
short int a; long int b; long long int c; |
上面代码分别声明了三种整数子类型的变量。
默认情况下,short
、long
、long long
都是带符号的(signed),即signed
关键字省略了。它们也可以声明为不带符号(unsigned),使得能够表示的最大值扩大一倍。
1 2 3 |
unsigned short int a; unsigned long int b; unsigned long long int c; |
C 语言允许省略int
,所以变量声明语句也可以写成下面这样。
1 2 3 4 5 6 7 |
short a; unsigned short a; long b; unsigned long b; long long c; unsigned long long c; |
不同的计算机,数据类型的字节长度是不一样的。确实需要32位整数时,应使用long
类型而不是int
类型,可以确保不少于4个字节;确实需要64位的整数时,应该使用long long
类型,可以确保不少于8个字节。另一方面,为了节省空间,只需要16位整数时,应使用short
类型;需要8位整数时,应该使用char
类型。
4.整数类型的极限值
有时候需要查看,当前系统不同整数类型的最大值和最小值,C 语言的头文件limits.h
提供了相应的常量,比如SCHAR_MIN
代表 signed char 类型的最小值-128
,SCHAR_MAX
代表 signed char 类型的最大值127
。
为了代码的可移植性,需要知道某种整数类型的极限值时,应该尽量使用这些常量。
SCHAR_MIN
,SCHAR_MAX
:signed char 的最小值和最大值。SHRT_MIN
,SHRT_MAX
:short 的最小值和最大值。INT_MIN
,INT_MAX
:int 的最小值和最大值。LONG_MIN
,LONG_MAX
:long 的最小值和最大值。LLONG_MIN
,LLONG_MAX
:long long 的最小值和最大值。UCHAR_MAX
:unsigned char 的最大值。USHRT_MAX
:unsigned short 的最大值。UINT_MAX
:unsigned int 的最大值。ULONG_MAX
:unsigned long 的最大值。ULLONG_MAX
:unsigned long long 的最大值。
整型数据类型 | 字节 | 数值范围 | 输出输入格式说明 |
---|---|---|---|
short int | 2 | -32,768 to 32,767 | %hd |
unsigned short int | 2 | 0 to 65,535 | %hu |
unsigned int | 4 | 0 to 4,294,967,295 | %u |
int | 4 | -2,147,483,648 to 2,147,483,647 | %d |
long int | 4 | -2,147,483,648 to 2,147,483,647 | %ld |
unsigned long int | 4 | 0 to 4,294,967,295 | %lu |
long long int | 8 | -(2^63) to (2^63)-1 | %lld |
unsigned long long int | 8 | 0 to 18,446,744,073,709,551,615 | %llu |
signed char | 1 | -128 to 127 | %c |
unsigned char | 1 | 0 to 255 | %c |
float | 4 | %f | |
double | 8 | %lf | |
long double | 16 | %Lf |
我们可以使用 thesizeof() 函数检查每个数据类型的字节大小。
例1. 整数数据占用的字节和整数类型的最大值和最小值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
#include <stdio.h> #include <stdlib.h> #include <limits.h> #include <float.h> int main() { //for how many bytes printf("size of int : %d\n",sizeof(int)); printf("size of char : %d\n",sizeof(char)); printf("size of signed char : %d\n",sizeof(signed char)); printf("size of unsigned char : %d\n",sizeof(unsigned char)); printf("size of short : %d\n",sizeof(short)); printf("size of short int : %d\n",sizeof(short int)); printf("size of signed short : %d\n",sizeof(signed short)); printf("size of signed short int : %d\n",sizeof(signed short int)); printf("size of long int : %d\n",sizeof( long int)); printf("size of float : %d\n",sizeof(float)); printf("size of double : %d\n",sizeof(double)); printf("size of long double : %d\n",sizeof(long double)); printf("CHAR_BIT : %d\n", CHAR_BIT); //how many bits //Max Value and Min Value printf("CHAR_MAX : %d\n", CHAR_MAX); printf("CHAR_MIN : %d\n", CHAR_MIN); printf("INT_MAX : %d\n", INT_MAX); printf("INT_MIN : %d\n", INT_MIN); printf("LONG_MAX : %ld\n", (long) LONG_MAX); printf("LONG_MIN : %ld\n", (long) LONG_MIN); printf("SCHAR_MAX : %d\n", SCHAR_MAX); printf("SCHAR_MIN : %d\n", SCHAR_MIN); printf("SHRT_MAX : %d\n", SHRT_MAX); printf("SHRT_MIN : %d\n", SHRT_MIN); printf("UCHAR_MAX : %d\n", UCHAR_MAX); printf("UINT_MAX : %u\n", (unsigned int) UINT_MAX); printf("ULONG_MAX : %lu\n", (unsigned long) ULONG_MAX); printf("USHRT_MAX : %d\n", (unsigned short) USHRT_MAX); return 0; } |
结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
size of int : 4 size of char : 1 size of signed char : 1 size of unsigned char : 1 size of short : 2 size of short int : 2 size of signed short : 2 size of signed short int : 2 size of long int : 4 size of float : 4 size of double : 8 size of long double : 16 CHAR_BIT : 8 CHAR_MAX : 127 CHAR_MIN : -128 INT_MAX : 2147483647 INT_MIN : -2147483648 LONG_MAX : 2147483647 LONG_MIN : -2147483648 SCHAR_MAX : 127 SCHAR_MIN : -128 SHRT_MAX : 32767 SHRT_MIN : -32768 UCHAR_MAX : 255 UINT_MAX : 4294967295 ULONG_MAX : 4294967295 USHRT_MAX : 6553 |
5.整数的进制
C 语言的整数默认都是十进制数,如果要表示八进制数和十六进制数,必须使用专门的表示法。
八进制使用0
作为前缀,比如017
、0377
。
1 |
int a = 012; // 八进制,相当于十进制的10 |
十六进制使用0x或0X作为前缀,比如0xf、0X10。
1 |
int a = 0x1A2B; // 十六进制,相当于十进制的6699 |
注意,不同的进制只是整数的书写方法,不会对整数的实际存储方式产生影响。所有整数都是二进制形式存储,跟书写方式无关。
不同进制可以混合使用,比如10 + 015 + 0x20是一个合法的表达式。
例2. 十进制,八进制,十六进制的存储和运算
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
#include <stdio.h> #include <stdlib.h> #include <limits.h> #include <float.h> int main() { int x = 100; int y = 0144; printf("dec = %d\n", x); // 100 printf("octal = %o\n", x); // 144 printf("hex = %x\n", x); // 64 printf("octal = %#o\n", x); // 0144 printf("Dec x + y = %d\n", x+y); // 200 return 0; } |
结果:
1 2 3 4 5 |
dec = 100 octal = 144 hex = 64 octal = 0144 Dec x + y = 200 |
printf()
的进制相关占位符如下。
%d
:十进制整数。%o
:八进制整数。%x
:十六进制整数。%#o
:显示前缀0
的八进制整数。%#x
:显示前缀0x
的十六进制整数。%#X
:显示前缀0X
的十六进制整数。
6. 整型变量的溢出
例3. char型变量的溢出
#include <stdio.h>
1 2 3 4 5 6 7 |
int main() { char a = 127; char b = a + 1; printf("a=%d\tb=%d", a,b); return 0; } |
结果:
1 2 3 |
a=127 b=-128 Process returned 0 (0x0) execution time : 0.036 s Press any key to continue. |
原因:127的二进制值是0111 1111 加1后变成 1000 0000,这个值是-128.
所以输出结果是溢出了。
下图能够更好的理解整型变脸的溢出,127溢出后又变成-128。

例4.整型变量的溢出
1 2 3 4 5 6 7 8 9 10 |
#include <stdio.h> int main() { int a, b; a=2147483647; b=a+1; printf("%d, %d\n",a,b); return 0; } |
1 2 3 4 5 6 |
结果 2147483647, -2147483648 Process returned 0 (0x0) execution time : 0.587 s Press any key to continue. |
原因:a的值用二进制表示是:01111111 11111111 11111111 11111111 加1后变成 10000000 00000000 00000000
实际上也是溢出了。