C语言程序的基本数据类型及其运算.ppt_第1页
C语言程序的基本数据类型及其运算.ppt_第2页
C语言程序的基本数据类型及其运算.ppt_第3页
C语言程序的基本数据类型及其运算.ppt_第4页
C语言程序的基本数据类型及其运算.ppt_第5页
已阅读5页,还剩121页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第2章 C语言程序的 基本数据类型及其运算,申闫春 北京信息科技大学 2008年2月,2.1 C语言的数据类型,2.1.1 数据类型的一般概念 1、什么是数据类型? 数据结构 + 算法 = 程序 C语言中以“数据类型”形式存在。 根据用途不同,把数据分类为可计算的数值型、可打印、显示的字符型等数据类型。例:定义5是整型数,可以数值计算;若定义5为字符型,不能进行数值计算,只能进行字符显示、打印。,2、C语言的数据类型?,主要有整型、字符型、实型(浮点型)、枚举类型、数组类型、结构体类型、共用体类型、指针类型、空类型。 在程序中对用到的所有数据都必须指定其数据类型。 不同类型的数据,所占内存的字节数不同, 对应的操作也不相同。 数据类型决定: 1、数据占内存字节数。 2、数据取值范围。 3、可以进行的操作。,2.1.2 常量,1、概念:在程序运行过程中,其值不发生变化的数据,不能被改变的数据。 2、分类: 直接常量:12 -44.6 a “Hello! “ /字符串常量 符号常量:用一个标识符代表一个常量。 3、符号常量定义:格式:#define 常量名 直接常量 举例:#define PRICE 100 /习惯上常量名用大写,变量名用小写。 #define PI 3.14 #define C1 a /符号常量的定义放在函数外面。 4、意义:(1)含义清楚。不存在二义性。 (2)在需要改变一个常量时,能够做到“一改全改”。,举例:求某商品总价。,#include #define PRICE 100 /定义符号常量 void main() int sum; sum = PRICE * 20; printf(“ %d n“, sum); PRICE:单价符号常量 20: 数量直接常量,举例:求圆柱体的体积,#include “stdio.h“ #define PI 3.1415926 /符号常量 main() float r,h,v; scanf(“%f %f“, ,常量分类,整型常量,例:5,67,100。 实型常量,例:3.14, -6.7。 字符型常量,例:a, D。 转义字符:不能直接写出的字符。 例:n 回车换行, 单引号,”双引号 字符串常量,例:”hello”,”82427141”。 符号常量,用符号命名常量。 例:#define PRICE 100 #define PI 3.1415926,2.2 数据类型及变量,2.2.1 基本数据类型 (1) 从长度上分,有8位、16位、32位和64位。 (2) 从数据的符号来分,有无符号数和有符号数。 (3) 按照数据的数学性质,分为整型、实型和字符型。 数值型数据的类型及表示形式,见表2-3(p15)。,类型标识符 名 字 取值范围 char 字符型 ASCII字符代码 unsigned char 无符号字符型 0 255 signed char 有符号字符型 -27 27-1 int 整型 -215 215-1 unsigned int 无符号整型 0 216-1 singned int 有符号整型 同 int float 浮点 10-38 1038 double 双精度型 10-308 10308 void 空值型 无值,2.2.2 变量及变量的定义,1、概念:在程序运行过程中,其值可以改变的数据,在内存单元申请一个空间,可以存放常量数据。 2、要素:(1)变量名。每个变量都必须有一个名字变量名,变量命名遵循标识符命名规则。代表内存中的一个存储单元。 (2)变量值。在程序运行过程中,变量值存储在内存中。在程序中,通过变量名来引用变量的值。,3、标识符(identifier),(1) 标识符就是一个名字(如常量名、变量名、函数名)。有规定的命名规则。 (2) 组成:只能由字母、数字、下划线组成。且第一个字符必须为字母或下划线。 (3) 长度:标识符的有效长度随系统而异,如果超长,则超长部分被舍弃。VC+6.0中规定最大长度为247个字符。 (4) 标识符命名的良好习惯见名知意。 例如:name(姓名)、age(年龄)。,4、变量定义,数据类型 变量名,变量名2; int a1,a2; float x1,x2; double y1,y2; char c1,c2; 习惯上,变量名用小写字母。 常量名用大写字母。,例如: #include void main() float m; m = 1.11; m = 2 * m; m = m+2.2; printf(”%f”,m); char c1,c2; / 定义字符型变量 int x,y,z; / 定义整型变量 double volume; / 定义双精度型变量 float sum,average; / 定义实型变量 unsigned long distance;/定义无符号长整型变量,2.2.3 变量的初始化,变量初始化:给变量赋初值的的语句,称为变量初始化。 要求对所有用到的变量,必须先定义、后使用。 变量赋初值有两种方式: 1、在定义变量的同时赋初值(也叫变量初始化)。 (出现在函数体的声明部分) 格式:数据类型 变量名=初值,变量名2=初值2; 2、通过一个赋值语句给变量赋初值。 (出现在函数体的执行部分) 格式:变量名 = 初值; 两种方式的效果是等价的。 例如:int a,b=3; int a, b; b=3; 注意:没有赋初值的变量并不意味着该变量中没有数值,而只表明该变量中尚未存放特定值。,关于变量的几点说明,1、程序中用到的变量必须“先定义(declare),后使用”。 2、C语言的关键字不能用作变量名。 3、C语言对英文字母的大小写敏感,即同一字母的大小写,被认为是两个不同的字符。 4、定义变量时,给几个变量赋相同的初值, 应写成 : int a=3,b=3,c=3; 不能写成: int a=b=c=3; 5、给变量赋值时,正常情况下应给变量赋相同类型的数据。若给变量赋与其类型不同的数据时,需进行类型转换(后面介绍赋值语句时详细介绍)。,32个关键字:(由系统定义,不能再定义) auto break case char const continue default do double else enum extern float for goto if int long register return short signed sizeof static struct switch typedef unsigned union void volatile while,变量举例,double p=15.5,d=0.1; float x,y,z=4.53; short int i=j=k=555; char c=a; 下面程序中有几处错误? include void main() int student, age; int if = adrress = 1; float score = 90; stadent = 2; /undeclared identifier Age = 20.7; /undeclared identifier printf(“%d %d %d %f“,if,student,age,score); ,错误: 1、if:为关键词。 2、int if=address=1; 应分别赋初值。 3、stadent:未定义的标识符,拼写错误。 4、Age:未定义的标识符,大小写敏感。 对score和age赋值时会自动进行类型转化。 90转化为90.0; 20.7转化为20。 类型转换在赋初值和不同类型数据进行混合运算时都会遇到。有规定的转换规则。,2.2.4 数据类型转换,在语言中,整型、实型和字符型数据之间可以进行混合运算(因为字符数据与整型数据可以通用)。 如果一个运算符两侧的操作数的数据类型不同,则系统按“先转换、后运算”的原则,首先将数据自动转换成同一类型,然后在同一类型数据间进行运算。 当要对不同类型的数据进行操作时,应首先将其转换成相同的数据类型,然后进行操作。 有两种转换方式: 1、隐式类型转换(自动转换,先转换、后运算) 2、显式类型转换,1、隐式类型转换(自动转换,先转换、后运算) 所谓隐式类型转换就是在编译时由编译程序按照一定规则自动完成。 转换发生条件: 运算转换不同类型数据混合运算时。 赋值转换把一个值赋给与其类型不同的变量时。 输出转换输出时转换成指定的输出格式。 函数调用转换实参与形参类型不一致时转换。,转换规则:,1、纵向向上的箭头表示不同类型的 转换方向(由低类型转化为高类 型),不表示转换所经的步骤。 2、横向向左的箭头表示必须的转换。,int i; float f; double d; long e; i=2; f=2.5; d=3.9; e=3; ,10+a+i*f-d/e,int,double,double,double,double,思考:根据已知变量定义及赋值语句,计算以下表达式的值,并说明每一步所得结果的数据类型。,2、显式类型转换(强制转换) 一般形式: (要转换成的数据类型)(被转换的表达式) 举例:int i; i = i + (int)9.801 float x,y; x=2.3 ; y=4.5; (int)(x+y) / 6 (int) (int)x+y / 6.5 (double),说明:强制转换得到的是所需类型的中间变量,原变量或表达式的类型不变。ssssssssssss 例如,(double)a 只是将变量a的值转换成一个double型的中间量,a的数据类型并未转换成double型。 当被转换的表达式是一个简单表达式时,外面的一对圆括号可以缺省。 例如: (double)a 等价于(double)(a) /*将变量a的值转换成double型*/ (int)(x + y) /*将x+y的结果转换成int型*/ (float)5 / 2等价于(float)(5)/2 /*将5转换成实型,再除以2(=2.5)*/ (float)(5 / 2) /*将5整除2的结果(2)转换成实型(2.0)*/,#include void main() float x; int i; x=3.6; i=(int)x; printf(“x=%f,i=%d“,x,i); ,思考:以下程序的输出结果是什么?,x=3.600000,i=3,程序运行结果:,结论:较高类型向较低类型转换时可能发生精度损失问题,例:已知三角形的边长a、b、c,求三角形周长的一半。,#include void main() float a,b,c,s; a=3;b=4;c=5; s=1/2 * (a+b+c); printf(“s=%8.2f“,s); ,s= 0.00,程序运行结果:,?,s= 6.00,程序运行结果:,改为:1.0/2 (1/2.0) 或 (float)1/2 (1/(float)2),在求三角形面积时会用到周长的一半。 改为:1.0/2 1/2.0 1.0/2.0 或 (float)1/2 1/(float)2) (float)1/(float)2,2.3 运算符和表达式,1、表达式:由操作符和操作数连接起来的、符合C语法规则的式子。例:a-b、c=9.8。 赋值表达式:进行赋值操作,如:变量初始化。 算术表达式:一般计算,如加、减、乘、除等。 关系表达式:进行比较判断。 逻辑表达式:进行逻辑比较判断。 条件表达式:进行条件满足与否的判断。 逗号表达式:实际上是一种复杂运算,可以 包含多个算术表达式。,2.3.1 运算符和表达式概述,2、C语言的操作符 (1)算术运算符 + - * / % (2)关系运算符 = | & (5)赋值运算符 = 及其扩展赋值运算符 (6)条件运算符 ? : (7)逗号运算符 , (8)指针运算符 * & (9)求字节数运算符 sizeof (10)强制类型转换运算符 (类型) (11)分量运算符 . (12)下标运算符 (13)其他:自增、自减:+ +、- -,函数调用运算符(),2.3.2 赋值运算符和赋值表达式,对于复合赋值表达式,如: a+=m-n; 它相当于: a=a+(m-n); int t=5; t+=t-=t*t; ? -15,-40,赋值运算符包含: 简单赋值运算符:= 复合赋值运算符:+=, -=,*=,/=,%=, 简单赋值运算符的一般形式为: 变量 = 表达式; 它的作用是将一个表达式的值赋给一个变量。 复合赋值运算的一般格式为: 变量 双目运算符 = 表达式; 复合赋值运算符 它等价于:变量 = 变量 双目运算符 (表达式)。 只有当表达式简化为一个变量或一个常数时,两边的括号可以省略。,1、赋值运算 赋值符号“=“就是赋值运算符,它的作用是将一个表达式的值赋给一个变量。 赋值运算符的一般形式为: 变量 = 赋值表达式; 例如,x = 5; y = (float)5 / 2; 如果表达式值的类型,与被赋值变量的类型不一致,但都是数值型或字符型时,系统自动地将表达式的值转换成被赋值变量的数据类型,然后再赋值给变量。 思考题:假设变量num的数据类型为float,其值为2.5,则执行“num = (int)num”后,num的值等于多少? float num=2.5; num = (int)num; printf(“num=%fn“,num);,2、复合赋值运算符是由赋值运算符之前再加一个双目运算符构成的。 复合赋值运算的一般格式为: 变量 双目运算符 = 表达式 复合赋值运算符 它等价于:变量 = 变量 双目运算符 (表达式)。 当表达式为简单表达式时,表达式外的一对圆括号才可缺省,否则可能出错。 例如:x += 3 /* 等价于x=x+3 */ y *= x+6 /*等价于y=y*(x+6),而不是y=y*x+6*/ C语言规定的10种复合赋值运算符如下: +=,-=,*=,/=,%=;/*复合算术运算符(5个)*/ &=,=,|=,=;/*复合位运算符(5个)*/,3、赋值表达式 格式: 赋值表达式的值:被赋变量的值 类型转换: 转换条件:当赋值运算符两侧的数据类型不一致时 转换原则:转换为被赋值变量的类型。,例1,float a; int b; a=1.2; b=a*3;,? b,b=3,例2,a+=3; x*=y+8,a=a+3; x=x*(y+8),例3,a=b=5; a=7+(b=8),? a,b,a=5 ;b=5 a=15;b=8,自右而左 的结合性,2.3.3 算术运算符及算术表达式,1、 基本算术运算符 +、-、*、/和求模(%) 2、自增自减运算符 i+ 或 +i (相当于i = i + 1;) i- - 或 - - i (相当于i = i - 1;),基本算术运算符:+ - * / % (% 模运算符或求余运算符) 说明:两个整数相除的结果为整数,舍去小数部分。 当商为负数时,多采用“向零取整”的方法。 例: 5/3 = 1 -5/3 = -1 注意:两个整数相除,结果要求舍去小数部分,而不是四舍五入的方法。 例:a*b/c-1.5+a 分析算术运算的优先级和结合性。 如果加减乘除运算中有一个数为实数,则结果是double型。因为所有实数都按double型运算。,算术表达式:用算术运算符和括号将运算对象(也称操作数、常量、变量、函数)连接起来的、符合C语法规则的式子。 例: a*b/c-1.5+a 优先级和结合性:先乘除、后加减,有括号先算括号。 自左至右。 说明:如果一个运算符两侧的数据类型不同,先自动进行类型转换,使二者具有同一类型,然后进行运算。,自增、自减运算符,作用:自增运算符()使单个变量的值增1; 自减运算符()使单个变量的值减1。,例,i=3; A)j=+i; B)j=i+; C)j=-i+;,i=i+1,i=i-1,? j,i,A) j=4 i=4 j=3 i=4 j=-3,格式:前置:+i ,- -i(在使用i之前,使i的值加(减)1) 后置:i+ ,i- - (在使用i之后,使i的值加(减)1),+和- -结合方向 是“自右至左”,j=-i+; 相当于j=-(i+);,例,i=3; A) c=(i+)+(i+); B) a=i+; b=i+; c=a+b;,? c, i,A) c=6 i=5 B) c=7 i=5,两处i值都为3,例,? i, j,i=4 j=4 表达式的值:7,自左而右组合,例,i=3; printf(“%d,%d”,i,i+),?,4, 3,函数参数自右至左求值,例3中的自左至右不是指+运算符的结合性,而是指C编译系统在处理多个运算符连写情况时,多采用自左而右尽可能多的将若干个字符组成一个运算符。,说明: (1) 自增、自减运算是语言特有的,常用于循环语句中,使循环控制变量加(或减),以及指针变量中,使指针指向下(或上)一个地址。 (2) 自增、自减运算符,不能用于常量和表达式。 例如,5+、- -(a+b)等都是非法的。 (3) +和- -的结合方向为自右至左。 (4) 如果对一个变量的自增自减运算,单独构成语句,而不是作为表达式的一部分时,前置和后置运算效果一样,都是使变量自加。 如 i+;和 +i;是一样的,都是使i加。 (5) 在表达式中,连续使用同一变量进行自增或自减运算时,很容易出错,所以最好避免这种用法。,2.3.4 关系运算符和关系表达式,= (大于或等于) (大于) (小于),关系运算符, = = != (6种),优先级,赋值 关系( 后2前4 ) 算术,关系表达式,用关系运算符将两个表达式连接起来的式子.,算术、关系、逻辑、赋值、字符。,值,真(1) 假(0),举例,已知: (a=3 b=2 c=1 d=0),0,a=bc,d=ab+c,1,53 ?,d=ab+c?,关系运算符和关系表达式,2.3.5 逻辑运算符和逻辑表达式,! (逻辑非) & (逻辑与) | (逻辑或) 如:xy & a y)& (a =c + 5 =(x != y)&(a=c+5) !x & a=c =(!x) & (a = c),逻辑运算符,!(逻辑非) &(逻辑与) |(逻辑或),运算规则,优先次序,赋值 | & 关系 算术 !,(1) !: 取逻辑值的相反值。 (2) &: 参加运算的两个逻辑值都为真时,结果为真(1)。 (3) |: 参加运算的两个逻辑值都为假时,结果为假(0)。,逻辑表达式,用逻辑运算符将关系表达式和逻辑量连接起来的式子。,举例,已知: (a= b=),1,a | b & 0,! a & (53) | b,0,双目,单目,逻辑运算符和逻辑表达式,举例,53 & 8 4- !0,0,(53) & (8 (4- !0),4 & 53 | 2,1,逻辑运算符两侧的运算对象不但可以是和,也可以是或非的整数,也可是任何类型的数据。系统判定标准:为假;非为真。,逻辑运算符和逻辑表达式,2.3.6 条件运算符,C语言中有一种条件运算符称为三项条件运算符,它具有如下的语法形式: 表达式1? 表达式2:表达式3 如: a8 ? b+10:b-20,2.3.7 其他运算符,1、逗号运算符和逗号表达式 a = 15,b = a *5,z= y,a + 6 2、求字节数运算符 sizeof(double) = 8 sizeof(char) = 1,逗号运算符:, 逗号表达式:表达式1,表达式2,表达式n 说明: 1、逗号表达式的求解过程为自左至右,依次计算各表达式的值,最后一个表达式的值即为整个逗号表达式的值; 2、逗号运算符的优先级最低。 3、使用逗号表达式的目的通常是想分别得到各个表达式的值,而并非一定要得到整个表达式的值。 4、常用于for循环语句中,除此以外很少使用。,例1,a=3 a=(3*5,a*4),? a,a=12,例2,a=3 a=3*5,a*4,? a,a=15 表达式的值为60,例3,(a=3*5,a*4),a+5,? a,a=15 表达式的值为20,2.4 位运算,前面介绍的各种运算都是以字节作为最基本单元参与运算的。 例:a*c-5 例:a=1,b=0,则:a|b 是 1。 为了开发系统软件,需要直接对地址进行运算,C语言提供了位运算的功能。 什么叫位运算? 位运算是针对二进制代码进行的运算。 例:按位“与”运算:规则:1,1,为1。 即;只有对应的两个二进制位均为1时,与的结果位才为1,否则为0。参与运算的数以补码方式出现。,例如:9 & 5可写算式如下: 00001001 (9的二进制补码) & 00000101 (5的二进制补码) 00000001 (1的二进制补码) 可见: 9 & 5=1。 (什么叫补码? 正数的补码:与实际值一致,符号位为0。 负数的补码:先求出该数对应的正数的补码,然后,按位取反,末位加1 。),2.4.1 位运算符和位运算,运算符 含义 运算符 含义 按位与 取反 | 按位或 右移,(1)位运算符中除以外,均为二目(元)运算符,即要求两侧各有一个运算量。 (2)运算量只能是整型或字符型的数据,不能为实型数据。,语言提供的位运算符有:,说明:,一、“按位与”运算符(),按位与是指:参加运算的两个数据,按二进制位进行“与”运算。如果两个相应的二进制位都为,则该位的结果值为;否则为。参与运算的两个数均以补码出现。 即:, 规则:1,1,为1。,例:并不等于,应该是按位与运算:,注意:如果参加&运算的是负数(如-3&-5),则要以补码形式表示为二进制数,然后再按位进行“与”运算。,3&5的值得,例:9 ,按位与的用途:,若想对一个存储单元清零,即使其全部二进制位为,只要找一个二进制数,其中各个位符合以下条件:原来的数中为的位,新数中相应位为。然后使二者进行运算,即可达到清零目的。,(1) 清零,例: 原有数为,另找一个数,设它为,这样在原数为的位置上,该数的相应位值均为。将这两个数进行运算:,(2) 取一个数中某些指定位,如有一个整数(个字节),想要取其中的低字节,只需将与8个1“按位与”即可。,(3)保留一位的方法:与一个数进行运算,此数在该位取。,即:a=84,b=59 c = a & b = 16,例:有一数,想把其中左面第、位保留下来,运算如下:,二、 “按位或”运算符(|),两个相应的二进制位中只要有一个为,该位的结果值为。 即: |,|,|,| 参与运算的两个数均以补码出现。 规则:有1,为1。,例: 060|017,将八进制数60与八进制数17进行按位或运算。,例:9|5可写算式如下: 00001001 | 00000101 00001101 可见:9|5=13 上机: #include main() int a=9,b=5,c; c=a|b; printf(“a=%dnb=%dnc=%dn“,a,b,c); ,应用:按位或运算常用来对一个数据的某些位定值为。例如:如果想使一个数的低位改为,只需将与进行按位或运算即可。,例: 是一个整数(位), 有表达式: | 则低位全置为,高位保留原样。,三、“异或”运算符(),异或运算符也称XOR运算符。它的规则是: 若参加运算的两个二进制位同号则结果为(假) 异号则结果为(真) 参与运算数仍以补码出现。 规则:异号,为1。,即:00=0,01=1,10=1, 11=0,即: 071052=023 (八进制数),例:,例:95可写成算式如下: 00001001 00000101 00001100 可见:95=12 上机: #include main() int a=9; a=a5; printf(“a=%dn“,a); ,() 使特定位翻转,设有,想使其低位翻转,即变为,变为。可以将它与进行运算,即:,运算符应用:,运算结果的低位正好是原数低位的翻转。可见,要使哪几位翻转就将与其进行运算的该几位置为即可。,因为原数中的与进行运算得,得,故保留原数。,例如:01200=012,() 与相,保留原值,() 交换两个值,不用临时变量,例如:,。 想将和的值互换,可以用以下赋值语句实现: ab; ba; ab;, () (ab的结果,a已变成) () (ba的结果,b已变成) () (ab的结果,a已变成), 执行前两个赋值语句:“;”和“;”相当于b=b(ab)。 再执行第三个赋值语句: 。由于a的值等于(),b的值等于(),因此,相当于a=,即a的值等于,等于。 得到原来的值。,即等效于以下两步:,四、 “取反”运算符(),是一个单目(元)运算符,用来对一个二进制数按位取反,即将变,将变。例如,是对八进制数(即二进制数)按位求反。 规则: 变,变。,五、 左移运算符(),左移运算符是用来将一个数的各二进制位全部左移若干位。,例如:a=2 将的二进制数左移位,右补。 若,即二进制数, 左移位得,(十进制数),高位左移后溢出,舍弃,低位补0。,左移位相当于该数乘以,左移位相当于该数乘以22,152=60,即乘了。但此结论只适用于该数左移时被溢出舍弃的高位中不包含的情况。 假设以一个字节(位)存一个整数,若为无符号整型变量,则时,左移一位时溢出的是,而左移位时,溢出的高位中包含。,六、右移运算符(),右移运算符是a2表示将a的各二进制位右移2位,移到右端的低位被舍弃,对无符号数,高位补0。,例如: a=017时: a的值用二进制形式表示为00001111, 舍弃低2位11: a2=00000011,右移一位相当于除以2 右移n位相当于除以2n。,例:#include main() unsigned a,b; printf(“input a number: “); scanf(“%d“, ,在右移时,需要注意符号位问题: 对无符号数,右移时左边高位移入0;对于有符号的值,如果原来符号位为0(该数为正),则左边也是移入0。如果符号位原来为1(即负数),则左边移入0还是1,要取决于所用的计算机系统。有的系统移入0,有的系统移入1。移入0的称为“逻辑右移”,即简单右移;移入1的称为“算术右移”。,例:a的值是八进制数113755: a: 1001011111101101 (用二进制形式表示) a1: 0100101111110110 (逻辑右移时) a1: 1100101111110110 (算术右移时),在有些系统中,a1得八进制数045766,而在另一些系统上可能得到的是145766。Turbo C和其他一些C编译采用的是算术右移,即对有符号数右移时,如果符号位原来为1,左面移入高位的是1。,七、位运算赋值运算符,位运算符与赋值运算符可以组成复合赋值运算符。 例如: &=, |=, =, =, =,例: a & = b 相当于 a = a & b a =2 相当于 a = a 2,八、不同长度的数据进行位运算,如果两个数据长度不同(例如long型和int型),进行位运算时(如a & b,而a为long型,b为int型),系统会将二者按右端对齐。如果b为正数,则左侧16位补满0;若b为负数,左端应补满1;如果b为无符号整数型,则左侧添满0。,2.4.2 位运算举例,例1 取一个整数a从右端开始的47位, 先使a右移4位:a 4 目的是使要取出的那几位移到最右端,未右移时的情况 右移4位后的情况, 设置一个低4位全为1,其余全为0的数。 ( 0 4 ), 将上面、进行&运算。 (a 4) & ( 0 4 ),程序如下: #include void main() unsigned a,b,c,d; scanf(“%o”, ,运行情况如下:(输入) , 217 (的值) , 13 (的值) 输入的值为八进制数331, 其二进制形式为11011001 经运算最后得到的d为00001101 即八进制数,十进制数13。,例2 循环移位,要求将进行右循环移位,将右循环移位,即将中原来左面()位右移位,原来右端位移到最左面位。, 将的右端位先放到中的高位中,实现语句:(); 将右移位,其左面高位位补, 实现语句:; 将与进行按位或运算,即|;,步骤:,程序如下: #include void main() unsigned a,b,c; int n; scanf(“a=%o,n=%d”, ,运行情况如下: , 3 ,运行开始时输入八进制数157653, 即二进制数1101111110101011 循环右移位后得二进制数0111101111110101 即八进制数75765,2.4.3 位段,信息的存取一般以字节为单位。但有时存储一个信息不必用一个字节,而只需占一个或几个二进制位。例如,“真”或“假”用或表示,只需位即可。存放一个开关量时,只有0和1两种状态。在计算机用于过程控制、参数检测或数据通信领域时,控制信息往往只占一个字节中的一个或几个二进制位,常常在一个字节中放几个信息。 为了节省存储空间,并使处理简便,语言又提供了一种数据结构,称为 “位段”或“位域” 。 所谓“位段”是把一个字节中的二进位划分为几个不同的区域,并说明每个区域的位数。每个域有一个域名,允许在程序中按域名进行操作。这样就可以把几个不同的对象用一个字节的二进制位域来表示。 C语言允许在一个结构体中以位为单位来指定其成员所占内存长度,这种以位为单位的成员称为“位段”或称“位域” ( bit field) 。利用位段能够用较少的位数存储数据。,(1) 可以人为地将一个整型变量data分为几部分。 但是用这种方法给一个字节中某几位赋值太麻烦。 (2) 可以用位段结构体的方法。,怎样向一个字节中的一个或几个二进制位赋值和改变它的值呢?可以用以下两种方法:,1、位域的定义和位域变量的说明 位域定义与结构定义相仿,其形式为: struct 位域结构名 位域列表 ; 其中:位域列表的形式为: 类型说明符 位域名:位域长度 例如: struct bs int a:8; int b:2; int c:6; ;,位域变量的说明与结构变量说明的方式相同。 可采用先定义后说明,同时定义说明或者直接说明这三种方式。 例如: struct bs int a:8; int b:2; int c:6; data; 说明data为bs变量,共占两个字节。其中位域a占8位,位域b占2位,位域c占6位。,例: struct packed-data unsigned :; unsigned :; unsigned :; unsigned :; int ; data;,对于位域的定义有以下几点说明: (1)一个位域必须存储在同一个字节中,不能跨两个字节。如一个字节所剩空间不够存放另一位域时,应从下一单元起存放该位域。也可以有意使某位域从下一单元开始。 例如: struct bs unsigned a:4 unsigned :0 /*空域*/ unsigned b:4 /*从下一单元开始存放*/ unsigned c:4 在这个位域定义中,a占第一字节的4位,后4位填0表示不使用,b从第二字节开始,占用4位,c占用4位。,(2)由于位域不允许跨两个字节,因此位域的长度不能大于一个字节的长度,也就是说不能超过8位二进位。 (3)位域可以无位域名,这时它只用来作填充或调整位置。无名的位域是不能使用的。 例如: struct k int a:1 int :2 /*该2位不能使用*/ int b:3 int c:2 ; 从以上分析可以看出,位域在本质上就是一种结构类型,不过其成员是按二进位分配的。,2、位域的使用 位域的使用和结构成员的使用相同,其一般形式为: 位域变量名位域名 位域允许用各种格式输出。 例: main() struct bs unsigned a:1; unsigned b:3; unsigned c:4; bit, *pbit; bit.a=1; bit.b=7; bit.c=15; printf(“%d,%d,%dn“,bit.a,bit.b,bit.c); pbit= ,上例程序中定义了位域结构bs,三个位域为a,b,c。说明了bs类型的变量bit和指向bs类型的指针变量pbit。这表示位域也是可以使用指针的。程序的9、10、11三行分别给三个位域赋值(应注意赋值不能超过该位域的允许范围)。程序第12行以整型量格式输出三个域的内容。第13行把位域变量bit的地址送给指针变量pbit。第14行用指针方式给位域a重新赋值,赋为0。第15行使用了复合的位运算符“&=“,该行相当于: pbit-b = pbit- b & 3 位域b中原有值为7,与3作按位与运算的结果为3(111&011=011,十进制值为3)。 同样,程序第16行中使用了复合位运算符“|=”, 相当于:pbit-c=pbit-c|1 其结果为15。程序第17行用指针方式输出了这三个域的值。,(1) 位段成员的类型必须指定为unsigned或int类型。 (2) 若某一位段要从另一个字开始存放,可用以下形式定义: unsigned :1; unsigned b:;一个存储单元 unsigned: ; unsigned :;另一存储单元 a、b、c应连续存放在一个存储单元中,由于用了长度为的位段,其作用是使下一个位段从下一个存储单元开始存放。因此,只将a、b存储在一个存储单元中,c另存在下一个单元(“存储单元”可能是一个字节,也可能是2个字节,视不同的编译系统而异)。,(3) 一个位段必须存储在同一存储单元中,不能跨两个单元。如果第一个单元空间不能容纳下一个位段,则该空间不用,而从下一个单元起存放该位段。 (4) 可以定义无名位段。 (5) 位段的长度不能大于存储单元的长度,也不能定义位段数组。 (6) 位段可以用整型格式符输出。 (7) 位段可以在数值表达式中引用,它会被系统自动地转换成整型数。,位运算小结 1、位运算是语言的一种特殊运算功能, 它是以二进制位为单位进行运算的。位运算符只有逻辑运算和移位运算两类。位运算符可以与赋值符一起组成复合赋值符。如&=,|=,=,=,=等。 2、利用位运算可以完成汇编语言的某些功能,如置位,位清零,移位等。还可进行数据的压缩存储和并行运算。 3、位域在本质上也是结构类型,不过它的成员按二进制位分配内存。其定义、说明及使用的方式都与结构相同。 4、位域提供了一种手段,使得可在高级语言中实现数据的压缩,节省了存储空间,同时也提高了程序的效率。,2.5 C语言的基本输入输出,C语言中的基本输入输出由标准的输入和输出函数完成。 这些函数的原型均在特定的stdio.h这个头文件中定义。 1、所谓输入输出是以计算机为主体而言的。从计算机向外部输出设备(如显示器、打印机等)输出数据称为“输出”,从输入设备(如键盘、光盘、扫描仪等)向计算机输入数据称为“输入”。 2、C语言本身不提供输入输出语句,输入输出操作是由函数实现的。,3、标准输入输出函数:以标准的输入输出设备(终端设备)为输入输出对象。 终端:终端是指通过通信线路连接到计算机的输入输出设备,它通常由显示器和键盘组成。 putchar( ) getchar( ) puts( ) gets( ) printf( ) scanf( ) 预编译命令:在使用C语言库函数时,要用预编译命令“#include”将有关的“头文件”包括到用户源文件中。 举例:#include main() printf(“Hello!” ); ,4、include 或:#include “stdio.h” 在调用标准输入输出函数时必须使用include 文件包含命令将 stdio.h头文件包含进来。 include 文件包含命令都是放在程序的开头。 注意:include 在.c文件中可以省略,在.cpp文件中不能省略。 在TC环境中,若使用printf()或scanf()函数,则前面的预编译命令可以省略!在VC+环境中不能省略!,2.5.1 字符输入/输出函数,1、字符输入函数getchar() 例:getchar()函数的应用。 #include void main() int c; printf(“please input a character:“); c=getchar(); printf(“What inputed is %cn“,c); ,单个字符的输入getchar函数 作用:从终端(键盘、输入设备)输入一个字符。 格式:getchar(); 注:getchar函数没有参数,所接受的字符可以赋给字符型或整型变量,也可以作为表达式的一部分。 举例:,#include void main() char c1; c1=getchar(); putchar(c1); putchar(getchar(); ,输入: a ,a _,输入: a b ,ab_,?,思考:分别输入a和ab时输出为什么不同? 输出框中的下划线表示光标。,2、字符输出函数putchar(),例:利用putchar()函数将字符输出到显示终端上。 #include void main() int a; a=100; printf(“ output the character n“); putchar(a); ,单个字符的输出putchar函数 作用:向终端(显示器、输出设备)输出一个字符。 格式:putchar(ch); 注:其中ch可以是字符型(整型)变量、常量或表达式 也可以是一个转义字符,如putchar(n)、putchar(101) 举例: #include void main() char ch1B,ch2=O,ch3=Y; putchar(”); /*输出双引号*/ putchar(ch1);putchar(ch2);putchar(ch3);/*输出BOY*/ putchar(”); /*输出双引号*/ 该程序输出”BOY”。,思 考? 想从键盘输入三个字母,然后将字母输出。编写程序。 想从键盘输入三个小写字母,然后将字母变成大写,再输出。编写程序。 想从键盘输入三个大写字母,然后将字母变成小写,再输出。编写程序。,2.5.2 格式化输入输出函数,1、格式化输出函数printf函数 Printf ( ” 格式描述串 ” ,输出项表列 ) “格式描述串”由一系列“格式转换说明符”组成。 作用:向终端(或输出设备)输出若干个任意类型的数据。 格式:printf(“格式控制字符串” ,输出列表); 说明: 1、“格式控制字符串“是用双撇号引起来的字符串,包括三种信息: (1)格式说明:由%和格式字符组成。 (如%d、%f) (将输出的数据转换为指定的格式输出。),(2)普通字符:需要按原样输出的字符。 (3)转义字符: (如t、n、b、r等) 2、“输出列表”是需要输出的一些数据,可以是表达式。 3、printf函数和putchar函数的区别: putchar函数只能输出字符,而且只能时一个字符;而printf函数可以输出多个数据,而且是任意类型。 必须强调:“格式控制字符串”中的格式字符,必须与“输出列表”中输出项的数据类型兼容,否则会引起输出错误。 注:1)整型和字符型可以通用。 2)tb连写,退一个制表位。 如:printf(“abcbthello”); 输出结果为:abchello。,例2,#include void main() int a,b; a=3; b=4; printf(“输出结果为:”); printf(“%d %dn”,a,b); printf(“a=%d, b=%dn”,a,b); printf(“a+b=%d”,a+b); ,输出结果为:3 4 a=3, b=4 a+b=7 _,例1,printf(“sum=%d n %c”, x, ch);,普通字符,格式说明,转义字符,如果x=100,ch= A ,那么下面的输出语句将输出什么结果?,输出列表,sum=100 A_,例1:体会printf函数中不同组成部分的输出形式 例2:输出列表分别为空、变量或表达式时的输出。 注:输出框中的下划线表示光标的位置。,格式说明必须以开始,以格式字符结束。 一般形式如下: % 标志 宽度 .精度 l 格式字符,-,-,n,m,d/f/c/u/s等,长整型整数,输出数据向左靠拢,输出数据最小宽度,对实数:输出小数点位数; 对字符串:截取字符的个数,格式说明的一般形式,注意:m和n都是正整数。m指数据输出的最小宽度,若指定的宽度m小于数据的实际宽度,则按实际宽度输出。,格式字符,附加格式说明字符,格式字符,必须强调:“格式控制字符串”中的格式字符,

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论