版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、2020/9/14,C语言程序设计,1,第二章 数据描述与基本操作,2020/9/14,C语言程序设计,2,第二章 数据描述与基本操作,数据与操作是构成程序的两个要素。 在C语言中,数据处理的基本对象是常量和变量。运算(基本操作)是对上述各种形式的数据进行加工的过程。,2020/9/14,C语言程序设计,3,2.1 常量,常量是程序中数值不发生变化的量。C语言的常量有三类:数、字符和字符串。常量在程序中不必作任何说明就可以直接使用。此外,C语言还经常使用如下两种表现形式不同的常量:换码序列和符号常量。,2020/9/14,C语言程序设计,4,2.1.1 数,C语言中使用整数和实数两种数。 (1
2、)整数 整数的使用 整数的表示 允许使用的数符 表示形式 数值2304的不同表示 八进制整数 0,1,2,3,4,5,6,7 第一位是:o o4400 十六进制整数 0,1,2,3,4,5,6,7, 前两位是: ox900或0X900 8,9,a(或A),b(或B),c(或C), 0 x或0X d(或D),e(或E),f(或F) 十进制整数 常规09 常规 2304 注:af或AF分别表示十进制数1015。 因此,需要注意的是,如15,015,0 x15等是数值不同的整数,其值用十进制数表示分别为:15,13,21。,2020/9/14,C语言程序设计,5,整数可分为正整数和负整数,分别在数的
3、前面加正号“+”和负号“-”表示。正数的“+”一般省略不写。需要注意的是,八进制和十六进制整数只能表示无符号整数。没有负八进制和负十六进制整数一说。这是因为负整数以二进制补码形式存放在内存单元中,在调用或输出时符号位作为数值的一部分。有关这方面的详细介绍,请参阅计算机组成与结构之类的书籍。下列以例题的形式简要介绍一下负整数的原码与补码之间的相互转换。 例2.1.1,求负整数“-18”的补码。 做一做下例: 在C语言中,整数的取值范围随着不同的CPU的机器和不同的编译系统而不同。一般由CPU所处理的机器字的位数所决定的,如IBM-PC,POP-11等16位(bit)机器中,整数的取值范围是:-3
4、276832767。对于超过这个范围的整数,可以使用长型整数。长型整数的取值范围一般是整数的两倍长,如上述16位机器中,长型整数的取值范围是:-21474836482147483647。长型整数的表示方法是在整数后跟一个“l”或“L”。如:123L,0 x85I,0364l。也就是说,系统在16位机中为长整数扩充存储空间为4个字节。,-18的绝对值18的二进制原码表示为:00000000 00100010(详细计算步骤请参见2.1.3);,18的二进制反码表示为:11111111 11011101(各位取反);,-18的二进制补码表示为:11111111 11011110(在绝对值的反码末位加
5、1)。,例2.1.2,已知负整数“-16”的二进制补码表示为:11111111 11110000,根据原、补码的转换关系求其原码。,2020/9/14,C语言程序设计,6,(2)实数 实数又称浮点数。在C语言中,实数只能使用十进制。实数分为单精度实数和双精度实数两种,它们表示方法相同。通过中学的学习,我们知道实数有两种表示方法,即一般形式和指数形式。一般形式的实数由整数部分,小数点和小数部分组成。例如:4.37,.0423,48.0,-301415,58.等。对于数值特别大或特别小的数,要使用指数形式表示。它由尾数部分,字母“e”或“E”以及指数部分(阶码)组成。但要注意,字母“e”或“E”之
6、前必须有数字,并且”e”或“E”后面的指数必须为整数。例如:26.49,-32.17分别用指数表示为:26.49e12或2.649e12, -32.17e11或-3.217e11。虽然一个实数可以有多种指数表示形式,但是在使用指数形式输出时,按“标准指数形式”(即:在字母“e”或“E”之前的小数部分中小数点前有一位非0数字)。 实数取值的绝对值范围,在16位(bit)CPU机器中一般为到。实数的精度,在使用单精度实数时具有7位有效数字,而在使用双精度实数时一般具有15或16位有效数字(这由数据在计算机中的存储精度决定)。,2020/9/14,C语言程序设计,7,2.1.2数值转换,一个数从一种
7、进位计数制表示法转换成另外一种进位计数制表示法,称为数值转换。 一般来说,将进制(基数为R=)的数转换为进制(基数R=)的数,即:从求得。 通常用于数值转换的两种方法是多项式代替法和基数乘除法,这两种方法具有不同的应用范围。 (1)多项式代替法 用多项式代替法实现从到的转换,计算是在进制中进行的,所以必须熟悉进制的运算。如果要转换成其它进制,则必须熟悉该进制的计算规则。 进制数的位置记数法表示为: = 它在进制中用多项式表示法表示为:转换为进制为: 其中,中的(i=-m,-m+1,n-1)由中的(i=-m,-m+1,n-1)转换为进制而来,而中的是在进制中的表示。,2020/9/14,C语言程
8、序设计,8,2020/9/14,C语言程序设计,9,(2)基数乘除法 与多项式替换法相反,在将转换成时,基数乘除法的计算是在进制中进行的。整数的转换与小数的转换方法不同,整数的转换方法可以称为基数除法,而小数的转换方法则可以称为基数乘法。一个进制的数,若包含整数和小数两部分,则可以将它们分别进行转换,然后结合起来。 整数转换(基数除法) 举例说明一下。 例2.1.5,将转换为十六进制数。 设=2803,=16。 , 商,余数,相应数为3; , 商,余数,相应数为F; , 商,余数,相应数为A; 这样:。,2020/9/14,C语言程序设计,10,例2.1.6,转换为二进制数,即:问。 下面用一
9、种简化除式的方法: 0 所以,。 动手做一下下例。 例2.1.7,将先转换为二进制数,再转换为八进制数。,2020/9/14,C语言程序设计,11,小数的转换(基数乘法) 在多项式代替法的介绍中,我们接触过以下这样的例子: 可以看出从一种进制转换到另一种进制时,小数位数的变化是很大的,有时甚至不可能用有限位数准确实现转换。例如:1/3在三进制中仅有一位小数,而在十进制中则是无限循环小数,即: 那么,小数采用基数乘法转换为时,的小数位数到底应该取多少呢?这里有两种情况。 一、进制小数位数已经事先确定。例如,表示进制的小数设备本身已经确定了,这时就不必再根据来考虑了。 二,要使的精度不低于的精度,
10、即:要由的位数确定的位数。 设进制小数有k位,转换成进制后维持相同的精度需j位。这时应有:。 在十进制中应写成: , ,其中j是一个整数。 具体就不再推导下去了。,2020/9/14,C语言程序设计,12,例2.1.8,将转换为四进制数(小数点后保留五位数字) 在十进制中完成的计算过程,也可以用下列算式表示(=4): 0. 1285 4 4 0.0560 4 4 4 这时 例2.1.9,将转换为十六进制数,保持的精度。 设十六进制小数需j位,则j应为满足下列不等式的整数。 , 这样,j取值4(具体转换过程不再列出)。 计算一下下例。 例2.1.10,将转换为八进制,保持的精度。,2020/9/
11、14,C语言程序设计,13,(3)任意两个进位制之间的转换 根据上面的介绍,在 转换为时,若熟悉进制的运算规则就可采用基数乘除法,若熟悉进制的运算规则就可以采用多项式代替法。 一般说来,、进制的运算都不为我们所熟悉时,那么一种方便的方法就是利用十进制作桥梁。其大体步骤为: 首先将转换成,采用多项式替换法,在十进制中进行计算。 其次将转换成,采用基数除法,也可以在十进制中进行计算。 例2.1.11, 第一步:采用多进制替换法把该数转换为十进制数: 第二步,采用基数乘除法将十进制 转换为五进制: 自己动手计算一下下例。 例2.1.12,要求保留4位小数。 其它方法暂不详述。,2020/9/14,C
12、语言程序设计,14,2.1.3字符常量,字符常量是一个单一的字符,其表示形式是由一对单引号包围着一个字符。例如:a,A,f,5,?,+等都是字符常量。其中单引号只能作为定界符使用,并不表示字符常量本身。而其包围的字符不能是单引号和反斜线,即:,是错误的表示形式。关于这两个字符常量的表示形式,在后面的换码序列部分予以说明。但a,A是两个不同的字符常量。 在C语言中,字符常量具有数值,其值就是该字符的ASCII码。因此,可以说字符常量实际上是一字节的正整数。下面是某些字符常量及其ASCII码的数值(十进制数)。 A=65,f=102,5=53,?=63。 在C语言中,当把字符常量赋予某一变量时,实
13、际上就是把该字符常量的代码值赋予该变量,并且字符常量是可以像数一样,在程序中参与各种运算。 例如: a=D,x=A+5,s=!+G 相当于 a=68, x=65+5, s=33+71 在C语言程序中,字符常量通常用于字符之间的比较。,2020/9/14,C语言程序设计,15,2.1.4字符串常量,字符串常量用一对双引号包围一串字符来表示,这串字符串中不能包括双引号和反斜线。例如:“hello”,“program C”,“a”,“$12000.00”等都是字符串常量。双引号作为定界符,并不代表字符本身。 C语言的字符串常量具有与其它语言不同的独特性质。字符串常量在内存中存储时,自动在其尾部追加一
14、个NULL字符,它也是一个1字节(8位)的代码。在ASCII码中,其代码值为0。NULL字符常用“0”表示。因此,长度为n个字符的字符串常量,在内存中占用n+1个字节的空间。值得注意的是,在写字符时不要加上“0”,否则会画蛇添足。 C语言的字符串常量由于具有这种性质,所以一般称之为C字符串。 例如,字符串常量“hello”有5个字符,它存储在内存中时,如图所示: h e l l o 0 它占用6个字节空间。 字符串常量在内存中的存储形式是各个字节的代码值。例如上例中的C字符在内存中的有效值为: 104 101 108 108 111 0 从以上说明可以看出,字符常量与字符串常量在表示形式和存储
15、性质上是不同的。 例如:A和“A”是两个不同的常量,A占一个字节,而“A”占两个字节。 C字符串“”(双引号中什么也没有)表示空字符串,它在内存中占用一个字节其值为NULL的代码值。而字符“ ”(双引号中有一个空格)在内存中占用两个字符。,2020/9/14,C语言程序设计,16,2.1.5 换码序列,换码序列又称为转移字符,是C语言中使用字符的一种特殊表示形式。换码序列常常用于表示ASCII码字符集内的控制代码和某些用于功能定义的字符。例如:单引号,反斜线等。 换码序列通常用反斜线“”后跟一个字符或一个数字表示。 控制代码一般是计算机发向外部设备的命令码,它们仅仅控制设备实现某些特定动作,而
16、不是提供给用户输出信息。在ASCII码字符集中,代码值001F(十六进制数)的代码都是控制代码。在C语言程序中,可以在字符常量或C字符串中包含有控制代码。控制代码的换码序列如下:,2020/9/14,C语言程序设计,17,表2.1.1 换码序列 字符形式 含义 ASCII码 0 空字符(null) 0 x00 a 响铃 0 x07 b 退格(backspace), 0 x08 将当前位置移到前一列 t 水平制表,将当前位置 0 x09 移到下一个Tab位置 n 换行,将当前位置移 0 x0a 到下一行开头 v 垂直制表,将当前位置 0 x0b 移到下一行该tab所在列 f 换页 0 x0c r
17、 回车,将当前位置移到 0 x0d 本行开头 ” 双引号 0 x22 单引号 0 x27 反斜线 0 x5c ddd 1到3位八进制数所代表的字符 对应字符的ASCII码 xhh 以x开头的1到3位十六进制数 对应字符的ASCII码,2020/9/14,C语言程序设计,18,例2.1.13,“I say :” Goodbye!”中的字符串为“I say :“Goodbye!” “program C”中的字符串为“program C” 在字符常量和C字符串中使用单、双引号和反斜线时,必须使用换码序列,即前面加上反斜线:,“”,“”。 进一步引申上述概念,在C语言中可以使用换码序列形式表示任意一字
18、节代码,其表现形式为反斜线后面跟必须用1到3位八进制数或以x开头的十六进制数表示的代码值。 例2.1.14,一般字符A可以表示为101或x041; 控制字符b可以表示为010或x008; 反斜线可以表示为134或x05c.,2020/9/14,C语言程序设计,19,2.1.6符号常量,在C语言中,常量可以用符号代替。代替常量的符号称为符号常量。为了便于与一般常量区分,符号常量一般使用大写英文字母。符号常量在使用之前必须预先定义,其定义形式为:#define 符号常量 常量 。 例2.1.15, #define NULL 0 /*符号常量NULL代替常量0*/ #define EOF -1 /*
19、符号常量EOF代替常量-1*/ 每个符号常量定义式只能定义一个符号常量(即:符号常量在其定义域内不能改变,也不能再被赋值),并且占据一个书写行,但必须以#开头且后面不能加分号。实际上,它们不是C语言程序语句,而是发给编译系统的预处理命令(后面讲述)。 符号常量一经定义,它们就可以在程序中代替常量使用。 另外,程序中的某些常量,在调试、扩充或移植时要求修改其值,这种常量通常也定义为符号常量。当它们需要修改时,只需改变其定义即可。在一个符号常量多处使用的大程序中,充分体现了它的优越性。同时,也避免了一个常量在多处修改中,因失误造成的不一致性而导致的错误。,2020/9/14,C语言程序设计,20,
20、2.2 变量及其数据类型,变量是在程序中其值发生变化的量。C语言的变量具有以下三种属性。 (1)根据变量所持有的数据的性质不同而分为各种数据类型; (2)根据变量的存储方式不同而分为各种存储类型; (3)变量在使用时有一定的有效范围。,2020/9/14,C语言程序设计,21,2.2.1变量和变量的地址,C语言的变量在程序中用变量名表示。和其它高级语言一样,用来标识符号常量、变量名、函数名、数组名、文件名、结构类型名、标号和其它各种用户定义的对象名的有效字符序列称为标识符。C语言规定只能用英文字母(包括大小写共52个)、数字(0,1,9)和下划线三种字符组成。且必须由字母(az,AZ)或下划线
21、开头,字符长度没有限制,一般C语言编译系统(如:IBM PC的 MS C)仅把前8个字符作为有效字符。例如:ZhangFang.1.C,ZhangFang.2.C被认为是同一文件。Turbo C则允许使用32个字符。为了提高程序的可移植性,建议变量名的长度不要超过8个字符。在C语言中,大写字母和小写字母被认为是两种不同的字符,根据惯例变量名用小写字母,且在构造标识符时,应做到见名知意。 在构造变量名时,不能将关键字作为变量名。C语言有如下32个关键字: 表2.2.1 C语言中的关键字 auto break case char const continue default do double e
22、lse enum extern float for goto if int long register return short signed sizeof static struct switch typedef union unsigned void volatile while,2020/9/14,C语言程序设计,22,有些标识符并不是关键字,但有专门的用途,而不能当一般标识符使用。常用的有 define elif endif ifdef ifndef include 在程序运行中,变量的数值被存储在一定的存储空间中,存储某变量的内存空间的首地址称为变量的地址。C语言中,变量的地址用“
23、变量说明可以放在函数的前面,也可以放在函数的参数说明部分,还可以放在复合语句的说明部分进行。编译系统在处理变量说明语句时,根据其存储类型和数据类型,在特定的存储区域为该变量分配存储空间。,2020/9/14,C语言程序设计,23,2.2.2 变量的数据类型,C语言的变量,根据其数值的性质,分为以下不同的数据类型: (1)按照数据的长度,分为8bit,16bit,32bit,64bit四种类型,其表示分别如:char,short,long,double。 (2)按照数据是否带符号,分为带符号数和无符号数,其表示分别为signed(也可以省略不写)和unsigned。 (3)按照数据的数系性质,分
24、为整数型和浮点小数型(实数型),其表示分别如:int,float(单精度型,有效数字7位),double(或long float,双精度型,有效数字为15或16位),2020/9/14,C语言程序设计,24,2.2.3 数据类型的转换,不同数据类型的变量之间进行各种运算时,C语言编译系统自动进行数据类型转换。转换的原则是,参加运算的各种类型都转换为它们之间数据最长的数据类型。如下所示: charshortlongfloatdouble 。可见从左向右,数据长度增加,所以左边的数据类型向右边转换。按照上述原则进行数据类型转换可以保证运算的精度不会降低。 当把一个变量的数值赋予另一个变量,或是把运
25、算结果赋予某个变量时,C语言编译系统也自动实现数据类型的转换。转换的原则是,等号右边的数据类型转换为等号左边的数据类型。 例如:short a; char b; long c; a=b; /*b转换为a的short型*/ c=a+b; /*b先转换为a的short型,运算结果再转换为c的long型,赋予c*/ 当等号右边的数据类型比左边长时,按照上述原则转换时,右边的数据仅被截取所需的长度。因此,可能引起精度降低或出现错误的结果。C语言提供了一个测定某一类型数据所占有存储空间长度的运算符“sizeof()”。格式为: sizeof(类型标识符) 。例如:sizeof(double),其值为8。
26、 除了上述的由C语言编译系统自动实现数据类型转换之外,还可以在程序中强制进行这种转换。表示形式为:(数据类型) 变量名或运算式 。它将后面指出的变量名或运算式结果强制的转换为指定的数据类型。;例如:sqrt()函数调用时要求参数是double型数据。若变量n是int型,且作为该函数参数使用时,必须按下列方式强制进行类型转换:sqrt(doudle)n)。在以后我们会再次接触强制数据类型转换的情况。 无论是自动地还是强制地实现数据类型的转换,仅仅是为了本次运算或赋值的需要,而对变量的数据长度进行一时性的转换,并不能改变数据说明时对该变量规定的数据类型及其长度。,2020/9/14,C语言程序设计
27、,25,2.3 变量的存储类型和使用范围,变量的存储类型规定了该变量数据的存储区域,而变量的存储区域和变量在程序中说明的位置决定了它的使用范围。,2020/9/14,C语言程序设计,26,2.3.1 变量的存储类型,C语言变量的存储类型有四种,分别为: 表 2.3.1变量的存储类型 存储类型 auto register static extern 说明 自动型或堆栈型 寄存器型 静态型 外部参照型 auto型变量存储在内存的堆栈区,它在堆栈区域中属于一时性存储,并不长期占用内存,其存储空间可以被若干变量多次覆盖使用。因此。C语言程序中大量使用的变量为auto型,其目的之一就是为了节省内存空间。
28、 register变量存储在CPU的通用寄存器中.通常使用频率比较多的变量为register型,目的是提高运算速度。 使用register型变量是C语言所具有的汇编语言的特性之一,因而与计算机硬件关系比较密切。不同类型的CPU具有个数不同的通用寄存器,其中供C语言编译系统使用的个数也不同。所以,在C语言程序中,设定register变量的个数不是任意的。通常以两个左右为宜。C语言编译系统对于超过CPU中可供使用的通用寄存器个数的reguster变量作为auto变量处理。值得注意的是,数据类型为longdouble和float的变量不能设为register型,因为它们的数据长度超过通用寄存器本身的
29、位长。 static变量存储在一般的内存区域中。这类变量在数据说明时被分配了一定的内存空间,并且该空间在整个程序运行中,自始至终都归该变量使用。 extern型变量一般用于在程序的多个源编译单位之间传递数据。在这种情况下,指定为extern型的变量是在其它编译单位的源文件中定义的。它的存储空间需要参照本身的编译单位外部而决定,所以称为外部参照型。关于extern型变量的概念和使用方法在后面讨论。,2020/9/14,C语言程序设计,27,2.3.2 变量的使用范围,C语言的变量,由于其存储类型不同而有不同的存储寿命。有些类型的变量,其寿命仅限于某个程序范围之内,脱出这个范围后它们就不再存在,这
30、样的变量具有局部寿命,称为局部变量。与此相对应,有些变量存在于整个程序运行期间,它们具有全局寿命,称为全局变量。 此外,变量说明可以出现在程序不同的位置上。在函数内部,更广义地说讲,在某个大括号对包围的程序范围内部被说明的变量,称为内部变量。与之相对应,在所有的函数外部被说明的变量称为外部变量。 内部变量可以是auto型,register型或static型。其中类型名auto可以缺省,即内部变量没有指明存储类型时,意味着它是auto型。 例如: main() #define BEGIN /*声明部分,BEGIN对应,定义为符号常量*/ #define END /*声明部分,END对应,定义为符
31、号常量*/ BEGIN int i,j; /*类型缺省,整型局部变量i,j为auto型*/ register char c; /*字符型局部变量c为 register型*/ static int n; /*整型局部变量n 为static型*/ END,2020/9/14,C语言程序设计,28,C语言规定,auto 型和register型变量只能是内部变量。它们都是局部变量,其存在寿命和使用范围仅限于包围着该变量说明的大括号对之内。当程序执行完该范围的所有语句,程序控制脱出了“”后,这些变量占用的存储空间被释放,它们也就不再存在。由此可见,在不同的大括号对包围的程序范围内,例如在不同的函数内出现
32、的同名的auto型和register型变量是毫无关系,相互独立的变量,它们不会发生冲突。 static型变量可以是内部变量,也可以是外部变量。static型内部变量不同于auto型和register型内部变量。当程序控制退出这个程序范围之后,它并不释放占用的内存空间。该空间在整个程序运行期间都由该变量占用。所以,即使退出它的大括号对之后,该变量的数值仍然保存在其内存空间中。因此,static型内部变量都是全局变量。但是,这类变量的使用范围仅限于其说明的大括号对之内,这称做在程序范围内它们是可见的。脱出该程序范围之后,虽然其值仍然保留着,但它不能被使用。也就是说,它们在包围其说明的大括号对外部是
33、不可见的。这时,它们在内存空间保留的使用的值可以再度使用。所以我们说,static型内部变量具有全局寿命和 局部可见性。由此可见,不同大括号对内部变量说明的同名static型变量,占用各自不同的内存空间,有各自的可见范围,所以它们不冲突, 外部变量可以是static型和缺省存储类型的变量。auto型和register型变量不能是外部变量。外部变量是全局变量,它们在整个程序运行期间到占据一定的存储空间,始终都保持其存储数据,它们在其说明之后的程序中所有的函数内部都是可见的。,2020/9/14,C语言程序设计,29,例2.3.1,内部变量的使用范围。 main() int i; /*类型缺省,整
34、型局部变量i为auto型*/ static int a; /*整型局部变量a为static型*/ register int b; /*整型局部变量b为register型*/ i=1;a=10;b=5; /*为i,a,b赋值*/ printf(“-MAIN-n”); /*输出语句*/ printf(“i:%d;a:%d;b:%d.n”,i,a,b); /*输出i,a,b的值*/ other(); /*调用other()函数*/ /*输出语句*/ printf(“i:%d;a:%d;b:%d.n”,i,a,b); /*输出i,a,b的值*/ other() /*定义other()函数*/ int
35、i; /*类型缺省,整型局部变量i为auto型*/ static int a; /*整型局部变量a为static型*/ i=16;a=100; /*为i,a赋值*/ printf(“-OTHER-n”); /*输出语句*/ printf(“i:%d;a:%d.n”,i,a); /*输出i,a的值*/ 运行结果(见右图):,2020/9/14,C语言程序设计,30,例2.3.2,外部变量的使用范围。 int a; /*声明两个外部变量a和b,在以下两个函数main()和next()内部都可以使用*/ static int b; main() a=30;b=100; /*为a,b赋值*/ prin
36、tf(“a:%d;b:%d.n”,a,b); /*输出 a,b的值*/ next(); /*调用函数next()*/ printf(“a:%d;b:%d.n”,a,b); /*输出 a,b的值*/ next() /*定义函数next()*/ a=a+b; /*把a与b的和赋予a*/ 运行结果:,2020/9/14,C语言程序设计,31,分析一下下列程序的运行结果。 例2.3.3, int n; main() int m,n; m=1;n=2; printf(“%d,%d.n”,m,n); inf(); printf(“%d,%d.n”,m,n); outf(); printf(“%d,%d.n
37、”,m,n); inf() int m=2,n=3; printf(“%d,%d.n”,m,n); outf() int m=4; n=m+1; printf(“%d,%d.n”,m,n); ,2020/9/14,C语言程序设计,32,2.4赋值和算术运算,2020/9/14,C语言程序设计,33,2.4.1 变量的初始化和简单赋值,变量在被说明的同时可以赋予初值,这称为变量的初始化。 例如:char a=3; static int b=5; 不同存储类型的变量,其初始化的意义不同。auto型和register型变量若被初始化,则每当进入该程序块后,都执行该变量的初始化赋值功能。这两种类型在数
38、据说明中不进行初始化的话,则在程序中必须给它们赋予数值后才能使用。这就是说,没有进行初始化的auto型和register型变量,其初值不定,它们不能直接在程序中使用(参加运算或将其赋予其它值)。 static型变量和外部变量初始化时,必须使用常量给其赋初值,。而auto型和register型变量则可以用常量或变量进行初始化。 当然,指定为extern型的变量不能进行初始化。 static型变量和外部变量在数据说明中不进行初始化,自动赋予零值。与auto型和register型变量不同,static型内部变量的初始化仅执行一次,即第一次进入该程序块时,该变量被赋予初始值,而在此之后再次进入该程序块
39、时,则不再执行赋初值的功能。 简单赋值是把一个运算表达式的值赋予一个变量,其形式为:变量=运算表达式 ;。其中,“=”为赋值符,不同于数学中使用的等号,没有“相等”的含义。且其左边必须为变量。对于赋值表达式,要注意,在赋值时,数据类型的变换。,2020/9/14,C语言程序设计,34,2.4.2 算术运算,运算是对数据加工的过程,记述各种不同运算的符号称为运算符。参加运算的数据称为运算量或操作数。用运算符把运算量连接起来的式子称为运算表达式,简称表达式。任何运算表达式都有一定的运算结果值。运算表达式是C语言中可执行语句的一种。运算表达式中的运算量可以是常量也可以是变量。所有运算量都是常量的表达
40、式称为常量表达式。 C语言的运算种类丰富,与之相应,它的运算种类繁多。当各种不同运算组成一个运算表达式时,运算的优先顺序起着十分重要的作用。我们先来讨论算术运算。 (1)单项算术运算 单项算术运算是对一个运算量施行的算术运算,即对一个运算量进行运算之后,运算结果仍赋予该运算量。因此,参加单项算术运算的运算量必须是变量。 表2.4.1单项算术运算 运算符 名称 举例 等价于 + 递增运算符 a+或+a a=a+1 - 递减运算符 a或a a=a-1 - 反符号 -a a=-a,2020/9/14,C语言程序设计,35,下面简要介绍一下一些必要的术语: 前置运算:运算符写在变量之前,例如:+a,-
41、a. 后置运算:运算符写在变量之后,例如:a+,a-. 但是,当前后置运算与其它运算结合在一个表达式时,它们参加运算的值不同。前置运算是变量的值首先加一或减一,然后以该变量变化后的值参加其它运算。 例2.4.1int a=3,b=5; c=(+a)*b; 程序先计算+a,返回值4,a=4;再计算4*b,返回值20,a=4,b=5,c=20. 后置运算是变量的值首先参加运算,然后它本身的值加一或减一,即参加运算的是变量变化前的值。 例2.4.2,int a=3,b=5; c=(a+)*b; 程序先计算a+ ,返回值3,a=4;再计算3*b,返回值15,a=4,b=5,c=15。 需要指出的是,一
42、个变量的前置和后置运算仅仅说明该变量本身参加运算与其值变化之间的先后关系,它们并不影响该单项运算在表达式中与其它运算之间的运算顺序。 前置和后置运算经常用于数组下标的变化。例如:a=10;i=5;对于data+i=a;语句,程序先执行+i,返回值6,i=6;结果为:data6=10.对于datai+=a;语句,程序先执行i+, 返回值5,i=6;结果为:data5=10. 在程序中,要避免使用这样的前置或后置运算:datai+=i;datai=i+;因为这种用法的结果随机器和编译系统不同而不同。,2020/9/14,C语言程序设计,36,(2)二项算术运算 二项算术运算是两个运算量之间的运算,
43、与以前学过的程序语言类似的是:运算符有“+”、“-”、“*”、“/”,另外还增加了一个“%”(取余运算)。例如:a%b,是求a除以b 的余数,该运算的运算量必须是整常量或变量,即实数型( float型或double型)运算量不能参加取余运算。 (3)算术赋值运算 C语言中,二项算术运算可以和赋值运算结合在一起,形成算术赋值运算。 表2.4.2 二项算术赋值运算,参加运算的两个运算量,先进行算术运算,然后将结果赋予第一个运算量。另外,有正负号的运算符,如:-5,-a,-5相当于0-5,-a相当于a=0-a.,2020/9/14,C语言程序设计,37,2.5 关系运算和逻辑运算,2020/9/14
44、,C语言程序设计,38,2.5.1 关系运算,关系运算是对两个运算量进行大小关系等比较。关系运算的表达式称为关系表达式。与其它程序语言类似,C语言提供了如下6种关系运算符: 表2.5.1 关系运算符 关系运算符 = b a=b ab a=b a= =b a! =b 说明 结果值为0或1。当关系表达式表示的关系成立,值为1;否则为0。 优先级 高(以上四者同级) 低(以上两者同级) 关系运算符经常用于流程控制中作为分支和循环的条件。所以,关系运算又称做二项运算。与之相应,关系表达式又称为二项条件表达式。,2020/9/14,C语言程序设计,39,2.5.2 逻辑运算,逻辑运算表示运算量之间的逻辑
45、关系。逻辑运算的表达式又称为逻辑表达式。C语言提供了如下三种逻辑运算符。 表2.5.2 逻辑运算符 逻辑运算符 ! /*只要ab和cd中一者成立,表达式结果为1*/,2020/9/14,C语言程序设计,40,2.6 位操作,位操作是对操作数以二进制位(bit)为单位进行数据加工。 C语言具有的位操作功能为位逻辑运算和移位操作。参加位操作的操作数必须是整型或字符型数据。,2020/9/14,C语言程序设计,41,2.6.1 位逻辑运算,位操作通常不象关系和逻辑运算符那样用在条件语句中。在C语言中,有如下几种位逻辑运算符。 表2.6.1 位逻辑运算符 位逻辑运算符 (4)(a)(a char b=
46、a1; printf(“%c”,b); 右移位操作与操作数的数据类型是否带符号有关。不带符号的操作数右移位时,左端出现的空位补零。带符号的操作数右移位时,左端出现的空位按原最左端位复制。无论什么操作,移出右端的位都被舍弃。 例2.6.6,char a=-8,b=a2,求b。 a在二进制中的表示为:1 1 1 1 1 0 0 0, 右移2位得: 1 1 1 1 1 0, 左端空位按原首位复制: 1 1 1 1 1 1 1 0 = -2。 所以,b为-2。,2020/9/14,C语言程序设计,44,例2.6.7,unsigned char a=248,b=a2,求b。 a在二进制中的表示为:1 1
47、 1 1 1 0 0 0, 右移2位得: 1 1 1 1 1 0, 左端空位补零得: 0 0 1 1 1 1 1 0 =62。 所以,b为62。 以上两例中变量a的数值的二进制表示形式相同,但是右移2位 后,结果是不同的。可以看出,每右移一位,其结果相当于操作数除以2的值;左移一位则相当于操作数乘以2的值。值得注意的是,操作数的移位操作并不会改变操作数本身的数值。移位操作可以对外部设备(如:D/A转换)的输入状态信息进行译码,还可以用于整数的快速乘除法。 分析下面程序的输出结果。 例2.8.8, main() char a=0 xa,c=-3; unsigned char b=02;y=b2;
48、 char x=a1;z=c3; printf(“x=%c,y=%c,z=%cn”,x,y,z); ,2020/9/14,C语言程序设计,45,2.6.3 位操作赋值运算,上述两类位操作可以和赋值运算结合成位操作赋值运算。在C语言中,有以下赋值运算符。 表2.6.3 赋值运算符 赋值运算符 x的结果为64。 由于逗号表达式是一个运算表达式,所以在程序中可以作为一个单一语句使用。值得注意的是 ,并不是在任何地方的逗号表达式都作为运算符使用。例如:在printf(“%d,%d,%d,%d.n”,a,b,c,d);和printf(“%d,%d.n”,(a,b),(c,d);中, (a,b)和(c,d
49、)中的逗号为运算符,“%d,%d,%d%d”以及a、b、c、d间的逗号为函数参数分隔符。,2020/9/14,C语言程序设计,49,2.7.3 运算顺序,到此为止,我们讨论了C语言具有的主要运算功能。除此之外,C语言还有几种运算,这将在以后各章中陆续介绍。可以看出C语言的运算功能十分完善,运算种类多于其它程序设计语言。因此,当多种不同运算组成一个运算表达式,即一个运算式中出现多种运算符时,运算的优先顺序和结合规则显得十分重要。 C语言运算符的优先级自最高级至最低级的次序见下表2.7.1。,2020/9/14,C语言程序设计,50,表2.7.1 C语言运算符及其优先级 - 指向结构体成员运算符
50、。 结构体成员运算符 按位取反运算符 + + 自增运算符 - - 自减运算符 14 - 负号运算符 单目运算符 自右至左 (类型) 类型转换运算符 * 指针运算符 其中“v=%fn”是指定的输出格式,而第二个v是输出项,它们之间用逗号割开。 Printf()函数的功能是按照给定的输出格式把输出项输出到显示器或标准输出设备上,输出格式中用%打头后面跟有一个对格式进行描述的字符串,并以前一章所描述的转换字符结束的转换说明字符串(格式描述符)。它规定了输出项的输出形式,其中“”中也包括了一些普通输出字符,它们将简单的复制显示。 格式描述符的完整格式为: % +/- o m.n l/n 格式字符 ,2
51、020/9/14,C语言程序设计,54,格式字符(转换说明符) 格式字符指定输出项数据的数据类型和输出格式。各自具体意义如下: 表2.8.1只带格式字符的格式描述符,表示形式 说明,%c 输出 单一字符,%d或%i 输出十进制整数,%e或%E 输出指数型浮点小数,%f 输出 小数形式的浮点小数,%g或%G 选用%e、%f格式中输出较短的一种输出,%p 输出变量内存地址,%s 输出字符串,%u 输出不带符号的十进制整数,%x或%X 输出十六进制整数,%0 输出八进制整数,% 输出%本身,2020/9/14,C语言程序设计,55,长度修正符 整型格式描述符未区分int、short、long、实型,
52、也未区分float与double型。这个修正符具体作用就是加强说明。 长度修正符分别为: 整型的long型:%ld,%lx,%l0,%lu 实型的double型:%lf h: 整型的short型:%hd,%hx,%h0,%hu 未修正的分别为:int型:%d,%x,%0,%u float型:% e,%f,%g 域宽及精度描述符 m:指域度,即输出项显示的字符所占用的字数 n:精度,即实型数输出的小数位数。当不指定n时,缺省值n为6 当然,正整数m、n可任意缺省。 例2.8.2, main() float a=1.23; printf(“%6.3f”,a); 程序输出结果为: 1 . 2 3 0
53、 其中符号表示空格。,2020/9/14,C语言程序设计,56,在输出字符串时,m、n中m指定了输出字符串占用的字符位置长度,而n指定了实际输出的字符个数。 例2.8.3,有如下语句段: static char a =“ABCDE”; printf(“%5.3s”,a); 占用5个字符位置,而实际输出了三个字符: ABC 值得注意的是,域宽和精度只描述了数据的输入,并不能改变数据的实际精度。 例2.8.4, main() int x=1; printf(“%5.2dn”,x); printf(“%dn”,x,); 输出结果为: 1,输出结果为:ABC, 0 1 ,2020/9/14,C语言程序
54、设计,57,不使用空位补零的指定 这个指定仅用于输出数值时使用。当给出0时,不使用的输出位置自动填0,不指定时,用空格填充。 例2.8.5,有如下程序: main() int a=123; printf(“%05dn”,a); printf(“%5dn”,a); 程序输出结果为: 0 0 1 2 3 1 2 3 指定输出位置 指定“+”时,可以省略,指定输出字符靠近输出位置右端(右对齐);指定“-”时,指定输出字符靠近输出位置左端(左对齐)。,2020/9/14,C语言程序设计,58,充分了解和灵活运用printf()函数的转换说明符,就可以按要求的格式输出各个输出项的内容,同时,输出项可以是
55、多个。 例2.8.7,有如下语句:printf(“%d%x%f”,a,b,c); 这时,输出格式中的转换说明符与输出项的个数应该一致。当转换说明符的个数少于输出项的个数时,它们按自左至右的顺序一一对应的输出,多余项无效。当转换说明符的个数多于输出项的个数时,它们按自左至右的顺序一一对应的输出,多余的说明符则输出不定值(有些型号的计算机输出“0”)。转换说明符类型必须与与之对应的输出项的类型相匹配,否则会出现错误输出。 例2.8.7,分析下列程序的输出结果。 main() int a,b; a=10;b=25; printf(“a=%d,b=%dn”,a,b); printf(“a+b=%dna
56、-b=%dn”,a+b,a-b); a=10,b=25 a+b=35 a-b= -15 从上例中可以看出,转换说明符不仅规定了输出格式,而且也决定了输出项在整个输出信息中的位置。例2.8.7中输出项a的位置就是输出格式中与它相对应的转换说明符的位置,即“a=”后面“%d”的位置。此外,从上面也可以看出,输出项可以是运算表达式,这时输出的是它的运算结果。,运行结果为:a=10,b=25,例2.8.8,程序段:printf(“%5sn”,”ABCDE”);的输出结果为:ABCDE,2020/9/14,C语言程序设计,59,(2)输入函数scanf() 输入函数scanf()的一般形式如下 scan
57、f(“输入格式控制参数”,输入项系列); 其中“输入项系列”必须为地址量。其功能为:按格式参数的要求,从标准输入文件中读取数据,将读取的数据传送到地址参数所指定的内存空间中。当输入数据后,按回车键“”,scanf()函数才能接收到输入的数据。地址量为通过对变量求地址得到,具体运算为: 若输入:12345678765.43 则i接收123,f接收8765.43。 若认为共享时,哪一个数据不需要,可以用此法“跳过”这些无用数据。 在学习中,需要注意输入分隔符的指定。在C语言中,scanf()函数可以用空白字符(空格、Tab和回车符)作为隐含分割符使用。除此之外,还可以指定其它字符作为输入分割符使用,方法是:在双引号包围的输入格式中,两个转换说明符“%”之间出现的字符就是它们对应输入项之间的分割符。 例2.8.10,有下列输入形式 scanf(“%d:%d:%d”, /*用非char型返回值中,除正常代码值之外,还有EOF(-1)*/ printf(“Enter a character:n”); c=getchar(
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026六年级数学下册 负数方法拓展
- 【 生物 】生命的延续和发展(第一、二章)复习课件-2025-2026学年人教版生物八年级下册
- 2024高考语文复习的重点
- 中风昏迷患者护理
- 安全生产四查制度讲解
- 美图M8 AI美颜技术
- 2023长春某中学高三数学(理)期末试题及答案
- 2023年军队文职人员招录考试《档案专业》考前模拟题及答案
- 智能化弱电机房工程防雷接地知识
- 制度型开放的理论逻辑与现实路径阅读札记
- 高铁动车乘务应急处理
- 心力衰竭的治疗(基层诊疗与指南2024)
- 《绿》听评课记录
- 【MOOC】近现代船舶工业发展与中国崛起-江苏科技大学 中国大学慕课MOOC答案
- 食堂供货商考核评分表
- 大疆在线测评100题
- 学前儿童德育教育教学-第一章学前儿童道德教育概述课件
- 注册监理工程师-合同管理复习资料
- 福建省能化集团招聘笔试真题
- DB43-T 3000-2024 松材线虫病治理工程监理技术规程
- 河北省九校联盟2023-2024学年高一下学期期中考试数学试题(解析版)
评论
0/150
提交评论