第三章 基本数据类型.docx
《第三章 基本数据类型.docx》由会员分享,可在线阅读,更多相关《第三章 基本数据类型.docx(30页珍藏版)》请在冰豆网上搜索。
第三章基本数据类型
第三章基本数据类型
本章的重点、难点:
•理解C语言基本数据类型的概念、特点、初始化、输入输出及运算方法。
•运算符和表达式的应用
学习目标:
•掌握整型、实型和字符型这三种基本数据类型变量的定义、初始化、输入输出方法。
•掌握运算符和表达式的应用方法。
•理解C语言数据存储、运算的特点。
关于程序的定义,著名的计算机科学家沃思(NikiklausWirth)曾提出一个公式:
程序=数据结构+算法。
即一个程序应该包括数据结构和算法两个方面:
(1)数据结构(datastructure):
在程序中对数据的类型及数据组织形式的描述,是计算机要加工的对象。
(2)算法(algorithm):
在程序中对解决问题所需方法和步骤的描述,是对操作步骤的描述。
程序设计就像制作精美的工艺作品,数据就是原材料,而算法就是加工步骤。
对同样的原材料,按照不同的步骤去加工,生产的工艺品就会不同。
原材料也不会永远只需要一种,为了完成一个工艺品所需的原材料可能是多种类型的,各种原材料还可能需要按照一定的联系组织在一起使用。
在实际的程序设计中,选择适当的算法和数据是非常重要的,C语言提供了多种类型的原材料供我们在程序设计中选用,C语言的数据结构就是以数据类型的形式表现的。
C语言的数据类型如下:
在程序设计中,数据是使用各种量来表示的,比如整型量、实型量。
在程序的运行过程中,其值不能改变的量我们称之为常量。
例如:
100是整型常量,1.2是实型常量,‘c’是字符型常量、由#define定义的符号常量等等。
相应的,其值可以改变的量我们称之为变量。
变量应该有一个名字即变量名、有具体的值即变量值,而且这个值可以改变,但名字不能改变。
在计算机内存中应该同时存储变量名和变量值,其存储结构如图3-1:
图3-1图3-2图3-3
例如:
变量值为85,变量名为chengji,其存储结构如图3-2,在程序运行过程中,变量名chengji代表的变量值可以发生变化,由85变化为90,其存储结构如图3-3。
用来标识变量名的字符序列称为标识符(identifier)。
标识符必须遵守一定点规则,C语言规定:
(1)标识符只能由字母、数字和下划线三种字符组成,且第一个字符必须为字母或下划线。
例如:
chengji,_kucun,a,i,_6,Fushu,_ti_9_1,shangping6等等均为合法标识符。
(2)标识符区分大小写。
例如chengji和CHENGJI是两个不同的名字。
(3)ANSIC标准没有规定标识符的长度限制,但各个C编译系统都有自己的规定。
例如TurboC取32个字符,即32个有效字符,超过32位的部分不识别,而IBMPC的MSC取8个字符,即8个有效字符,超过8位的部分不识别。
在实际应用中,建议标识符的长度不要超过8个字符,命名时应该做到“见名知意”,增加程序的可读性。
3.1整型数据
在程序中如果需要处理整数,可以考虑使用整型数据表示该数,整型数据有整型常量和整型变量之分。
在C语言中,整型常量可以用以下三种形式表示:
(1)十进制整数。
例如-128,0,85等。
(2)以0开头表示的八进制整数。
例如0135表示八进制的135,对应的十进制数为:
1×82+3×81+5×80,即91。
(3)以0x开头表示的十六进制整数。
例如0x135表示十六进制的135,对应的十进制数为:
1×162+3×161+5×160,即309。
3.1.1整型变量定义
在C语言中,任何变量都必须先定义再使用,在定义时必须指明变量的类型。
整型变量定义方法为:
格式:
int变量名列表;
例如:
inti;/*定义了一个整型变量,变量名为i*/
intshuxuedm,yuwendm,yingyudm;/*定义了三个整型变量,取值是整型数*/
第二行程序等价于下列三行程序:
intshuxuedm;/*定义了一个整型变量,取值是整型数*/
intyuwendm;/*定义了一个整型变量,取值是整型数*/
intyingyudm;/*定义了一个整型变量,取值是整型数*/
上述三行程序定义了三个整型变量,变量名分别是:
shuxuedm,yuwendm,yingyudm,取值都是整型数。
它告诉计算机在内存里开辟3个存储区域,叫shuxuedm,yuwendm,yingyudm,分别可以用来存放三个整型数,如同定好了三个学号,等待分配给即将来报到的学生。
当给变量赋值以后,就可以通过变量名来使用变量所代表的整数值。
每个int型整型值占2个字节,以ASCII码二进制形式存储在内存里,如下图3-4。
图3-4
说明:
(1)int是关键字,也叫类型名,相当于指令。
(2)在类型名int和变量名列表间至少要有一个空格。
(3)一次可以定义多个相同类型的变量,各个变量用“,”分隔。
(4)最后一个变量名之后必须用“;”结尾。
(5)变量定义必须在变量使用之前。
(6)建议一行定义一个变量,这样可以方便添加注释,增加程序的可读性。
3.1.2整型变量的初始化
初始化即给变量赋初始值,有了具体值的变量才能参与运算。
如同学生学号只有指向具体的某一位学生才有意义。
整型变量初始化一般有两种方法:
(1)先定义,然后初始化:
intshuxuedm,yuwendm,yingyudm;/*先定义三个变量*/
shuxuedm=1;/*初始化赋值运算,把整型数“1”赋给变量shuxuedm*/
yuwendm=2;/*初始化赋值运算,把整型数“2”赋给变量yuwendm*/
yingyudm=3;/*初始化赋值运算,把整型数“3”赋给变量yingyu*/
(2)边定义边初始化
inti=15;/*边定义,边初始化赋值*/
intshuxuedm=1,yuwendm=2,yingyudm3;/*边定义,边初始化赋值*/
对于变量shuxuedm,yuwendm和yingyudm经过赋值后内存存储结构如图3-5:
图3-5
说明:
(1)计算机内存里的数及其他信息不是以十进制数的形式存储的,要转换成二进制数才能存储,前面例子中表示的内存存储结构图仅为示意图,实际int型数在内存里占2个字节,共16位,以16位二进制数存储。
如整型数3的真实存储形式如图3-6:
0
0
0
0
0
0
0
0
0
0
0
0
1
1
0
0
图3-6
(2)第一次给变量赋值叫变量初始化,任何变量必须先定义,再初始化,然后才能使用。
(3)在同一段程序里,一个变量只能定义一次,不能重复定义。
(4)TurboC要求一次性把需要的变量定义完,再使用变量进行数据处理,不允许定义一个处理一个,也就是说,数据定义部分和数据处理部分要分开写。
例如下列两段程序中,程序段1是不合法的,程序段2是合法的。
程序段1:
main()
{
inta;/*定义变量*/
printf(“%d”,a*a);/*使用变量*/
intb;/*又定义变量,非法*/
printf(“%d”,b*b);
}
程序段2:
main()
{
inta;
intb;/*先定义所有变量*/
printf(“%d”,a*a);/*根据需要使用变量,合法*/
printf(“%d”,b*b);
}
3.1.3整型数的算数运算
整型数的算术运算有+,-,*,/,%,其意义和使用方式与数学中一样。
例3-1 整型数算数运算。
#include
main()
{
inta,b,c;
inttotal,average,remainder;
a=80;
b=90;
c=86;
total=a+b+c;
average=total/3;
remainder=total%3;
printf(“%d,%d,%d”,total,average,remainder);
}
程序运行结果如下:
256,85,1
说明:
(1)只有整型数才有求余运算。
如上例中remainder=total%3。
(2)整型数除以整型数其商一定是整型数。
如上例中average=total/3,再例如1/2=0而不是0.5。
(3)整型数不等同与整数,在计算机里,整型数有一定的范围限制,超出该范围程序就会出错,这称之为溢出。
例如int型整型数取值范围为-32768~32767。
(4)整型变量还有longint、unsignedint、shortint、unsignedint、unsignedlongint类型,都是用来表示整型数,但表示的取值范围不同,具体如下表3-1:
表3-1ANSI标准定义的整数类型
类型
比特数
取值范围
[signed]int
16
-32768~32767即-215~(215-1)
Unsignedint
16
0~65535即0~(216-1)
[signed]short[int]
16
-32768~32767即-215~(215-1)
Unsignedshort[int]
16
0~65535即0~(216-1)
long[int]
32
-2147483648~2147483647即-231~(231-1)
unsignedlong[int]
32
0~4294967295即-215~(215-1)即0~(232-1)
3.1.4整型数据的输入和输出
3.1.4.1整型数据的输入
整型数据的输入是指在程序运行过程中,用户给一个整型变量指定值的操作。
它的语句格式为:
(1)scanf(“%d”,&zhengshu1);
在程序运行过程中等待用户输入一个整型数,并把输入的整型数值存放在变量zhengshu1
里。
(2)scanf(“%d%d%d”,&zhengshu1,&zhengshu2,&zhengshu3);
在程序运行时,等待用户输入3个整型数,三个数用回车(Enter键)或空格隔开,输入完三个数后需用回车表示输入结束。
这时计算机就把用户输入的三个整型数分别存储在zhengshu1,zhengshu2和zhengshu3内。
例如:
inta,b,c;
scanf(“%d%d%d”,&a,&b,&c);
在程序运行中,用户可以输入:
2□3□4
或者2
3
4
都实现了给a,b,c赋值,即a=2,b=3,c=4。
内存存储示意图如下图3-7
图3-7
说明:
(1)scanf()被称为输入函数,其功能就是给变量赋值。
关于函数请参见函数相关章节。
(2)“%d”是控制符,表示等待输入一个十进制整型数,相应的,有几个“%d”就代表等待输入几个十进制整型数。
(3)控制符有几个,逗号后面就必须有几个变量,变量名前必须加“&”,如语句scanf(“%d%d%d”,&a,&b,&c)中的“,&a,&b,&c”。
(4)控制符之间可以有一定的格式,如写成scanf(“%d,%d,%d”,&a,&b,&c)也表示等待输入三个十进制整数,但三个数之间必须用逗号隔开,第三个数输入后按回车表示输入结束。
(5)scanf()输入函数在使用前必须在程序中包含头文件,即在main()前面加:
#include
3.1.4.2整型数据的输出
整型数据的输出是指把整型数的值输出显示在显示器屏幕上。
它的常见语句格式为:
(1)printf(“%d”,zhengshu1);/*把整数zhengshu1的值显示在显示器屏幕上*/
(2)printf(“%d%d%d%d”,zhengshu1,zhengshu2,zhengshu3,5);
printf(“%d,%d,%d,%d”,zhengshu1,zhengshu2,zhengshu3,5);
printf(“%d%d%d%d”,zhengshu1,zhengshu2,zhengshu3,5);
以上三句的功能都是把整数zhengshu1,zhengshu2,zhengshu3的值和常整数5输出到显示器屏幕上。
若zhengshu1=2,zhengshu2=3,zhengshu3=4,则第一句显示结果是“2345”,第二句显示结果为“2,3,4,5”,第三句显示结果为“2□3□4□5”。
请读者注意观察三句输出的差异。
说明:
(1)printf()被称为输出函数,其功能就是把变量值输出显示到显示器屏幕上。
(2)与scanf()函数类似,“%d”为控制符,一个%d占的位置可以显示一个int整型数,有几个%d,其后就应该有几个整型数等待输出。
(3)printf()还可以输出一句话,其格式如下:
printf(“Nihao,tongxuemen!
\n”);
要显示的话用双引号括起来。
注意符号\n,它是换行控制符,即计算机执行到\n时,就在下一行开头开始显示其余的内容,不管上一行是否已显示满。
如果没有换行符\n,则一行显示满后才自动换行。
(4)因为程序遇到scanf()会等待用户输入,建议在scanf()前加上一个printf()语句用来提示用户输入。
例如:
printf(“请输入两个整型数,用空格分开:
\n”);
scanf(“%d%d”,&a,&b);
(5)与scanf()输入函数一样,printf()在使用前必须在程序中包含头文件,即在main()函数前面加上:
#include
例3-2判断下列语句的输出结果
(1)printf(“%d%d%d”,2,3,4);
输出结果为:
234
(2)printf(“%d,%d,%d”,2,3,4);
输出结果为:
2,3,4
(3)printf(“a=%d,b=%d,c=%d”,2,3,4);
输出结果为:
a=2,b=3,c=4
(4)printf(“a=%d\nb=%d\nc=%d\n”,2,3,4);
输出结果为:
a=2
b=3
c=4
思考:
把上述题中%d换成%4d或%6d显示效果会如何?
例3-3在屏幕上提示并允许用户输入一个100以内的整型数,然后输出该整型数的值并换行输出它的平方值,在输出数值时做出相应的提示“你输入的数是:
”以及“它的平方是:
”。
算法思考:
(1)定义变量a来表示用户要输入的数,定义变量b准备用来存储a的平方值,因a的值小于100,其平方小于10000,可以使用整型变量来存储这两个值;
(2)提示用户输入数“请输入一个小于100的整型数:
”;
(3)等待用户输入数;
(4)计算a的平方,将其赋给b;
(5)显示“你输入的数是”及该数的值;
(6)显示“它的平方是:
”及b的值。
程序代码:
#include
main()
{
inta;/*用来存储将输入的数*/
intb;/*用来存储a的平方值*/
printf("\n请输入一个小于100的整型数:
");
scanf("%d",&a);
b=a*a;
printf(“你输入的数是:
%d\n”,a);
printf(“它的平方是:
%d\n”,b);
/*上两句可写成一句:
printf(“你输入的数是:
%d,\n它的平方是:
%d\n”,a,b);*/
}
在程序运行后输入任意100以内的整型数,例如30,运行结果如下:
请输入一个小于100的整型数:
30
你输入的数是:
30
它的平方是:
900
例3-4运行下面程序并分析程序的异常情况
#include
main()
{
inta,b;
a=32767;
b=a+1;
printf("\na=%d,a+1=%d\n",a,b);
a=-32768;
b=a-1;
printf("\na=%d,a-1=%d\n",a,b);
}
程序运行结果:
a=32767,a+1=-32768
a=-32768,a-1=32767
说明:
超出数据类型表示范围时会发生溢出,但运行时程序并不会报错。
例3-5编写一个程序求任意两个整型数之和
算法思考:
(1)定义两个整型变量存储参加运算的整型数:
intjiashu1,jiashu2;
(2)定义一个变量用来存储两个数的和:
longinthe;思考:
为什么用longint类型?
(3)允许用户输入两个整型值,分别赋给jiashu1和jiashu2;
(4)求和,将结果赋给he;
(5)输出he的值。
程序代码:
#include
main()
{
intjiashu1,jiaoshu2;/*jiashu1,jiashu2来表示任意两个数*/
longinthe;/*he准备存储两数之和*/
printf(“请输入第一个数jiashu1:
”);/*提示用户输入整型数*/
scanf(“%d”,&jiashu1);
printf(“\n请输入第二个数jiashu2:
”);
scanf(“%d”,&jiashu2);
he=jiashu1+jiashu2;
printf(”\n%3d+%3d=%4ld”,jiashu1,jiaoshu2,he);
}
程序运行结果:
请输入第一个数jiashu1:
35
请输入第二个数jiashu2:
60
□35+□60=□□95
说明:
(1)printf()的格式控制符用到%3d,其作用是让每个整型数占3个位置,若整型数位数超出3位则自动全部显示,若不够3位则左边会补空格,右对齐显示。
思考:
printf()的格式控制符如果改为“-%3d”会怎样显示?
(2)格式控制符%ld是用来显示longint型的整型数。
3.2实型数据
在程序中如果需要处理实数,则可以考虑用实型数据表示该数。
实型数也称浮点数,实型数据也有实型常量和实型变量之分。
在C语言中,实型常量可以用以下两种形式表示:
(1)带小数点的十进制小数形式。
如85.5,0.0,-35,.125等。
(2)带e(或E)的指数形式。
如25e3(或25E3)表示25×103。
注意:
e(或E)之前必须有数字,e(或E)之后必须是整数。
3.2.1实型变量的定义
格式:
float变量名列表;
或者
double变量名列表;
一般把float型实数称单精度型实数,double型实数称双精度型实数。
双精度(double)实型变量比单精度(float)实型变量取值范围大。
另外,还有一种长双精度(longdouble)型实数,它们的取值范围如下表3-2:
表3-2TurboC实型数据
类型
比特数
有效数字
取值范围
float
32
6~7
10-37~1038
double
64
15~16
10-307~10308
longdouble
128
18~19
10-4931~104932
例如:
doublezongcj;/*定义了一个实型变量,取值是实型数*/
floatshuxuecj,yuwencj;/*定义了两个实型变量,取值是实型数*/
上面的程序等价于下列三行:
floatshuxuecj;
floatyuwencj;
doublezongcj;
以上程序定义了三个实型变量,变量名分别是:
shuxuecj,yuwencj,zongcj,取值都是实型数。
它告诉计算机在内存里开辟3个存储区域,叫shuxuecj,yuwencj,zongcj,分别用来存放三个实型数。
今后在程序里通过引用变量名来使用变量的值。
它们在内存中的存储结构如下图3-8:
图3-8
说明:
(1)float和double是关键字,也叫类型名,相当于指令。
(2)在类型名(float或double)和变量名列表间至少要有一个空格。
(3)一次可以定义多个相同类型的变量,各个变量用“,”分隔。
(4)最后一个变量名之后必须用“;”结尾。
(5)变量定义必须在变量使用之前。
3.2.2实型变量的初始化
实型变量初始化一般有两种方法:
(1)先定义,然后赋值:
floatshuxuecj,yuwencj;/*定义两个实型变量*/
doublezongcj;/*定义一个实型变量*/
shuxuecj=91.8;/*初始化赋值运算,把实型数“91.8”赋给变量shuxuecj*/
yuwencj=87.5;/*初始化赋值运算,把整型数“87.5”赋给变量yuwencj*/
zongcj=179.3;/*初始化赋值运算,把整型数“179.3”赋给变量zongcj*/
(2)边定义边赋值
floatshuxuecj=91.8,yuwencj=87.5;/*边定义,边初始化赋值*/
doublezongcj=179.3;/*边定义,边初始化赋值*/
经过赋值后内存的存储结构示意图如图3-9:
图3-9
说明:
(1)实型数在在内存中是以指数形式存储的。
如实型数91.8在内存中的存储形式示意图为图3-10:
+
.918
2
图3-10
图3.10中三个部分分别为符号部分、小数部分和指数部分。
在存储实型数的32位中,有多少位用来表示小数部分及多少位用来表示指数部分就分别决定了数值的精度和取值范围。
表示小数部分的位越多则精度越高,表示指数部分的位越多则取值范围越大。
注意,图3.10为存储示意图,在计算机里,这三个部分依然是以二进制存储的。
float型数在内存里占4个字节,共32位。
Double占8个字节64位。
(2)任何变量必须先定义,再赋值,然后才能引用。
(3)可以给实型变量赋整型值,在内存里会将该整型值自动存储成实型。
比如:
inta=2;
floatb=2;
以上两句都取值2,但在内存里a为整型占2字节,b为实型占4字节。
3.2.3实型数据的算术运算
实型数据的算术运算有+,-,*,/,%,其意义和使用方式与数学中一样。
这里需要说明的是:
(1)实型数与实型数进行算数运算,其结果为实型数。
(2)实型数与整型数进行算数运算,其结果是实型数。
例如:
1.0/2=0.5;
(3)由于实型数的精度是有限的,在运算中有效位以外的数字会被直接舍去,因此会产生一定的误差。
例如:
(2.0/3)*3结果并不等于2.0。
(4)许多C编译系统将实型常量默认为双精度数来处理,这时可以在常量的后面加上f(或F),以使系统按单精度数处理,这样可以提高运算效率。
3.2.4实型数据的输入和输出
3.2.4.1实型数据的输入
实型数据的输入是指在程序运行过程中,用户给一个实型变量指定值的操作。
它的语句格式为:
(1)floatzongcj1 ;/*定义实型变量zongcj1 */
scanf(“%f”,&zongcj1);
在程序运行过程中等待用户输入一个float类实型数,并把该值存在zongcj