1、第2章 C语言基础,北京科技大学 计算机系,C 语言程序设计,2,2,本章主要内容,本章介绍C语言的基础,包括: 数据类型 运算符和表达式 均是程序设计的基本知识 为什么讨论这些知识?,通常程序要对数据进行操作处理: 处理的对象是数据 通过运算符和表达式进行操作,3,3,例如:,【例2.1】计算圆的面积,半径为 5 cm。程序如下:,main( ) float r, area ;r=5 ;area=3.14*r*r;printf (“%fn “, area) ;,运算结果是输出圆的面积:78.500000,程序中用到的数据:r、area、5、3.14 对数据进行的运算:* 、=,例jc2_1,
2、4,4,分析:,计算机操作处理时,首先要解决数据的存放: 事先要在内存中给半径 r 和运算结果 area 开辟存储空间,存放它们的值。应该留多大的地方来存放它们的值? 数据 5 和 3.14 与 r 、area 不同,它们是在编写程序时就给出确定的值,在运算过程中不会改变。这样的数计算机怎么处理? 对整数 5 和小数3.14 ,计算机存放时是否有区别?,涉及数据类型 的基本知识,5,5,C语言的数据类型,C数据类型,本章讨论 基本类型数据,6,6,2.1.1 整型数据,1整型数据的类型 基本整型数据 int ,分配 2 Byte 短整型数据 short int,分配 2 Byte 长整型数据
3、long int,分配 4 Byte 整型数据均以二进制补码形式存储,问题: 为什么要采用补码? 如何表示?,7,7,计算机中正、负数的表示,例如:109 (1101101)2 要区别:109 和 109 方法是:将符号也数码化 即: 正的符号 用 0 表示负的符号 用 1 表示, 计算机中的数表示方法是:符号位二进制数值(以 8bit 为例) 109 110 1101 0110 1101109 110 1101 1110 1101,8,8,问题:计算机计算复杂化,例如计算: (-19)+(+22) 1001 0011 + 0001 0110,解决的方法是:使用反码或补码的表示方法(按前述表示
4、的编码称为原码),即能将减法一律转换为加法。,需要判断符号是否相同: 如果相同,结果符号不变,并进行绝对值相加 如果不同,结果取绝对值大的数的符号,并进行绝对值相减,9,9,原码、反码和补码,正数:原码、反码、补码相同 符号位为0,数值为对应的二进制数。109,01101101原 = 01101101反 = 01101101补 负数: 原码符号位为1,数值为绝对值的二进制数。 109 11101101原 反码符号位为1,数值为绝对值的二进制数各位变反。 109 10010010反 补码符号位为1,数值为绝对值的二进制数各位变反加1。109 10010011补,10,10,2. 有符号和无符号整
5、型数据,有符号的整型数据 signed int 无符号的整型数据 unsigned int 区别是将最高位看作符号位还是数据位,例如: 1111 1111 1010 1000 作为有符号数使用时,最高为符号位 为负数,值是:- 88(再求一次补) 作为无符号数使用时,最高为数据位 为无符号的数,值是:65448,11,11,整型数据的类型及规定,方括号表示可选项 int 分配2 Byte,long分配4 Byte,12,12,例如:,main( ) unsigned int m;m= 65448;printf(“nm=%dn“,m);printf(“m=%un“,m);,例jc2_a,输出结果
6、: m=-88 m=65448,按有符号数输出,按无符号数输出,13,13,注意:,系统为 int 型数分配的存储空间为: 16 bit (2Byte),=215-1=32767,0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1,1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0,问题:上数再加1是多少?,=-215=-32768,表示范围:-32768 32767,例jc2_c,使用中注意数的范围,有符号int型整数的最大值,有符号int型整数的最小值,14,14,2.1.2 实型数据,1实型数据的类型 单精度实型数据 float,分配4 Byte 双精度实型数据d
7、ouble,分配 8 Byte 2实型数据的存储,单精度实型,指数部分,小数部分,小数的符号位,指数的符号位,15,15,实型数据的类型及规定,C标准并未具体规定各种实型数据所占字节数,也不规定具体小数和指数部分的位数。 一般而言,小数部分位数多,数据表示的有效数字多,精度就高;而指数部分位数多,则表示的数据范围更大。,有效数字的意义?,16,16,2.1.3 字符型数据,字符型数据char,分配 1 Byte 字符型数据是指字母、数字、各种符号等用ASCII值表示的字符 例如 a 是一个char类型数据,称作字符常量,存储:,0 1 1 0 0 0 0 1,17,2.1.3 字符型数据,17
8、,18,2.1.3 字符型数据,C 语言中,字符数据以ASCII码的格式存储在内存中,因此字符数据和整型数据相互通用: int i = a; 把 字符a 的ASCII值 97 赋予 i char c = 65;把 ASCII值为65的字符A 赋予 c,18,19,2.1.4 空类型,空类型void 通常与指针或函数结合使用,19,20,20,2.2 常量、变量与标准函数,主要内容: 常量 变量 标准库函数,21,21,2.2.1 常量,在运行程序的过程中值保持不变的量 1整型常量 十进制:09 八进制:07,以 0开头 十六进制:09,AF/af,以 0x或 0X 开头,例如: 100 -8
9、0 +123 010 024 0100 073 0x38 0x10 0X10 0XFF 0x0a,22,22,1. 整型常量,整型常量的类型: 根据值大小默认类型。 整型常量后面加l或L,则认为是long int型例如:123L、0L、432l、0x100l,注意: 十六进制常量中可以使用大写字母AF,也可以使用小写字母af。 八进制常量中不能出现数字 8 或 9 例如:018、0921非法,23,23,2. 实型常量,十进制形式1.0 1. +12.0 -12.0 0.0 指数形式1e3 1.8e-3 -123E-6 -.1E-3,指数只能是整数,而尾数则可以是整数也可以是小数 ,无论指数或
10、尾数均不能省略 例如:1e、E.5、E-3 非法 实型常量的类型:默认为double型,后面加F(或f),则强调表示该数是float类型 例如:3.5f、1e2F,24,24,3. 字符型常量,可视字符常量 单引号括起来的单个可视字符 例如:a、A 、+ 、3、 等 转义字符常量 单引号括起来的 与可视字符组合,例如:,25,3. 字符型常量,25,26,26,4. 字符串常量,用双引号括起的一个字符序列 例如:“ABC“、“123“、“a“、 “nt “nGood morning“ 字符串常量的长度 : 所包含的字符个数 字符串常量的存储方式:,所占存储单元数:串长度1 例如:,字符串 结束
11、标记,27,4. 字符串常量,区别: a 和 “a” “123” 和 123双引号、反斜杠在字符串中的表示: ” 字符串的长度:“ab123bn515tkbwxa” 14,27,28,28,5. 符号常量,以标识符来代表的常量 事先编译预处理命令define定义 编译时先由系统替换为它所代表的常量,再进行编译 例如:,#define LEN 2.5 main( ) float a,b;a= 2*3.14 *LEN;b=3.14*LEN*LEN;printf(“a=%f,b=%fn“,a,b); ,编译前系统进行替换,29,29,5. 符号常量,main( ) float a,b;a= 2*3.
12、14 *2.5;b=3.14*2.5*2.5;printf(“a=%f, b=%fn“,a,b); ,define是编译预处理命令,必须以“#”开头 编译预处理命令在第7章讨论。,替换为,30,2.2.2 变量,1. 变量的有关概念 在程序运行过程中,其值改变的数据,称为变量。 程序中为什么要使用变量?,30,main() printf(“%ft”, 2*3.14*2.5);printf(“%fn”,3.14*2.5*2.5); ,变量,main() float r, length, area;r = 2.5;length = 2 * 3.14 * r;area = 3.14 * r *r;p
13、rintf(“%ft%fn”, length, area); ,31,31,2.2.2 变量,1. 变量的有关概念 在程序运行过程中,其值改变的数据,称为变量,变量用标识符表示,称为变量名。编写程序时通过变量名来存、取变量值。 变量必须“先定义后使用” 系统为变量分配存储单元,存储变量的值。,例如: 有变量a 它的值是510,32,32,2. 变量定义,变量定义的一般格式: 数据类型说明符 变量名1, 变量名2变量名n; 例如:int i, j;long k, m;float x,y;char ch1,ch2;,变量定义的目的:根据类型分配存储空间 必须使用合法的标识符作变量名 不能使用关键字
14、为变量命名,先定义 后使用,33,33,3. 变量的初始化:,允许在说明变量的时候对变量赋初值。 例如:int a=5,b=10+2; double x=23.568,y ; char ch1=a,ch2=66,ch3=142; 表示定义变量并对变量存储单元赋值。,34,3. 变量的初始化:,只定义变量、没有赋初值时,变量的值不确定,使用时会产生意外结果eg:int a; a = a+2; a = 1127 初始化的初值应该与变量的类型一致eg:int a; a = 1.5; a = 1错误的初始化:int a=3+b,b=5; float m=n=23.16;,34,35,35,2.2.3
15、标准库函数,由C编译系统定义的一种函数,存放在系统函数库中,用户可以根据需要随时调用 常用函数 如:printf、scanf、fabs、sqrt、sin、 (常用数学函数参见教材 P30 表2.5 ) 函数调用形式: 函数名(参数表) 例如:putchar(a) sqrt(x),36,36,2.3 运算符和表达式,主要内容: 算术运算符和算术表达式 赋值运算符和赋值表达式 关系运算符和关系表达式 逻辑运算符和逻辑表达式 位运算符和位运算表达式 条件运算符和条件表达式 逗号运算符和逗号表达式 其他运算符及其运算,37,37,运算符的有关概念,作用: 对运算对象完成规定的操作运算 类型: 按运算对
16、象分: 单目、双目、三目 按功能分: 算术、赋值、关系、逻辑 条件、逗号、位、其他,38,38,运算符的优先级和结合性,优先级 指各种运算符号的运算优先顺序 例如:算术运算优先于关系运算算术运算中先 * / 后 + -1 + 2 * 3 4 = 5,39,39,运算符的优先级和结合性,结合性 指运算符号和运算对象的结合方向 当表达式中运算符的优先级相同时,根据结合性来决定求值顺序 分为:从左向右(左结合)和从右向左(右结合) 例如:算术运算符为左结合 a-b+4赋值运算符为右结合 a= b = 5 ( C语言规定见教材 P297 附录B),40,40,本章涉及的运算符,+ - * / % +
17、- + - = += -= *= /= %= &= |= = = = ?: , & sizeof (数据类型标识符),41,41,表达式的有关概念,什么是表达式 由运算符将运算对象连接成的式子,它描述了一个具体的求值运算过程。 如:150+b*2-12.456 b=(+a)-2a /= a *= (a = 2) 计算表达式的值 按照运算符的运算规则求值 求值时注意运算符的优先级和结合性,42,42,表达式的有关概念,表达式值的类型 自动转换 强制转换 eg. 150+b*2-12.456 b=(+a)-2 a /= a *= (a = 2) f=abc -a |+b&c+ max=ab ? a
18、 : b a=3,a+=3,a*a 1/(float)a+6,43,43,算术运算,算术运算符的优先级,单目算术运算符求正 + 、求负 ,右结合int m = -5;,44,算术运算,双目算术运算符加+ 、减- 、乘* 、除/ 、求余 %左结合型 注(1)“%”要求运算对象必须是整型数据,功能是求两数相除的余数,余数的符号与被除数的符号相同。 注(2) “/”的运算对象可为各种类型数据,但是当进行两个整型数据相除时,运算结果也是整型数据 (截取商的整数部分) 注(3) “*”不能省略,没有乘方运算符,44,45,45,算术运算-自增自减运算,+ -是单目运算符 有前缀和后缀两种形式 前缀形式:
19、 先自增(自减)再引用; 后缀形式: 先引用再自增(自减); 功能:前缀形式 + a 等价于 a = a + 1- a 等价于 a = a 1后缀形式 a + 等价于 a = a + 1a - 等价于 a = a 1,表达式的值会不同,46,46,算术运算-自增自减运算,例:当 a5 时 +a 表达式的值为 6,且 a6 a+ 表达式的值为5 ,且 a6 b=+a 等价于 a=a+1; b=a表达式的值为6,且 a=6, b=6 b=a+ 等价于 b=a; a=a+1表达式的值为5,且 a=6, b=5,47,47,算术运算-自增自减运算说明:,+ 和 - 的运算对象只能是变量(或运算结果是变
20、量的表达式), 不能是常量(或运算结果是数值的表达式)。 例如: 5+、(a+2)+ 不合法。 具有右结合性,结合方向为从右到左。 例如: a+ 等价于 -(a+) 如果有多个运算符连续出现时,C系统尽可能多的从左到右将字符组合成一个运算符 例如: i + j 等价于 ( i+)+j,48,48,main( ) int a=5;printf(“%d %dn“,a,a+ );,算术运算-自增自减运算说明(续):,对函数参数的求值顺序:Turbo C系统先计算最右边的参数值,再依次计算左面的参数值。,【例2.5】有多个函数参数且为同一变量自增的运算处理。,输出结果: 6 5,49,49,算术运算,
21、算术运算符的优先级,算术表达式:用算术运算符和圆括号将操作数连接起来形成的式子。eg: 5 m % 100 + 7.8 * 2 ():圆括号,具有最高优先级,可以改变运算顺序,50,50,赋值运算,赋值运算符(右结合) 基本赋值运算符 = 复合赋值运算符:先运算后赋值+= -= *= /= %= &= |= = = = 如:m=12 b=(+a)-2 m%=3+n 等价于 m=m%(3+n) x *= (x = 5),51,51,赋值运算说明:,赋值号的含义:将赋值号右边表达式的值赋给左边的变量,并将该值作为赋值表达式的值。 a=b 与 b=a ? 赋值号左边必须是变量,右边可以是任意合法的表
22、达式 例如:n= t +2s 合法a+ b = 15 不合法,52,52,赋值运算说明:,赋值运算符仅优先于“,”,具有右结合性 例如: a= b= b*c10 等价于:a= (b=( (b*c)10) ) a /= a *= a = 2赋值号与数学中的等号含义不同 例如:数学中 a=b 等价于 b=a C语言中 a=b 不等价于 b=a,53,小测验: int a = 12; a += 10; a += a-= a * 5; 请问a的值是多少?,53,54,赋值运算说明:,“=” 两边操作数的数据类型不同:系统会自动将右侧的值转换成左侧变量的类型后,再进行赋值。int a = 3.4;flo
23、at f = 2.1;,54,55,55,逗号表达式运算,逗号表达式的一般形式表达式1,表达式2,表达式n逗号表达式的值 从左向右,依次对表达式求值,最后得到表达式n 的值就是逗号表达式的值,求值: a=5, a+, a*3 t=1, t+5, t+ x=(a=3*5, a*4 ),最低 优先级,只有赋值运算 才能改变变量 的值,56,逗号表达式运算,区分 逗号运算符 和逗号分隔符:printf(“%d,%d”,a,b);int max(int a, int b); printf(“%d,%d”,(a,b),c);TC中函数实参的求值顺序为从右向左如: m = max( i, i+ );,56
24、,57,运算符小结,() 单目,右结合 算术,左结合 赋值,右结合 逗号,左结合,57,58,58,2.4 运算中数据类型的转换,2.4.1 数据类型的自动转换 转换原则:,自动将精度低、表示范围小的运算对象类型向精度高、表示范围大的运算对象类型转换,例如有定义: int a; char ch; 表达式: a-ch*2+35L a-ch*2+ 35.,59,59,赋值运算中的自动类型转换, = 小数部分自动补0, = 自动舍去实型表达式的小数部分(注意不进行四舍五入) = 自动截取低8位如:int a = 326;char ch = a;,60,60,赋值运算中的自动类型转换, = 自动截取表达式值的低字节赋值,舍去高字节 如:long m = 65538; int n = m;= 高8位补0= 自动给高字节补0 或补1(带符号扩展),61,61,2.4.2 数据类型的强制转换,强制转换的一般形式(类型名) 表达式 例如: (int)( b+3*x)%3 1/(float)a+6,注意:(float) 22/5 与 (float) (22/5) 不同 错误的类型转换:(int) b=a+5 b= int (3*a),62,62,