1、第2章 C语言基础,2.1 数据类型 2.2 标识符、常量与变量 2.3 基本运算 2.4 数据类型转换 2.5 程序举例,2.1 数据类型,2.1.1 数据类型概述,整型(int),数据类型,基本类型,整型,单精度型(float),字符型(char),长整型(long),短整型(short),实型,双精度型(double),枚举类型(enum),共用体类型(union),构造类型,结构体类型(struct),数组类型,空类型(void),指针类型(*),2.1 数据类型,2.1.2 整型 归纳起来,C语言定义了6种整型,分别是: 基本整型 int 无符号基本整型 unsigned int 短
2、整型 short或short int 无符号短整型 unsigned short或unsigned short int 长整型 long或long int 无符号长整型 unsigned long或unsigned long int C语言没有规定各种整数类型的表示范围,即没有规定各种整数的二进制编码长度(数据在内存中所占的位数)。,2.1 数据类型,表中列出了一般PC机上规定的整数类型及相关数据。【注意】在Visual C+ 6.0中,基本整型(含无符号基本整型)与长整型(含无符号长整型)在内存中所占的字节数以及表示的取值范围对应相同。,2.1 数据类型,2.1.3 实型 C语言中实型数据又
3、称浮点型数据。Turbo C提供了三种表示实数的类型: 单精度浮点数类型,简称浮点类型 float双精度浮点数类型,简称双精度类型 double长双精度类型 long double 实型的相关规定,2.1 数据类型,2.1.4 字符型 字符类型的数据包括计算机所用编码字符集中的所有字符。常用的ASCII字符集包括所有大小写英文字母、数字、各种标点符号字符,还有一些控制字符,一共128个。扩展的ASCII字符集包括ASCII字符集中的全部字符和另外的128个字符,总共256个字符。 字符类型的数据在内存中存储的是它的ASCII码值,一个字符通常占用一个字节的内存空间。 除了占用的存储空间不同(因
4、而数据的取值范围不同)以外,字符数据与整型数据是相似的。为了方便处理,C语言规定字符类型与整型基本一致,即也有有符号和无符号两种类型。,2.1 数据类型,字符类型的相关规定。由于ASCII码字符的取值范围是0127,因此,既可以用char类型表示,也可以用unsigned char类型表示;扩展ASCII码字符的取值范围是0255,因此,在128255范围内的扩展ASCII码字符只能用unsigned char类型表示。,2.2 标识符、常量与变量,2.2.1 标识符 1.标识符 具体命名规则如下: (1) 标识符的只能由下划线“_”、数字09与26个大小写字母(az,AZ)构成。Turbo
5、C最多识别32个字符,Microsoft C最多识别8个字符。 (2) 标识符的首字符必须是字母或下划线“_”而不能是数字或其它符号。 (3) C语言中大小写字母是敏感的,即在标识符中,大写字母和小写字母代表不同的意义。例如:Name和name是两个不同的标识符。 (4) 标识符不能使用系统关键字,因为关键字是系统的保留字,它们已有特定的含义。,2.2 标识符、常量与变量,2.关键字 所谓关键字是指系统预定义的保留标识符,又称之为保留字。它们有特定的含义,不能再作其它用途使用。ANSI C定义的关键字共32个:,2.2 标识符、常量与变量,2.2.2 常量 1.整型常量 (1) 十进制整数:如
6、154、565、-6523。 (2) 八进制整数:以0开头的数是八进制数。如0123表示八进制数的(123)8,等于十进制数83。 (3) 十六进制整数:以0x开头的数是十六进制数。如0x4a即(4a)16,等于十进制数74。 在上述方法表示的整数后面附一个字母l或L作后缀,即可表示该数据的类型是长整型的。例如-63L、0123LU、0x4aL等分别表示十进制有符号长整型数、八进制无符号长整型数和十六进制有符号长整型数。,2.2 标识符、常量与变量,2.实型常量 实型常量只能用十进制形式表示,不能用八进制和十六进制形式表示。 (1) 小数形式:由数字和小数点组成,如3.1415926、 -0.
7、12、.4、3.等都是实数。 (2) 指数形式:如1.8e5或1.8E5都代表1.8x105。但注意字母e(或E)之前必须有数字,且e后面指数必须为整数,如e3、2.1e3.2、e等都不是合法的指数形式。 3.字符常量 字符型常量是由一对单引号括起来的单个字符构成,例如,a,b,1等都是有效的字符型常量。,2.2 标识符、常量与变量,C语言中的常用转义字符及这些字符的含义,2.2 标识符、常量与变量,4.字符串常量 字符串常量是由一对双引号括起来的字符序列组成的,例如“abc”、“a”等都是字符串常量。 字符串常量与字符常量的区别: (1) 字符常量由单引号括起来,字符串常量由双引号括起来。
8、(2) 字符常量占一个字节的内存空间。字符串常量在内存中存储时由系统自动在存储的所有字符尾部添加串结束标记0,所以,字符串常量占的内存字节数等于字符串中字符所占的字节数加1。注意不要将单个字符组成的字符串常量与字符常量混淆。不能把一个字符串常量赋给一个字符变量。,2.2 标识符、常量与变量,5.符号常量 符号常量就是使用符号代表常量。 C语言中允许用标识符定义一个常量,这种常量定义在C语言中被称之为“宏定义” 。 2.2.3 变量 一个变量有3个相关的要素: 变量名; 变量的存储单元; 变量(存储单元存放)的值。,2.2 标识符、常量与变量,1.变量的定义和赋值 C语言要求程序中使用的每个变量
9、都必须先定义,然后才能使用。定义变量需要用变量定义语句进行,其形式为: 类型 变量名=初值,变量名=初值,; 例如:int a;int x,y,min;int m,n=3,w=5; 若对定义的多个变量赋相同的初值,不能采用连续赋初值的形式,如 int a=b=c=5,必须采用形式: int a=5,b=5,c=5。 【注意】除了不能用关键字做变量名外,可以用任何标识符作为变量名 。,2.2 标识符、常量与变量,2.整型数据的存储 short int型补码为16位二进制数,它表示一个有符号整数,其特点是:当首位为0时表示一个正数,当首位为1时表示一个负数。正数的补码与其原码相同,而负数的补码为其
10、对应的正数的反码加1。如:+4补= 0000 0000 0000 0100-4补= 1111 1111 1111 1100 一个用补码表示的二进制数,最高位为符号位,当符号位为“0”(即正数)时,其余位即为此数的二进制值;但当符号位为“1”(即负数)时,其余位不是此数的二进制值,应把它们按位求反,且在最低位加1,才是它的二进制值。如:X补= 1111 1111 1111 1101 则X= - 000 0000 0000 0011 = -3,2.2 标识符、常量与变量,3.实型数据的存储 实型数据是按指数形式存储的。以微机中存储float型数据为例,float型数据在内存中占据4个字节即32位二
11、进制信息,分别存放符号位、规格化的尾数、阶符位和阶码。 例如,实数-32.28E-20的存储情况如图所示。,4.字符型数据的存储用一个字节(8位二进制信息)存储字符类型数据。对于无符号字符类型(unsigned char)数据直接存放ASCII码或扩展ASCII码。对于有符号字符类型(char)的数据也是用补码存储的。,2.3 基本运算,2.3.1 算术运算 1.基本算术运算符 C语言规定: (1) %运算符仅用于整型变量或整型常量的运算,a%b的结果为a除以b的余数,余数的符号与被除数相同。 (2) +、-、*、/ 运算符的两个操作数既可以是整数,也可以是实数。当两个操作数均是整数时,结果仍
12、是整数;若参加运算的两个操作数中有一个是实数,则结果为double型。 (3) 当对两个整型的数据相除时结果为整数。但是如果除数或被除数中有一个为负数,则舍入的方向是不固定的。如:-5/3在有的机器上得到结果-1,有的机器则给出结果-2。多数机器采取“向零取整”方法,即-5/3=-1,取整后向零靠拢。,2.3 基本运算,2.算术表达式 (1) 算术表达式定义 由算术运算符、括号以及操作对象组成的符合C语言语法规则的表达式称为算术表达式。如:a+b-c/d*(a-c) 。 (2) 优先级和结合性 在表达式求值时,先按运算符的优先级别高低次序执行。若一个运算对象两侧的运算符的优先级别相同,如a-b
13、+c,则按规定的“结合方向”处理。 算术运算符的结合方向为“自左至右”,又成为左结合性,即先左后右,因此b先与减号结合,执行a-b的运算,再执行加c的运算。,2.3 基本运算,3.自增、自减运算符 既可以放在操作数前,也可以放在操作数后,并且操作对象只能是变量,不能是常量或表达式。 如 i+,i- /* 表示在使用i值之后将i的值加(减)1 */ +i,-i /* 表示在使用i值之前将i的值加(减)1 */ 例如:设i的原值为5,则执行下面的赋值语句: j=i+; /* 先将i的值赋给j,i再自增1,赋值语句执行完 后i的值为6,j的值为5 */ j=+i; /* 先将i的值自增1,再赋给j,
14、赋值语句执行完 后i的值为6,j的值为6 */,2.3 基本运算,【注意】 (1) 自增自减运算符的优先级较高,和单目运算符相同。其结合方向是“自右向左”(右结合性)。 考虑表达式-i+,由于“-”和“+”优先级相同,均为右结合性,因此相当于-(i+)。 (2) 尽管自增自减运算符给程序员带来了方便,但同时也带来了副作用。 例如,“printf(“%d,%dn“,i,i+);”在不同的编译环境下结果有可能不同。若i的值为3,则结果可能是“3,3”,也可能是“4,3”。 (3) C编译在处理时尽可能多地自左而右将若干个字符组成一个运算符(在处理标识符和关键字时也按同一原则处理),如i+j,将解释
15、为(i+)+j,而不是i+(+j)。,2.3 基本运算,2.3.2 赋值运算 1.赋值运算符 C语言中,赋值被认为是一种运算,由赋值运算符将一个变量和一个表达式连接起来的式子称为赋值表达式。其形式是:赋值表达式的值也可以再赋给其它变量,如:a=(b=3+5)。 【注意】赋值运算符“=”不同于数学中使用的符号,它没有“相等”的含义。如果赋值运算符两侧的数据类型不同时,在赋值时要进行类型转换。,2.3 基本运算,2.复合赋值运算符 C语言允许在赋值运算符“=”之前加上其他运算符以构成复合的赋值运算符。例如: a+=5; 等价于 a=a+5; a*=b+5; 等价于 a=a*(b+5); a%=5;
16、 等价于 a=a%8; 在C语言中,可以使用的复合赋值运算符有: +=,-=,*=,/=,%=,=,&=,=,|= 3.运算符的优先级和结合性 赋值运算符和复合赋值运算符的优先级相同,且都具有右结合性。,2.3 基本运算,【例2-1】分析下面程序的运行结果 /* EX2-1.C */ main() int a=12; a+=a-=a*a; printf(“%d n“,a); ,2.3 基本运算,2.3.3 位运算 运算规则,2.3 基本运算,1.按位取反 【格式】x 【例2-2】分析下面程序的运行结果 /* EX2-2.C */ main() unsigned char x=56,y;y=x;
17、printf(“%d n“,y); 其运算过程为:,56(00111000),56(00111000),199(11000111),2.3 基本运算,2.按位与 【格式】x 其运算过程为:56: 00111000&157: 1001110100011000,24,2.3 基本运算,3.按位或 【格式】x | y 【例2-4】分析下面程序的运行结果 main() unsigned char x=56,y=157,z; z=x|y; printf(“%d n“,z); 其运算过程为:56: 00111000| 157: 1001110110111101,189,2.3 基本运算,4.按位异或 【格
18、式】x y 【例2-5】分析下面程序的运行结果。 main() unsigned char x=56,y=157,z; z=xy; printf(“%d n“,z); 其运算过程为:56: 00111000 157: 10011101,10100101,165,2.3 基本运算,5.左位移 【格式】x要位移的位数 【功能】把操作对象的二进制数向左移动指定的位,并在右面补上相应的0,高位溢出。 【示例】如x=00001111,y=x2,则y=00111100。 【注意】左移会引起数据的变化,具体地说,左移一位相当于对原来的数值乘以2。左移n位相当于对原来的数值乘以2n。但此结论只适用于该数左移被
19、溢出舍弃的高位中不包含1的情况,有溢出的情况下,左移n位相当于对原来的数值乘以2n 后取28 (两字节为216,四字节为232)为模。,2.3 基本运算,6.右位移 【格式】x要位移的位数 【功能】把操作对象的二进制数向右移动指定的位,移出的低位舍弃;高位则: (1) 对无符号数和有符号中的正数,补0,称为“逻辑右移” ; (2) 有符号数中的负数补1,称为“算术右移”。 【示例】如x=01010001,y=x2,则y=00010100;如x=11010100,y=x2,则y=11110101。,2.3 基本运算,【注意】右移会引起数据的变化,具体说,右移一位相当于对原来的数值除以2。右移n位
20、相当于对原来的数值除以2n。 如上例010100012得00010100,即是81/4=20。 负数高位补1的目的也是右移n位相当于对原来的数值绝对值除以2n ,而负号不变 。 如上例110101002得11110101,即是-44/4=-11。 但上述结论只适用于该数右移被溢出舍弃的低位中不包含1的情况,若包含1,右移n位相当于对原来的数值除以2n后再取整 (如81/4=20的例子);而对于负数,右移舍弃的低位使得补码减少一个小数,商的绝对值则向增大的方向取整,如: 110100012得11110100 ,即-472得-12,而-47/4=-11,2.3 基本运算,【说明】 (1) 复合赋值
21、运算符 除按位取反运算外,其余5个位运算符均可与赋值运算符一起,构成复合赋值运算符: &=、|+、=、=。 (2) 不同长度数据间的位运算低字节对齐,短数的高字节按最高位补位: 对无符号数和有符号中的正数,补0; 有符号数中的负数,补1。 2.3.4 逗号运算 1.逗号运算符其一般形式为: 表达式1,表达式2,2.3 基本运算,逗号表达式的求值过程是:先求表达式1的值,再求表达式2的值,表达式2的值就是整个逗号表达式的值。 一个逗号表达式可以与另一个表达式构成一个新的逗号表达式。 例如: (a=5-3,a*5),a+15 逗号表达式的一般形式可以扩展为:表达式1,表达式2,表达式3,表达式n
22、2.运算符的优先级和结合性 逗号运算符是所有运算符中级别最低的。 逗号表达式的结合性为自左向右的。 【注意】并不是任何地方出现的逗号都是作为逗号运算符。,2.3 基本运算,【例2-6】分析下面程序的运行结果。 main() int a=5,b=6,c=1; printf(“%d %dn“,(+a,b+),c+2); ,2.4 数据类型转换,2.4.1 类型自动转换 转换规则 高 double float long unsigned 低 int char,short 图中横向向左的箭头表示必定的转换,纵向的箭头表示当运算对象为不同类型时转换的方向。,2.4 数据类型转换,2.4.2 赋值类型转换
23、 (1) 当整型数据赋给浮点型变量时,数值上不发生任何变化,但有效位增加。 (2) 当单、双精度浮点型数据赋给整型变量时,浮点数的小数部分将被舍弃。 (3) 将字符型数据赋给整型变量时,由于字符只占一个字节,而整型变量为4个字节,因此将字符数据(8位)放到整型变量低8位中。 将unsigned char型数据赋给unsigned int或int型变量时,高24位补0。 将char型数据赋给unsigned int或int型变量时,若字符值最高位为0,则高24位补0;若字符值最高位为1,则高24位全补1。,2.4 数据类型转换,【例2-7】分析下面程序的运行结果。 main() unsigned
24、 char a;char b;unsigned int x;int y;a=0xfe; x=a; y=a;printf(“%x %xn“,x,y);b=0x7e; x=b; y=b;printf(“%x %xn“,x,y);b=0xfe; x=b; y=b;printf(“%x %xn“,x,y); ,2.4 数据类型转换,(4) 当长度长的整型数据赋给长度短的变量时,将进行截断赋值。 【例2-8】分析下面程序的运行结果。 /* EX2-8.C */ main() unsigned short a; short b; unsigned long x; x=0x6a8b5cfd; a=x; b=
25、x; printf(“%x %xn“,a,b); ,2.4 数据类型转换,(5) 当整型数据赋给长度相同的变量时,将进行原样赋值。 【例2-9】分析下面程序的运行结果。 /* EX2-9.C */ main() unsigned int a; int b; a=0xffff; b=a; printf(“%x %xn“,a,b); ,2.4 数据类型转换,2.4.3 强制类型转换 强制类型转换的一般形式为: (类型名) (表达式) 【注意】 (1) 表达式应该用括号括起来。 (2) 经强制类型转换后,得到的是一个所需类型的中间变量,原来变量的类型并没有发生任何变化。 【例2-10】分析下面程序的
26、运行结果。 main() int a;float b=3.5;a=(int)b;printf(“a=%d,b=%fn“,a,b); ,2.5 程序举例,【例2-11】分析下面程序的运行结果。 /* EX2-11.C */ main() int x, y; x=40; y=(x=x-4, x%7); printf(“y=%dn“,y); ,2.5 程序举例,【例2-12】分析下面程序的运行结果。 /* EX2-12.C */ main( ) int m,n, k; m=3; n=9; k=(+m)+(-n); printf(“m=%d,n=%d,k=%dn“,m,n,k); m=3, n=9; k=(m-)+(n+); printf(“m=%d,n=%d,k=%dn“,m,n,k); ,2.5 程序举例,【例2-13】取一个整数x从右端开始的47位。 【分析】 (1) 先使x右移4位,目的是使要取出的那几位移到最右端。 右移到右端可以用下面方法实现:x 4(2) 设置一个低4位全为1,其余全为0的数。 可用下面方法实现: ( 0 4) & ( 04 ),2.5 程序举例,main()unsigned int x,m,n,k;x=0x3aef;printf(“%xn“,x);m=x4;n=(04);k=m,