C语言基本数据类型整型int用法详解.docx
- 文档编号:29948173
- 上传时间:2023-08-03
- 格式:DOCX
- 页数:21
- 大小:30.75KB
C语言基本数据类型整型int用法详解.docx
《C语言基本数据类型整型int用法详解.docx》由会员分享,可在线阅读,更多相关《C语言基本数据类型整型int用法详解.docx(21页珍藏版)》请在冰豆网上搜索。
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;/*声明一个变量*/
/*注意:
一定要用逗号(,),不能用分号(;)*/
inthogs,cows,goats;/*声明三个变量*/
以上声明创建了变量,但是没有给它们提供“值(value)”。
在前面的教程中,我们已经用了两种方法使变量获得“值”。
一种是赋值:
cows=500;。
另一种是使用scanf函数:
scanf("%d",&goats);。
下面我们来学习第三种方法。
3.初始化变量
初始化变量是指给变量赋初值:
声明变量的时候,在变量名的后面写上等号(=),然后写下你希望赋予变量的“值”。
例如:
inthogs=21;
intcows=32,goats=14;
intdogs,cats=94;
以上声明创建了变量,并且为这些变量分配了空间,同时也赋了初值。
注意,第三行中只有cats被初始化为94,而dogs没有被初始化!
如下图:
4.int常量
上面的例子中,21、32、14,以及94都是整数常量。
C语言中,整数常量的默认类型是int。
如果整数常量的大小超过了int的取值范围,那么编译器将会把这个整数常量当作longint类型来处理,这个我们后面还会讲到。
21、32、14和94都在int的取值范围之内,因此它们都是int常量。
5.输出int型数据
我们可以用printf函数来输出int型数据。
正如我们在前面的教程中看到的那样,占位符%d代表输出的是int型数据,它告诉printf函数在什么地方输出相应的int型数据。
%d也被称为格式限定符(formatspecifier),因为它指定了printf函数应该使用什么形式来输出数据。
printf函数的第一个参数只能是字符串,这个字符串被称为格式串(formatstring)。
格式串中有多少个%d,我们就应该相应地提供多少个int型参数给printf函数。
int型参数可以是int型变量,int型常量,以及结果为int型的表达式等。
例如:
intyear=2005;/*year是int型变量*/
printf("Todayis%d-%d-%d",year,9,20+9);/*20+9是加法表达式*/
保证格式限定符的数目和参数数目一致是我们的责任,编译器不负责捕捉这种错误!
例如:
#include
intmain(void)
{
intten=10,two=2;
printf("%dminus%dis%d",ten);/*少写了两个参数*/
getchar();/*等待用户按回车*/
return0;
}
这个程序可以通过编译,但是运行结果将会出乎意料,因为我们少写了两个参数。
标准规定,如果格式限定符的数目大于参数数目,则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
intmain(void)
{
intx=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();
return0;
}
这个程序的输出是:
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)shortint(可简写为short),和int一样,也是有符号整数
2)longint(简写:
long),有符号整数
3)longlongint(简写:
longlong),C99标准添加的类型,
有符号整数
4)unsignedint(简写:
unsigned),无符号整数,不能表示负数
5)unsignedlongint(简写:
unsignedlong),无符号整数,
不能表示负数
6)unsignedshortint(简写:
unsignedshort),无符号整数,
不能表示负数
7)unsignedlonglongint(简写:
unsignedlonglong),
C99添加的类型,无符号整数
8)所有没有标明unsigned的整数类型默认都是有符号整数。
在这些整数类型前面加上signed可以使读者更清楚地知道
这些是有符号整数,尽管有没有signed都表示有符号整数。
例如:
signedint等同于int。
一般我们把short称为短整型,把long称为长整型,把longlong称为超长整型,把int称为整型。
unsigned打头的那些整数类型统称为无符号整型。
例如:
我们称unsignedshort为无符号短整型。
以此类推。
2.声明方式
这些整数类型的声明方式与int类型的声明方式一样。
例如:
longintestine;
longjohns;
shortinterns;
shortribs;
unsignedints_count;
unsignedplayers;
unsignedlongheadcount;
unsignedshortyesvotes;
longlongago;/*C99特有*/
unsignedlonglongego;/*C99特有*/
如果您的编译器不支持C99标准,那就不能使用longlong和unsignedlonglong。
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的最小取值范围是-2147483647到2147483647。
也就是-(2^31-1)到(2^31-1)。
unsignedshort的最小表示范围和unsignedint一样,都是0到65535(2^16-1)。
unsignedlong的最小取值范围是0到4294967295(2^32-1)。
longlong的最小取值范围是-9223372036854775807(-(2^63-1))到9223372036854775807(2^63-1);unsignedlonglong是0到184********709551615(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位的。
使用unsignedint声明的变量只能表示非负整数(0和正整数)。
如果int是16位的话,那么unsignedint的表示范围是0到65535(2^16-1)。
这是因为unsigned不需要符号位,可以把16个位全都用于表示整数。
而int需要一个位作为符号位,用于表示正负,只有15个位用于表示整数。
目前,longlong一般64位,long是32位,short是16位,而int或者16位,或者32位。
具体某个编译器到底使用多少位来表示这些类型,我们可以用运算符sizeof来获取。
例如:
printf("%lu",(unsignedlong)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位整数,那就用longlong。
如果int是32位的话,那么使用short可以节省空间,不过您得确保您要处理的整数不会超出short的表示范围。
这种“节省”对内存大的计算机来说,是没什么意义的。
5.long型常量和longlong型常量
一般来说,整数常量是被当作int类型来存储的。
如果我们使用的整数常量超出了int的表示范围,C语言规定编译器自动使用unsignedint来处理这个常量。
如果unsigned也不足以表示这个常量的话,编译器就会用long。
如果还表示不了的话,那就依次用unsignedlong,longlong,unsignedlonglong。
如果unsignedlonglong也表示不了,那么编译器就没辙了。
注意:
longlong和unsignedlonglong是C99特有的。
例如:
如果int是16位的话,它就表示不了常量1000000。
编译器会使用long来处理这个常量,因为unsignedint也表示不了1000000。
同样,十六进制和八进制整数常量通常也是被作为int来处理。
但是,当我们使用的常量超出了int的表示范围后,编译器会依次使用unsignedint,long,unsignedlong,longlong和unsignedlonglong。
直到所使用的类型足以表示那个常量为止。
有时,我们使用的是较小的常量,但是我们希望这个常量被当作long来处理,这就需要在这个常量后面加上后缀l(小写字母l)或者L(大写字母L)。
我们应该避免使用l,因为l容易和数字1混淆。
例如:
整数常量7是被作为int来处理的,但整数常量7L(或者7l)是被作为long来处理的。
类似地,在整数常量后面加上后缀ll或者LL,这个常量就会被当作longlong来处理。
例如:
3LL。
如果想使用无符号整数常量的话,还要配合使用后缀u或者U。
例如:
2u,3U,4Lu,5ul,6LU,7LLU,8Ull,9uLL。
这些后缀也可以用于十六进制和八进制整数常量。
例如:
020L,010LL,0x30uL,0x40ull。
1.输出各种整数类型的变量
输出不同类型的整数,需要使用不用的格式限定符。
输出unsignedint类型的整数,要用%u。
输出long,要用%ld;如果要以十六进制或者八进制形式输出,那就用%lx(或者%lX)或者%lo。
注意:
虽然整数常量的后缀使用大写或者小写英文字母都没关系,但是它们格式限定符必须使用小写!
如果我们要输出short类型的整数,可以在%d中间加上前缀h,也就是%hd;同理,%ho和%hx(或者%hX)分别表示以八进制或十六进制形式输出。
前缀h和l可以和u组合,表示输出无符号整数。
例如:
%lu表示输出unsignedlong类型的整数;%hu表示输出unsignedshort类型的整数。
如果您的编译器支持C99,可以使用%lld和%llu分别表示输出longlong和unsignedlonglong。
下面我们来看一个输出各种类型整数的程序:
#include
intmain(void)
{
unsignedintun=3000000000;/*我使用的编译器int是32位的*/
shortend=200;/*而short是16位的*/
longbig=65537;
printf("un=%uandnot%d",un,un);
printf("end=%hdand%d",end,end);
printf("big=%ldandnot%hd",big,big);
printf("PressENTERtoquit...");
getchar();
return0;
}
使用Dev-C++编译运行这个程序输出结果如下:
un=3000000000andnot-1294967296
end=200and200
big=65537andnot1
PressENTERtoquit...
这个程序表明,错误使用格式限定符会导致意想不到的输出。
首先,错误使用%d来做无符号整型变量un的格式限定符,导致输出的是负数。
这是因为我的计算机使用相同的二进制形式来表示3000000000和-129496296,而计算机只认识二进制。
所以,如果我们使用%u告诉printf输出无符号整数,输出的就是3000000000;如果我们误用了%d,那么输出的就是一个负数。
不过,如果我们把代码中的3000000000改成96的话,输出就不会出现异常。
因为96没有超出int的表示范围。
然后,对于第二个printf,无论我们使用%hd还是%d,输出的结果都是一样的。
这是因为C语言标准规定,当short类型值传递给函数时,要自动转化成int类型值。
之所以转化成int,是因为int被设计为计算机处理效率最高的整数类型。
所以,对于short和int大小不同的计算机来说,把变量end转化成int类型再传递给函数,速度更快。
如此说来,h好像没有存在意义。
其实不然。
我们可以用%hd来看看较大的整数类型被截断成short类型的时候会是什么样的。
而第三个printf,由于误用%hd,导致输出是1。
这是因为,如果long是32位的话,65537的二进制形式便是00000000000000010000000000000001,而%hd命令printf输出short类型的值,从而导致printf只处理16位数据(假设short是16位的),最终导致输出1。
在前面的教程里,我们说过,保证格式限定符的数目和参数数目一致是我们的责任。
同样,保证格式限定符的类型和参数类型一致也是我们的责任!
正如上面所说的那样,错误使用格式限定符会导致意想不到的输出!
标准规定,如果任意参数和与其对应的格式限定符类型不一致,则printf的行为是未定义的;如果格式限定符本身就是非法的,则printf的行为也是未定义的。
2.整数溢出
首先请看以下程序:
#include
intmain(void)
{
/*32位int表示范围的上限和下限*/
inti=2147483647,j=-2147483648;
unsignedintk=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("PressENTERtoquit...");
getchar();
return0;
}
使用Dev-C++编译运行这个程序输出结果如下:
2147483647-2147483648-21474836482147483647
42949672950104294967295
PressENTERtoquit...
本例中,i+1是负数,j-1是正数,k+1是0,l-1是4294967295。
这是因为加减运算过后,它们的值超出了它们对应的那种整数类型的表示范围,我们把这种现象称为溢出。
unsignedint型变量的值如果超过了上限,就会返回0,然后从0开始增大。
如果低于下限,那么就会到达unsigned型的上限,然后从上限开始减小。
就好像一个人绕着跑道跑步一样,绕了一圈,又返回出发点。
一般,int型变量溢出的话,会变成负数,或者正数。
对于unsigned类型的整数,它们溢出时的情况一定和上面描述的一样,这是标准规定的。
但是标准并没有规定有符号整数溢出时会出现什么情况。
这里描述的有符号整数溢出时出现的情况是最常见的,但是在别的计算机,使用别的编译器,也可能出现不同的情况。
补码运算,答案满意再追100,3天内有效
悬赏分:
50|解决时间:
2009-2-508:
56|提问者:
lishen226
X=76,则[X]补=?
[X]补=80H,则X=?
[X]补=98H,则[X]补/2=?
X=78,Y=-83,则[X+Y]补=?
问题补充:
我教朋友计算机呢,遇到这几个题,都是N年前学的,都忘光了,最好有个解题步骤,谢谢了!
最好能附上补码原码转换的一些知识点,比如负数怎么处理。
最佳答案
对正数而言:
[X]原=[X]反=[X]补
对负数而言:
[X]反=[X]原符号位不变,尾数按位变反。
[X]补=[X]反末位加“1”,
或[X]补=[X]原符号位不变,尾数按位变反后再加“1”。
[X]原=[X]反符号位不变,尾数按位变反。
[X]原=[[X]补]补即补码的补码,也就是说对负数的补码再求补得到原码。
X=76(都用一个字节表示)
则[X]补=[X]原=01001100B
[X]补=80H
这是补码的一个特殊情况-128,八位原码和反码都是表示不了这个数的。
[X]补=(10000000)B按位取反加1后有溢出,但计算机中该补码认定为-128,因此X=-(10000000)B=-128
[X]补=98H
[X]补=(10011000)B
如果计算机内做除以2的操作,因为计算机本身是将整个码当二进制数对待的,并不区分是什么码(也就是说计算机只认二进制数),所以[X]补/2是将[X]补每位都算术右移一位(包括符号位)。
[X]补/2=(01001100)B=4CH。
如果是单求补码值的一半(除2),则可理解为符号位保持不变的算术右移一位,[X]补/2=(11001100)B=CCH。
X=78,Y=-83
[X]补=(01001110)B
[Y]补=(10101101)B
[X+Y]补=[X]补+[Y]补=(01001110)B+(10101101)B=(11111011)B=FBH
∙补码
补码举例
补码(two'scomplement)
1、在计算机系统中,数值一律用补码来表示(存储)。
主要原因:
使用补码,可以将符号位和其它位统一处理;同时,减法也可按加法来处理。
另外,两个用补
码表示的数相加时,如果最高位(符号位)有进位,则进位被舍弃。
2、补码与原码的转换过程几乎是相同的。
求给定数值的补码表示分以下两种情况:
(1)正数的补码
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 语言 基本 数据类型 整型 int 用法 详解