第二章 C语言的数据类型和运算_第1页
第二章 C语言的数据类型和运算_第2页
第二章 C语言的数据类型和运算_第3页
第二章 C语言的数据类型和运算_第4页
第二章 C语言的数据类型和运算_第5页
已阅读5页,还剩19页未读 继续免费阅读

下载本文档

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

文档简介

1、语言讲义第二章 C语言的数据类型和运算第二章 C语言的数据类型和运算2.1 数据类型数据是计算机加工处理的对象,C语言中的数据包括:常量、变量和有返回值的函数。为存储和处理的需要,将数据划分为不同的类型,编译程序为不同的类型分配不同大小的存储空间(存储单元的字节数),并对各种类型规定了该类型能进行的运算(运算符集),任何类型数据的值均被限制在一定的范围内,称为数据类型的值域(取值范围)。短整数short (16bit)整数int (16bit)长整数long (32bit)基本类型(简单类型)数值类型整型实型(浮点型)单精度型float (32bit)双精度型double (64bit)字符类

2、型char (8bit)枚举类型enum构造类型(组合类型)(导出类型)数组类型结构类型struct联合(共用)类型union文件类型FILE指针类型空类型voidC的数据类型2.1.1 C的数据类型说明: 构造类型是由基本类型按一定的规律构造而成的。 空类型的作用:表示函数没有返回值;说明函数无参数;表示指针不指向任何值。2.1.2 数值型数据的表示与存储形式如的表示: 日常表示 语言中的表示3.14159*100 3.14159e00.314159*101 0.314159e+10.0314159*102 0.0314159e231.4159*10-1 31.4159e-13141.59*

3、10-3 3141.59e-3尾数部份指数部分 小数点的位置是浮动的,称为浮点数形式。在计算机内部实数都以浮点形式存储,如float占4个字节,三个字节存数字部分,一个字节存指数部分。0 . 3 1 4 1 5 9 + 1数字部分(3个字节)指数部分(1个字节)小数点的位置是固定的,称为定点数,如:3.14159 ,10,-20, 1992显然整数都属于定点数,如:整数10,在计算机内部一般占2个字节。 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1定点数的小数点一般是在最高位(定点小数)或在最低位(定点整数)。对于实数型定点数如:3.14159,语言则把它按指数形式存放3.1

4、4159e0,即的实数一律以浮点形式存储。2.1.3字符型数据的表示和存储形式字符型数如:(a,A,#,3)在内存中以相应的ASCII代码存放(占一个字节),如a的ASCII代码为97,存储形式为:0 1 1 0 0 0 0 1在中,ASCII代码值可以被看成整数,如A+32为97与a等价。2.1.4 基本类型的名字和长度下列关键字称为类型区分符:char、 int、 short、 long、 signed 、unsigned 、float、double类型区分符代表一个基本类型的名字,用来说明一个数据的类型。表2.1 基本类型的名字和长度完整的类型名简单的类型名类型的长度(字节)取值范围ch

5、ar char 1有符号:-128127 无符号:0255signed charsigned char1-128127unsigned charunsigned char10255int int 2或4(与具体机器有关)字节:-32768327674字节:约-21亿21亿short intshort2-3276832767long intlong4约-21亿21亿signed int signed2或4 (同int)同intunsigned intunsigned2或 4(同int)字节:0655354字节:约042亿signed short int signed shor2-32768327

6、67unsigned short intunsigned short2065535singed long int signed long 4约-21亿21亿unsigned long intunsinged long4约042亿float float4 绝对值约13.4e-3813.4e+38double double8绝对值约:1.7e-3081.7e+308long doublelong double>=8由具体实现定义说明:signed和unsigned不能同时修饰char,short和long或signed和unsigned不能同时修饰int。float不能使用任何修饰词,dou

7、ble可用long修饰;int的长度与具体机器的字长相同,在16位机上为2字节,在32位机上为字节。因此,int 的长度与short或long 相同。signed char用个字节的低位表示字符值,最高位表示符号。unsigned char用整个字节表示字符值,无符号位。char表示有符号和无符号与具体机器系统有关,但char一定和signed char或unsigned char其中之一同。在多数机器系统中,char与signed char同。浮点类型的范围与浮点在机器内的表示有关,标准没有规定浮点数格式,大多数机器浮点数格式为:对于个字节浮点数,阶码占位,尾数占位,位符号位: 尾 数 阶码

8、23位8位符号位(1位)对于字节的浮点数: 尾 数 阶码符号位(1位)52位11位在浮点数中尾数位决定精度(有效数字位数),阶码决定取值范围。对于带符号的数据类型,一般用最高位(左边第位)表示符号,表示正,表示负,数值以补码形式存放(一个正数的补码是该数的二进制数),如()补为0000000000001010。一个负数的补码为取反加,如()补为1111111111110110。表中列出的short,int, long 是带符号的(隐含signed);对于无符号的数据类型,最高位不作为符号,与其它各位一起表示数值,因此,无符号数只表示正数不表示负数,与同样长度的带符号正数相比表示的最大数扩大了一

9、倍。字符型数据也分为signed和unsigned。ANSI标准ASCII码字符的允许取值范围为0127,用位表示就可以了,最左位补表示正数。有些计算机系统,除ASCII码字符外,还扩展使用一些图形符号(如“”),扩充使用用128255,其第一位为。因此,对signed字符型数取值范围为-128127。对unsigned字符型,取值范围为0255; 实数类型数据signed、unsigned之分;以后各章均使用类型的简写形式;语言提供了一个测试某一类型数据所占存储空间长度的运算符sizeof,格式为sizeof(类型标识符)。如sizeof(char)为, sizeof(long)为。2.1

10、常量和变量的常量有两种形式:一种是文字常量,简称常量或常数,文字常量是由表示值的文字本身直接表示的常量,如123,3.14159;另一种是符号常量,是用标识符表示的文字常量(标识符一般用大写英文字母),标识符是文字常量的名字。任何一个常量都属于一个数据类型,文字常量的类型由文字常量自身隐含说明,如123为整型,3.14159是一个浮点型,符号常量的类型由定义时指定。2.2.1常量的表示的常量有整数常量、浮点常量、字符常量、字符串常量和枚举常量。整数整数有三种形式:十进制整数、八进制整数和十六进制整数。十进制整数 十进制整数由数字09组成的数字串,多位数时最左第一个数字不能为,前面可以有表示正负

11、的符号“”或“”,“”可以省略。如738 -500+39是合法的整数。八进制整数八进制整数由数字07组成的数字串,第一个数字必须为0(前导零),它是八进制数的标志,八进制一般用于表示无符号数如:0137027+013-024是合法的八进制整数,而0128非法。八进制可以与十进制转换:如0137=95若将转换为八进制:0188811余余余即:十六进制整数十六进制整数是由数字09和字母af(或)组成的符号串,符号串必须以x或X(十六进制的前缀)开头,十六进制表示无符号整数,如0x13a0xc320xff0xb8000xdc都是合法的十六进制整数。013ax13a13a均为非法。说明:所有整数的缺省

12、类型是int,通过在其后面加后缀字母,可以表示长整数(long)无符号整数(unsigned)和无符号长整数(unsigned long)。长整数:在任意进制整数后面加l或,如27l018l0x1aL无符号整数:在任意进制整数后加u或。如27u0400U0x1aU无符号长整数:任意进制的整数后加ul或UL。如:27ul 0400UL0x1aUL.后缀字母大小写任意,由于l与数字容易混,常用。当整数的值超出int类型所能表示的范围时,称为整数溢出。整数溢出会产生不正确的结果,为避免溢出或类型转换的需要,应根据具体情况将整数相应地表示为长整数、无符号整数或无符号长整数,如在16位机上,整数1234

13、56会产生溢出,应表示成123456L.2、浮点数浮点数的一般形式为:±整数部分 .小数部分 e±n其中 表示可选项,e±n称为指数部分,e±n 表±n, “e”可以写成“”。n称为阶码(位十进制无符号常整数,可以有前导但仍表示十进制),n前面的“”可以省略。如-123.567e+5 -123.567E5 -123.567e05 都是代表值-12356700.0浮点数的组成规则如下:一个浮点数可以无整数部分或小数部分,但不能二者均无。一个浮点数可以无小数点或指数部分,但不能二者均无。例如:3.141593 .1E+02 -.234e+5 243

14、.e-2 2.01234e+3 0. .08 100.0 都是合法的浮点数。若将2.01e+3写成2010,将. 写成,或将100. 写成100则它们不是浮点数而是整数。下面一些是非法表示:-.e+1 既无小数部分也无整数部分1e-0.5:阶码不是整数1e+I:阶码不是常量(除非I已定义为符号整型常量)当浮点数超出它的类型所能表示的范围产生浮点溢出。如果浮点数的绝对值小于所能表示的最小值则下溢。如1.7e-309和-1.7e-309均产生下溢。下溢时绝对值太小以致机器不能表示而产生零值,称之为“机器零”。下溢时机器可能不能正常运行。当浮点数的绝对值大于所能表示的最大值时产生上溢,如1.7e30

15、9和-1.7e309均产生上溢。上溢时将产生错误的结果。浮点数的缺省类型是double,通过在浮点数后面加后缀字母可以表示单精度(float)数、双精度数(double)和高精度 (lang double) 数。单精度浮点数:在浮点数后面加f或F。如:3.14159F。双精度浮点数:在浮点数后面加d或D。如:3.14159d。高精度浮点数:在浮点数后面加l或L。如:3.14159L。在程序中可根据存储的需要、精度的需要或类型转换的需要将浮点数表示为适当的类型。3、字符常数字符常数通常是指一对单引号(单撇号)括起来的一个字符,形式为:字符字符常数可以被看成是一个整数,值为该字符的ASCII码值。

16、字符常数有两种表示方法。(1) 用字符的图形符号表示一个字符,形式为: 字符的图形符号字符的图形符号是指可打印字符,ASCII码字符集中,字符码为32126的字符是可打印字符,因而这种方法只适用于部分字符。如: a B + 3 > 注意:a和a表示两种完全不同的概念,a是一个字符常数,a是由单个字母构成的标识符。另外,在可打印字符中,有两个特殊字符不能用图形符号来表示,它们是单引号本身()和反斜线()。即 是非法表示,要想表示它们必须用转义序列表示。(2)用转义序列表示一个字符,形式为: 转义序列转义序列是由反斜线()开头的一个特殊字符串,每个转义序列表示字符集中的一个字符,转义序列及其

17、表示的字符如表2.2所示。表2.2转义序列转义序列ASCII字符码表示的字符十进制八进制十六进制0abfnrtv?”oooxhh 0 7 8 12 10 13 9 11 92 63 39 3402550255 0 7 10 014 012 015 011 013 134 077 047 042000377000377 0x00 0x07 0x08 0x0c 0x0a 0x0d 0x09 0x0b 0x5c 0x3f 0x27 0x220x000xff0x000xff空字符响铃字符退格字符换页字符换行字符回车字符水平制表字符垂直制表字符反斜线字符问号字符单引号字符双引号字符以ooo为字符码的字符

18、以xhh 为字符码的字符说明:()从表中可以看出,转义序列有两种形式:一种是反斜线后跟一个图形符号;另一种转义序列的位型“ooo”和“xhh”。前者表示常用的控制字符(字符码为031的字符),如n表示一个换行字符,其ASCII码为十进制10。后者可以表示字符集中的任一字符(字符码为0255的所以字符)。()位型中的ooo表示个八进制数字,可以不用前缀;hh表示个十六进制数字,x 是前缀不能省。例如:水平制表符可用下列任一种形式表示:t011 11 x09 x9字符A可用下列任一种形式表示:A 101 x41 ()单引号和反斜线字符虽然是打印字符,但编译程序规定必须用转义序列表示。例如:单引号字

19、符可用下列任一种形式表示: 047 47 x27反斜线字符可用下列任一种形式表示: 0134 134 x5c()双引号字符常数可以用图形符号或转义序列任一种形式表示。例如:“” 042 x22()字符0是值为的字符(空字符),不是空白字符。0除表示值外,它强调对象的类型是字符型。也就是说,表示值为的字符用0比用好。、字符串C语言没有字符串类型,但可以表示字符串常数,字符串变量是用字符数组来表示的。字符串常数(简称字符串)是用一对双引号括起来的一个字符序列,其字符的个数称为字符串长度。形式为:“字符序列”双引号是字符串的定界符而不是字符串的组成部分,双引号中的任何一个字符都是一个字符常数,形式为

20、不带单引号的字符(图形符号或转义字符)。例如:“This is a stringn”一个字符串可以包含个字符,表示为“”(两个相邻的双撇号),称为空串。字符串在机内存储时,系统自动在其末尾加了一个0,0是字符串的结束标志,以确定字符串的实际长度,字符串的存储长度比实际长度大。空串的存储长度为,存储长度为。注意:()“a” 和a是两个不同的概念。()当双引号作为字符串的组成字符时,必须用转义序列表示。如:“” is a empty strinng”表示:“” is a empty strinng()当单引号作为字符串的组成字符时,可以用图形符号表示,也可以用转义字符表示,如:“Its a pen

21、.” “Its a pen.”()字符串可以连接。被连接的两个字符串之间可以有个或多个空白字符,但不能有其它字符。如:“Hello,” “how are you?”等价于“Hello, how are you?”字符串连接主要用于源程序中表示长度跨越多行的字符串。如:printf(“Hello,how are you?”); 是非法的。因为语法规定字符串常数必须书写一行。如果一行写不下可用两种方法:printf(“Hello,How are you?”); 是续行符或:printf(“Hello,” “how are you:”);2.2.2符号常量为使程序易于阅读和便于修改,可以给程序中经常

22、使用的常量定义一个有一定含义的名字,这个名字称为符号常量。符号常量是一个标识符,有三种方法定义一个符号常量:一种是利用编译预处理的宏替换功能#define;另一种是用const类型限定符说明并初始化一个标识符;第三种方法是通过定义枚举类型来定义符号常量(以后讲)。1. 用#define定义符号常量形式:#define 标识符 常量表达式常量表达式是值为常量的表达式,一般为已定义的符号常量或文字常量,也可以由运算符连接常量形成的表达式;标识符是符号常量的名字,它代表常量表达式所表示的文字。例如:#define SIZE 100#define PI 3.1415926#define BLANK #

23、define TWO_PI 2.0*PI注:符号常量的名字(标识符)一般用大写字母。#define 行不是C语句,而是编译程序的预处理控制,因此其后面不加“;”2. 用const定义符号常量。形式:const 类型区分符 标识符=常量表达式;符号“=”左边的标识符被定义为常量,标识符代表常量表达式的值。例如:const int MAX=1000;const double PI=3.14159;const char BLANK=;const signed TRUE=1,FALSE=0;说明:用#define和const定义的符号常量在实现上有本质不同。#define在编译预处理时用常量表达式去替

24、换程序中所有出现的常量标识符,标识符没有对应的存储单元;由const说明的标识符是一个不可更改的左值,编译时要给它分配存储单元。应用举例:计算圆柱体的体积V=r2h#include “stdio.h”void main (void) float v,r,h; printf (“input r,h:”); scanf (“%f%f”,&r,&h); v=3.14159 r*r*h; printf (“v=%fn”,v); 如果使用符号常量:#include “stdio.h”#define PI 3.14159 viod main void) float v,r,h; prinr

25、f(“input r,h:”); scanf (“%f%f”,&e,&h); v=PIr*r*h; printf(“v=%fn”,v);2.2.3变量说明变量:在程序中其值可变的量,每一个变量都有一个名字(标识符),称为变量名。常量的类型是由常量自身隐含说明的,不需要做显示说明,而变量的类型必须做显示说明。C程序中任何变量必须遵循现说明后引用的原则,以便编译程序为变量分配适当长度的存储单元以及确定变量所允许的运算。变量说明的形式:类型区分符 变量表。类型区分符:说明变量中所列变量的数据类型。变量表由一个或多个变量名组成,多于一个变量时中间用逗号“,”隔开。一个说明结束必须用分号

26、“;”。变量数又称说明符表,这里一个变量名即是一个说明符。如: int age,index;与int age; int index;等价程序中有些变量在使用前需要设置初值,如做为计数器使用(如n+;)和做累加和的变量(如sum=sum+x)通常置初值为零,做累乘积的变量(如time=time*y)通常置初值为1。给变量赋初值有两种方式:一是通过赋值语句置初值(如i=0;);另一个方式是在变量说明时给出初值称为初始化,格式为:类型区分符 变量名=表达式,;如: int age=15,index=1,i=0,j=0; int i=j=0; 非法。因为i=j=0等价于i=(j=0),而(j=0)是赋

27、值表达式。 int i,j=0; j被初始化为0;i的初值不确定。 char c=”y”; double esp=1.0e-5;注意:引用一个没有值的变量非法。2.3 运算符和表达式C的运算符十分丰富。由运算符通过对运算对象(操作数)进行各种操作,按操作数的数目可将运算符分为:单目(一元),双目(二元)和三目(三元)运算符;按运算符的功能分类有:算术运算符、关系运算符、逻辑运算符、自增和自减运算符、位运算符、赋值运算符和条件运算符。另外还有数组的下标 、 函数调用( )、表顺序求值的逗号运算符和类型强制运算符等。表达式是由运算符、操作符数组成的符合的语法算式。从本质上说,表达式是对运算规则的描

28、述并按规则执行运算,运算的结果是一个值,称为表达式的值,其类型称为表达式的类型。单个操作数也是表达式。常量、变量、有返回值的函数调用和用()括起来的表达式称为简单表达式。由简单表达式和以简单表达式为操作数的表达式都是表达式。如 y3(x4) “”称为赋值运算符表达式的运算规则是由运算符的功能和运算符的优先级与结合性决定的。为使表达式按一定的顺序求值,编译程序将所有运算符分成若干组,每组规定一个等级称为运算符的优先级,优先级高的先执行运算。处于同一优先级的运算符的运算顺序称为运算符的结合性。运算符的结合性有从左至右(左结合)和从右至左(右结合)两种。表2·2 运算符的优先级和结合性优先

29、级运算符结合性1() -> · 左结合2! (单目) (单目)(类型) *(指针运算) & sizeof(类型名)右结合3*(乘法) %左结合4(双目) (双目)左结合5<< >>左结合6< < > >左结合7 !左结合8&左结合9左结合10|左结合11&&左结合12| |左结合13? :左结合14 * % & | << >>左结合2.3.1 算术运算算术运算符包括(单目) (单目) (双目) (双目) * (实数式整数) %(整数)双目 , * , ,的操作数可为任

30、何整数式或浮点数。对于“” “” 还可以用于指针加(减)一个整数。双目运算符的两个操作数类型可以不同,运算时自动转换成相同的类型(以后介绍)。基本原则是值域较窄的类型向较宽的类型转换。例如: 135 结果为整数18 两个操作数类型相同不转换 13.05 结果为18.0 将5转换为5.0 后运算 d97 结果为整数3, d 的类型为char,先将 d 转换成整数100再运算对于除运算符“”,如果两操作数都是整数则执行整数除,结果也是整数,值为商的整数部分,小数部分被截去;若至少有一个操作数为浮点数则执行实数除,结果为浮点数。如: 155 结果为整数3 12 结果为整数0 85 结果为整数11.0

31、2 或 12.0 结果为实数0.5或1.02.0对于求余运算符%,规定两操作数必须为整数,运算结果也为整数,值为左操作数除以右操作数所得的余数,符号与左操作数相同。如:17%5 或 17%5 结果为整数 217%5 或 17%5 结果为整数25%10 结果为整数510%5 结果为整数0整数除和求余运算存在下列关系:a%baa/b*b 其中a,b均为整数下面是一个由算术运算符连接操作数构成的表达式25(i%j*8/(ik) 其中i,j,必须为整数k可为整数或为浮点数2.3.2 关系运算关系运算符包括 < (小于) < (小于等于) > (大于) > (大于等于) (等于)

32、 !(不等)关系运算符比较两个操作数值的大小,操作数可以为整数、字符、实数,两操作数类型可以不同,运算符按一般算术转换规则自动转换成相同的类型。结果类型一定为int,如果操作数关系成立则结果为非0(一般为1),否则为0。注意C语言中没有表示逻辑真值和逻辑假值的数据。任何非0值(一般为非0整数)都表示逻辑真,整数0表示逻辑假。如:a!=b 表达式值为非0,50+70<=100.0 表达式值为0.如果用浮点数比较来测试某个条件,则可能永远得不到所希望的结果。如设x,y为浮点变量,则表达式:x/y*y= =x 值可能不成立。若需要判别两实数是否大约相等,可用下式表示:fabs(x/y*y-x)

33、<e-5 如:数学中axb与C中a=<x<=b含义不同。若a=0,b=0.5,x=0.3。则执行 “a=<x<=b”时先求a<=x得1(真)再执行1<=b得0(假)。为判别x是否在区间a,b内应为:a<=x && x<=b 表达式5>2>7>8在数学中不允许,在C中是允许的。按自左向右的原则:5>2为1 1>7为0 0>8为0整个表达式为的值0 关系表达式的值为,也可看作整型表达式。如:int i=1,j=7,a;a=i+(j%4!=0);最后a的值为 字符比较按ASC码进行b&

34、gt;a为a>A为a<0为 0=0为1 例如:z=3-1>=x+1<=y+z 若x为2,y=3 则z的值为1 2.3.3 逻辑运算逻辑运算符包括:&&(与) |(或) !(非)逻辑运算符的操作数可以为任何基本类型,&&和|的两个操作数的类型可以不同,运算时不执行类型转换。非0值的操作数视为逻辑真,0值操作数视为逻辑假,运算结果类型为int,值为非0(逻辑真)或0(逻辑假)。运算规则:0&&0 为0; 0&&1 为0; 1&&0 为0; 1&&1 为1注 1可用任何非0操作数代

35、替,下同。0|0 为0 0|1 为1 1|0 为1 1|1 为1 !0 为0 !1 为0如:(c<=z)&&(c>=a) 或 c<=z&&c>=a其结果如果变量c的值是小写字母,则上式为真(非0)否则为0。d<0|d>9 若d为非数字时,表达式为非0 。否则为0!i等价于 i= =0 但!i 比i= =0效率高,若c为字符型,检查c 是否为空白字符时 用!c 比 c= =0好注意:对于逻辑与(&&)运算,当左操作数为0(假)时整个表达式的值已确定为假,则右操作数根本就不计算(运算短路)。 如:int i=1,j

36、=1,k; i>1&&k=i+j 其结果整个表达式的值为(假),k的值为。对于逻辑或(|)运算,当左操作数为非(真)时整个表达式的值已确定为真,则右操作数根本就不计算。 如:int i=1,j=1,k; i1|k=i+j 其结果整个表达式的值为1(真),k的值为。2.3.4 自增和自减运算 自增和自减运算符包括:+(增1) -(减1) “+”和“-”是单目运算符,操作数必须是可更改的左值表达式。左值表达式是一个表示存储单元的表达式,一般为不带const说明的变量名。带const说明的标识符是不可更改的左值表达式。可更改的左值表达式包括:基本类型的变量名、下标表达式、指针变

37、量名和间接访问表达式(指针变量)、结构成员选择表达式和结构变量名。用()括起来的左值表达式也是左值表达式。“+ +”将操作数加1,“ -”将操作数减1,结果类型与操作数类型相同。整型或浮点型操作数按整型数值1增加或减少,指针类型操作数以后讲。“+ +”或 “-”可以出现在操作数前面(前缀式)或后面(后缀式) 如 +n -n n+ n-。前缀式先将操作数增(减),然后取操作数的新值作为表达式的结果。例如若n=1 则+n结果为2,n的新值为2。后缀式将操作数增(减)1之前的值作为表达式的结果。操作数的增(减)1运算是在引用表达式的值之后完成的称为后缀+(或)的计算延迟。一直延迟到出现下面情况时,操

38、作数才增(减)。·逻辑与运算符&&·逻辑或运算符|·条件运算符?:·顺序求值运算符,·一个完整的表达式(包括以语句形式出现的表达式,选择语句中的选择表达式,循环语句中的控制表达式,return语句中表达式)举例:设 int x=0 , y=1; x+x+ 结果为。整个表达执行完后x值为。即若 z=x+x+ 则z的值为,x的值为2。 yx+&&x 结果为1,因为结果为,&&后面的x值为因而整个表达式的值为 z=x*y| y结果z的值为,因为|后的y值为,因而整个表达式的值为,z的值为。上机可以测试:

39、“+”、“”运算的延迟情况。#include “stdio.h”void main(void) int x=0,y=1; printf(“x=%d,y=%dn”,x,y); printf(“x+=%dn”,x+); printf(“d=%dn”,y); printf(“x=%d,y=%dn”,x,y);输出:x=0,y=1; x+=0 y=1 x=1,y=0注:自增(自减)运算符的结合性是自右至左。它的运算对象只能是整型变量,而不能是表达式或常数,如5+或(x+y)+非法,+x也是非法,x+也是非法的。若x为5,y为5,z=x-y,则x=4,y=5,z=0。例:1 +i+i 是错的,中间应有空

40、格:+i+ +i; 它的结合方法是:从左向右尽可能多地把连续的+号组成运算符。 2 i=3; j=+i+ +i, printf(“%d”,j),则输出10; 而printf(“%d”,+i+ +i),则输出9。 printf(“%d %d”,+i+ +i, i);则输出9 3。 而printf(“%d %d”,i, +i+ +i);则输出5 9。 3若i=3;j=i+ + +i;则j的值是8,i的值是5; 4若i=3;i=i+ + +i;则i的值是9; 5若i=3;i=i+ + i+;则i的值是8; 6若i=3;j=i+ + i+;则j的值是6,i的值是5; 7若i=3;i=+i + +i;则

41、i的值是10;2.3.5 位运算任何数据在计算机内部都是以二进制码形式存储的。例如一个unsigned char类型的字符A存储形式为01000001。位运算是以逐个二进制位为直接处理对象的运算。这是C语言区别于其它高级语言的特色之一。位运算符是指 (求反) &(按位与) |(按位或) (按位加 、异或)>>(右移) <<(左移)除是单目运算符外,其余均为双目运算符。所有位运算符的操作对象必须是整数。两个操作数类型可以不同,运算之前遵循一般算术转换规则自动转换为相同的类型。结果类型是转换后的类型,结果的值与是有符号或无符号数有关。1 求反运算()运算符“”将操作

42、数的每个二进制位取成相反值,即0变1,1变0。结果类型与操作数类型同。例:unsigned i=0xd3f5,j=0; short k=0; 将i变成二进制码 1101001111110101 i=0010110000001010即i为0x2C0Aj的二进制码为全0, j为全1,即65535将k各位求反,k为全1,因是有符号类型整数,所以k为-1。2 按位与、或、加运算(&、|、 )运算规则:i j i&j i|j ij0 0 00 00 1 01 11 0 01 11 1 11 0可以看出:i0的结果是i; i1的结果是i;例如 unsigned short x=0xd3f5

43、,y=0xff,z;(1) z=0xd3f5 & 0xff;它的值为0xf5,即0xd3f5通过与0xff按位与取上了它的低8位,而高8位被屏蔽,0xff称屏蔽码。1101001111110101 & 0000000011111111 0000000011110101(2) z=0xd3f5|0xffz被赋值为0xd3ff 通过与0xff按位或运算。使原来的数高8位不变低8位变为全1。(3)z=0xd3f50xffz被赋值为0xd30a。 低8位取反其余不变(4)对于十进制的位操作,应先转化为二进制,运算后再转为十进制。如:int i ,j , k i =5; /*i的值为-6

44、*/j=5&8 ; /*j的值为*/k=58; /*k的值为*/利用“”,可使两个变量的值交换(不借助于第三个变量)。例:a=3;b=4; a=ab; b=ba=b(ab)=abb=a0=a a=ab=(ab)b(ab)=abbab=b0=b课堂作业:要想让某数的第4位取反其它位不变,应如何设置。3移位运算符(<<和>>)"<<" 和">>"是双目运算符。移位运算的规则是将左操作数向左(“”或向右(“)”移动由右操作数指定的位数。两操作数必须为整数,且右操作数为正数,可以是值为正整数的表达式,结果类

45、型与转换后的左操作数类型相同。左移时,高位被移出(丢掉),右边空出的低位用0填充,右移时,左边空出的高位的填充方式决定于右操作数的类型,如果是无符号数,则用0填充,否则用符号位填充。例:unsigned x=65,y=15;short z=-8;(1) x<<3该表达式的值为520,类型与x相同。X=65=0x41=0000000001000001,左移3位后X=0000001000001000=520X<<3等价于x*2*2*2,即x<<n相当于x乘上2n。但x<<15的结果是多少?(2) y>>3该表达式的值为,表达式的类型与y相

46、同。Y=15即0xf二进制是0000000000001111右移位后 变成0000000000000001为整数1。y>>3等价于y/2/2/2或y/(2*2*2),即:y>>n相当于y整除2n。() z>>该表达式的值为-2,类型为intz=-8=1111111111111000(的补码),右移位后z=1111111111111110(的补码)=-2位操作综合应用举例:例将整数的低字节作为结果的低字节,的低字节作为结果的高字节拼成一个新的整数。(P&0377)| (K&0xff)<<8其中P&0377取出的低字节(低位)

47、,K&0xff取出的低字节,(K&0xff)<<8使的低字节成为高字节,最后由| 拼装(“<<”优先于“|”)。例2设x,m,n为unsigned short,且m15,n,取出x从第m位(从右至左编号依次为:15)开始向右的n位,并使其向右端(第位)靠齐。x>>(m-n+1)&(0<<n)其中m-n+1是要被取出部分距离右端的位数,x>>(m-n+1)向右端靠齐,(0<<n)制作一个低端n位为,其余为的屏蔽位。2.3.6 赋值运算赋值就是把值存入变量对应的存储单元中,语言中赋值操作是作为一种表达式

48、来处理的,赋值运算符()可以和算术运算符(,)及双目位运算符(&,|,>>,<<)组合成一个复合赋值运算符。赋值运算符共有11个。= += -= *= /= %= &= |= = <<= >>=注意:复合运算符的两个组成符号之间不能有空白字符。简单赋值简单赋值运算符“仅执行赋值操作,表达式的形式为:操作数操作数“的功能是将右操作数的值赋给由左操作数指定的存储单元(变量)。左操作数必须是一个可更改内容的左值表达式.赋值运算符的右操作数类型可以和左操作数不同,执行赋值之前右操作数被自动转换为左操作数的类型。如:int j; j=5.6

49、;则j的值为;表达式的结果和类型与左操作数相同。对于基本类型,赋值表达式的形式可具体化为:变量名表达式例如:int i=5,j;float a=3.0,b=3.5;double r;char c1,c2;c1=a;j=c1; /*由char向int转换,结果赋给j*/r=a*b+i; /*a*b的结果由float向double转换,结果赋给r*/c2=j; /*j由int向char转换,其结果赋给c2*/i=c1>c2; /*c1>c2的类型与左操作数相同,直接赋值*/当右操作数又是一个赋值表达式时,形成多重赋值表达式,例如:i=j=0是一个合法的赋值表达式,“”右结合。因此上式等

50、价于i=(j=0) ,而j=0表达式的值为,因此i的值也为,但要注意:多重赋值表达式不能出现在变量说明中,如:int i=j=0; 是非法的。 2复合赋值 复合赋值运算符包括+ = - = * = / = % = &= |= = <<=和>>=,其形式为操作数1 OP=操作数2可理解为下面的展开形式: 操作数1=操作数1 OP操作数2例如 i+=1 可理解为i=i+1注意:复合赋值运算符与它的展开形式不一定等价 如 si+=1 /*i增加1 */ 展开形式 si+=si+1 /* i增加2 */ 3表达式求值的副作用一个变量的值由于计算表达式时而发生了

51、不应有的改变,这种效应称为表达式求值的副作用:赋值操作、自增、自减操作及函数调用都有副作用。 c=b*=a+2; 应是 b=b*(a+2); c=b;而不是 b*=a; c=b+2; 赋值操作右结合。 如 x=i+j; 应如何理解:x=(i+)+j 或x=i+(+j)?C编译器总是从左至右尽量地将若干字符组成一个运算符。上式应理解为 x=(i+)+j 诸如 i=(k=j+1)+(j=5),不同的编译器有不同的理解。在C中不符合交换律,在turbo C2.0中先算k=j+1,再算j=5.2.3.7 条件运算条件运算符(?:)是一个三元运算符,一般形式为操作数1?操作数2:操作数3操作数1必须为基本类型或指针类型、(一般为整型的)表达式,操作数2和操作数3可以是其它任何类型的表达式,且类型也可以不一致。计算e2结果为e2的值计算e3结果为e3的值非0e10条件运算符的规则如图所示: 注意:e2和e3中只有一个被求值。

温馨提示

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

评论

0/150

提交评论