C语⾔基本数据类型:整型(int)⽤法详解
C语⾔基本数据类型:整型(int)⽤法详解
1. 整型int
C 语⾔提供了很多整数类型(整型),这些整型的区别在于它们的取值范围的⼤⼩,以及是否可以为负。int是整型之⼀,⼀般被称为整型。以后,在不产⽣歧义的情况下,我们把整数类型和int都称为整型。
int代表有符号整数,也就是说,⽤int声明的变量可以是正数,可以是负数,也可以是零,但是只能是整数。标准规定int的最⼩取值范围是 -32767 到 32767。int的取值范围因机器⽽异,但是⼀定要⼤于或者等于 -32767 到 32767。⼀般来说,int占⽤⼀个字的内存空间。因此,字长为 16 位(Bit)的旧式 IBM 兼容机使⽤ 16 位来储存整型int,取值范围是 -32768 到 32767 。⽬前的个⼈电脑⼀般都是 32 位字长的,这些电脑中,int⼀般也是 32 位的,取值范围是 -2147483648 到 2147483647。对于使⽤ 64 位 CPU 的电脑,使⽤更多位储存int也是很⾃然的事情,取值范围当然也会更⼤。
2. 声明int类型的变量
正如我们在以前的教程⾥看到的那样,int⽤于声明整型变量:以int打头,后⾯跟着变量的名字,最后以
分号(;)结束。例如: interns; /* 声明⼀个变量 */
/* 注意:⼀定要⽤逗号(,),不能⽤分号(;)*/ int hogs, cows, goats; /* 声明三个变量 */
以上声明创建了变量,但是没有给它们提供“值(value)”。在前⾯的教程中,我们已经⽤了两种⽅法使变量获
得“值”。⼀种是赋值:cows = 500; 。另⼀种是使⽤scanf函数:scanf( "%d", &goats ); 。下⾯我们来学习第三种⽅法。
3. 初始化变量
初始化变量是指给变量赋初值:声明变量的时候,在变量名的后⾯写上等号(=),然后写下你希望赋予变量的“值”。例如: int hogs = 21;
int cows = 32, goats = 14;
int dogs, cats = 94;
以上声明创建了变量,并且为这些变量分配了空间,同时也赋了初值。注意,第三⾏中只有 cats 被初始化为 94,⽽ dogs 没有被初始化!如下图:
4. int常量
上⾯的例⼦中,21、32、14,以及 94 都是整数常量。C 语⾔中,整数常量的默认类型是int。如果整数常量的⼤⼩超过了int的取值范围,那么编译器将会把这个整数常量当作 long int类型来处理,这个我们后⾯还会讲到。21、32、14 和 94
都在int的取值范围之内,因此它们都是int常量。
5. 输出int型数据
我们可以⽤printf函数来输出int型数据。正如我们在前⾯的教程中看到的那样,占位符 %d代表输出的是int型数据,它告诉printf函数在什么地⽅输出相应的int型数据。%d 也被称为格式限定符(format specifier),因为它指定了printf函数应该使⽤什么形式来输出数据。printf函数的第⼀个参数只能是字符串,这个字符串被称为格式串(format string)。格式串中有多少个 %d,我们就应该相应地提供多少个int型参数给printf函数。int型参数可以是int型变量,int型常量,以及结果为int型的表达式等。例如: int year = 2005; /* year 是int型变量 */
printf( "Today is %d-%d-%d ", year, 9, 20 + 9 ); /* 20 + 9 是加法表达式 */
保证格式限定符的数⽬和参数数⽬⼀致是我们的责任,编译器不负责捕捉这种错误!例如: #include
<stdio.h> int
main(void) {
int ten = 10, two = 2;
printf("%d minus %d is %d ", ten ); /* 少写了两个参数 */ getchar(); /* 等待⽤户按回车 */ return 0; }
这个程序可以通过编译,但是运⾏结果将会出乎意料,因为我们少写了两个参数。标准规定,如果格式限定符的数⽬⼤于参数数⽬,则printf函数的⾏为是未定义的;如果参数数⽬⼤于格式限定符的数⽬,则多余的参数会被忽略。
6. ⼋进制(octal)和⼗六进制(hexadecimal)
C 语⾔中,整数常量默认是⼗进制(decimal)整数。通过在整数常量前⾯加上特定的前缀,可以把它设定为⼋进制或者⼗六进制整数。前缀 0x 或者 0X 把整数常量设定为⼗六进制整数。注意,是数字 0 ,⽽不是字母 O ,别搞错了哦!例如:⼗进制的 16 ⽤⼗六进制来表⽰是 0x10 或者 0X10 。在整数常量前⾯加上前缀 0 ,表⽰它是⼋进制整数。注意,是数字0 ,⽽不是字母 O 。例如:⼗进制的 16 表⽰为⼋进制就是 020 。
7. 以⼋进制或者⼗六进制形式输出数据
使⽤格式限定符 %o 可以以⼋进制的形式输出整数。注意,是⼩写字母 o ,不是数字 0 。使⽤ %x 或者 %X 可以以⼗六进制的形式输出整数。⼩写 x 表⽰输出使⽤⼩写字母,⼤写 X 表⽰输出使⽤⼤写字母。使⽤ %#o,%#x 或者 %#X,得到的输出将包括前缀 0,0x 或者 0X。例如: #include <stdio.h> int main(void) {
int x = 200;
printf("dec = %d; octal = %o; hex = %x; HEX = %X ", x, x, x, x); printf("dec = %d; octal = %#o; hex = %#x; HEX = %#X ", x, x, x, x); getchar(); return 0; }
这个程序的输出是:
dec = 200; octal = 310; hex = c8; HEX = C8
dec = 200; octal = 0310; hex = 0xc8; HEX = 0XC8
1. 其它整数类型
int是 C 语⾔的基本整数类型,可以满⾜我们处理⼀般数据的需求。C 语⾔还提供了四个可以修饰int的关键字:short、long、signed,以及 unsigned。利⽤这四个关键字,C 语⾔标准定义了以下整数类型:
1) short int(可简写为short),和int⼀样,也是有符号整数 2) long int(简写:long),有符号整数 3) long longint(简写:long
long),C99 标准添加的类型, 有符号整数
4) unsigned int(简写:unsigned),⽆符号整数,不能表⽰负数 5) unsigned long int(简写:unsigned long),⽆符号整数, 不能表⽰负数
6) unsigned short int(简写:unsigned short),⽆符号整数, 不能表⽰负数
7) unsigned long longint(简写:unsigned long long),
C99 添加的类型,⽆符号整数
8) 所有没有标明 unsigned 的整数类型默认都是有符号整数。 在这些整数类型前⾯加上 signed 可以使读者更清楚地知道这些是有符号整数,尽管有没有 signed 都表⽰有符号整数。 例如:signed int等同于int。
⼀般我们把 short 称为短整型,把 long 称为长整型,把 long long称为超长整型,把int称为整型。unsigned 打头的那些整数类型统称为⽆符号整型。例如:我们称 unsigned short 为⽆符号短整型。以此类推。
2. 声明⽅式
这些整数类型的声明⽅式与int类型的声明⽅式⼀样。例如: longintestine; long johns; shortinterns; short ribs; unsignedints_count; unsigned players;
unsigned long headcount; unsigned short yesvotes;
long longago; /* C99 特有 */
unsigned long long ego; /* C99 特有 */
如果您的编译器不⽀持 C99 标准,那就不能使⽤ long long和 unsigned long long。
3. 取值范围(表⽰范围)
标准也规定了这些整数类型的最⼩取值范围。short 的最⼩表⽰范围和int⼀样,都是 -32767 到 32767 。也就是 -(2^15 - 1)到(2^15 - 1)。其中,2^15表⽰ 2 的 15 次⽅。类似地,2 的 20 次⽅记作 2^20 ,以此类推。注意:C 语⾔中
2^15 并不表⽰ 2 的 15 次⽅,为了书写⽅便,我们姑且这么表⽰。long 的最⼩取值范围是 -21474836
47 到2147483647 。也就是 -(2^31 - 1) 到 (2^31 - 1) 。unsigned short的最⼩表⽰范围和unsigned int⼀样,都是 0 到65535(2^16 - 1)。unsigned long 的最⼩取值范围是 0 到 4294967295(2^32 - 1)。long long的最⼩取值范围是 -9223372036854775807(-(2^63 - 1))到 9223372036854775807(2^63 - 1);unsigned long long是 0到 18446744073709551615(2^64 - 1)。
标准规定,int的表⽰范围不能⼩于 short 的表⽰范围,long 的表⽰范围不能⼩于int的表⽰范围。这就是说 short 型变量占⽤的空间可能⽐int型变量少,⽽ long 型变量占⽤的空间可能⽐int型变量多。16 位(bit)的计算机中,int和 short ⼀般都是 16 位,⽽ long 是 32位;32位的计算机中,short⼀般是 16 位,⽽long和int是 32位。TC2(16位的编译器)中,int是16位的;⽽Dev-C++(32 位的编译器)中,int是 32 位的。
使⽤ unsigned int声明的变量只能表⽰⾮负整数(0 和正整数)。如果int是 16 位的话,那么 unsigned int的表⽰范围是0 到 65535(2^16 - 1)。这是因为 unsigned 不需要符号位,可以把 16 个位全都⽤于表⽰整数。⽽int需要⼀个位作为符号位,⽤于表⽰正负,只有 15 个位⽤于表⽰整数。
⽬前,long long⼀般 64 位,long 是 32 位,short 是 16 位,⽽int或者 16 位,或者 32 位。具体某个编译器到底使⽤多少位来表⽰这些类型,我们可以⽤运算符sizeof来获取。例如:
printf( "%lu ", (unsigned long)sizeof(int) * 8 ); /* 输出int的位数 */ printf( "%zu ", sizeof(short) * 8 ); /* 输
出 short
的位数 */
sizeof运算符返回其操作数占⽤空间的⼤⼩,以字节(Byte)为单位。注意,C 定义字节的⼤⼩为 char 类型的⼤⼩。char
通常是 8 位(bit)的,当然也可以更⼤。这⾥我们假设 char 是 8 位的。点击查看 char 类型详细介绍
sizeof的⽤法我们以后会讲到,现在只要有个印象就好了。第⼆句中的 %zu是 C99 特有的,如果您的编译器不⽀持
C99(准确地说,应该是如果您的编译器使⽤的库函数不⽀持 C99),运⾏结果将会出错。
4. 整数类型的选择
如果您要处理的只是⾮负整数,那么应该优先使⽤ unsigned 打头的那些整数类型。如果您要处理的整数超出了int所能表⽰的范围,并且您的编译器中,long 的表⽰范围⽐int⼤,那就使⽤ long。不过,若⾮必要,尽量不要⽤ long,因为它可能会降低程序运⾏效率。有⼀点要注意:如果您的编译器中,long 和int都是 32 位的,并且您需要使⽤ 32 位整数,那么应该⽤ long,⽽不要⽤int。只有这样,我
们的程序才可以安全地移植到 16 位的计算机,因为 16 位的计算机中,int⼀般也是 16 位的。类似地,如果您需要使⽤ 64 位整数,那就⽤ long long。如果int是 32 位的话,那么使⽤ short 可以节省空间,不过您得确保您要处理的整数不会超出 short 的表⽰范围。这种“节省”对内存⼤的计算机来说,是没什么意义的。
5. long 型常量和 long long型常量
⼀般来说,整数常量是被当作int类型来存储的。如果我们使⽤的整数常量超出了int的表⽰范围,C 语⾔规定编译器⾃动使⽤ unsigned int来处理这个常量。如果 unsigned 也不⾜以表⽰这个常量的话,编译器就会⽤ long。如果还表⽰不了的话,那就依次⽤ unsigned long,long long,unsigned long long。如果 unsigned long long也表⽰不了,那么编译器就没辙了。注意:long long和 unsigned long long是 C99 特有的。例如:如果int是 16 位的话,它就表⽰不了常量1000000。编译器会使⽤ long 来处理这个常量,因为 unsigned int也表⽰不了 1000000 。 同样,⼗六进制和⼋进制整数常量通常也是被作为int来处理。但是,当我们使⽤的常量超出了int的表⽰范围后,编译器会依次使⽤unsigned
int,long,unsigned long,long long和 unsigned long long。直到所使⽤的类型⾜以表⽰那个常量为⽌。
有时,我们使⽤的是较⼩的常量,但是我们希望这个常量被当作 long 来处理,这就需要在这个常量后
⾯加上后缀 l(⼩写字母 l)或者 L(⼤写字母 L)。我们应该避免使⽤ l ,因为 l 容易和数字 1 混淆。例如:整数常量 7 是被作为int来处理的,但整数常量 7L(或者 7l)是被作为 long 来处理的。类似地,在整数常量后⾯加上后缀ll或者 LL ,这个常量就会被当作long long来处理。例如:3LL 。如果想使⽤⽆符号整数常量的话,还要配合使⽤后缀 u 或者 U 。例如:
2u,3U,4Lu,5ul,6LU,7LLU,8Ull,9uLL 。
这些后缀也可以⽤于⼗六进制和⼋进制整数常量。例如:020L,010LL,0x30uL,0x40ull 。
1. 输出各种整数类型的变量
输出不同类型的整数,需要使⽤不⽤的格式限定符。输出 unsigned int类型的整数,要⽤ %u 。输出 long ,要⽤ %ld;如果要以⼗六进制或者⼋进制形式输出,那就⽤ %lx(或者%lX)或者 %lo。注意:虽然整数常量的后缀使⽤⼤写或者⼩写英⽂字母都没关系,但是它们格式限定符必须使⽤⼩写!如果我们要输出 short 类型的整数,可以在 %d 中间加上前缀 h,也就是%hd;同理,%ho 和 %hx(或者 %hX)分别表⽰以⼋进制或⼗六进制形式输出。前缀 h 和 l 可以和 u 组合,表⽰输出⽆符号整数。例如:%lu表⽰输出 unsigned long 类型的整数;%hu表⽰输出unsigned short类型的整数。如果您的编译器⽀持C99,可以使⽤ %lld和 %llu分别表⽰输出 long long和 unsigned long long。下⾯我们来看⼀个输出各种类型整数的程序:
#include <stdio.h> int main(void)        {
unsigned int un = 3000000000; /* 我使⽤的编译器int是 32 位的 */ short end = 200; /* ⽽ short 是 16 位的 */ long big = 65537;
printf("un = %u and not %d ", un, un); printf("end = %hd and %d ", end, end); printf("big = %ld and not %hd ", big, big); printf("Press ENTER "); getchar(); return 0;        }
使⽤Dev-C++ 编译运⾏这个程序输出结果如下: un = 3000000000 and not -1294967296 end = 200 and 200 big = 65537 and not 1
Press ENTER
这个程序表明,错误使⽤格式限定符会导致意想不到的输出。⾸先,错误使⽤ %d 来做⽆符号整型变量 un 的格式限定符,导致输出的是负数。这是因为我的计算机使⽤相同的⼆进制形式来表⽰ 3000000000 和 -129496296 ,⽽计算机只认识⼆进制。所以,如果我们使⽤ %u 告诉printf输出⽆符号整数,输出的就是 3000000000;如果我们误⽤了 %d,那么输出的就是⼀个负数。不过,如果我们把代码中的 3000000000 改成 96 的话,输出就不会出现异常。因为 96 没有超出int的表⽰范围。
然后,对于第⼆个printf,⽆论我们使⽤ %hd还是 %d,输出的结果都是⼀样的。这是因为 C 语⾔标准
c++string类型规定,当 short 类型值传递给函数时,要⾃动转化成int类型值。之所以转化成int,是因为int被设计为计算机处理效率最⾼的整数类型。所以,对于 short 和int⼤⼩不同的计算机来说,把变量 end 转化成int类型再传递给函数,速度更快。如此说来,h 好像没有存在意义。其实不然。我们可以⽤ %hd来看看较⼤的整数类型被截断成 short 类型的时候会是什么样的。
⽽第三个printf,由于误⽤ %hd,导致输出是 1。这是因为,如果 long 是 32 位的话,65537 的⼆进制形式便是 0000 0000 0000 0001 0000 0000 0000 0001,⽽ %hd命令printf输出 short 类型的值,从⽽导致printf只处理 16 位数
据(假设 short 是 16 位的),最终导致输出 1。 在前⾯的教程⾥,我们说过,保证格式限定符的数⽬和参数数⽬⼀致是我们的责任。同样,保证格式限定符的类型和参数类型⼀致也是我们的责任!正如上⾯所说的那样,错误使⽤格式限定符会导致意想不到的输出!标准规定,如果任意参数和与其对应的格式限定符类型不⼀致,则printf的⾏为是未定义的;如果格式限定符本⾝就是⾮法的,则printf的⾏为也是未定义的。
2. 整数溢出
⾸先请看以下程序: #include <stdio.h> int main(void) {
/
* 32 位int表⽰范围的上限和下限 */ int i = 2147483647, j = -2147483648; unsignedint k = 4294967295, l = 0; printf("%d %d %d %d ", i, i+1, j, j-1); printf("%u %u %u %u %u ", k, k+1, k+2, l, l-1); printf("Press ENTER "); getchar(); return 0; }
使⽤Dev-C++ 编译运⾏这个程序输出结果如下:  2147483647 -2147483648 -2147483648 2147483647 4294967295 0 1 0 4294967295 Press ENTER
本例中,i+1 是负数,j-1 是正数,k+1 是 0,l-1 是 4294967295 。这是因为加减运算过后,它们的值超出了它们对应的那种整数类型的表⽰范围,我们把这种现象称为溢出。 unsigned int型变量的值如果超过了上限,就会返回 0,然后从 0开始增⼤。如果低于下限,那么就会到达 unsigned 型的上限,然后从上限开始减⼩。就好像⼀个⼈绕着跑道跑步⼀样,绕了⼀圈,⼜返回出发点。⼀般,int型变量溢出的话,会变成负数,或者正数。
对于 unsigned 类型的整数,它们溢出时的情况⼀定和上⾯描述的⼀样,这是标准规定的。但是标准并没有规定有符号整数溢出时会出现什么情况。这⾥描述的有符号整数溢出时出现的情况是最常见的,但是在别的计算机,使⽤别的编译器,也可能出现不同的情况。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。