降低程序的可移植性)。 当较低类型的数据转换为较高类型时,一般只是形式上有所改变,而不影响数据的实质 内容,而较高类型的数据转换为较低类型时则可能有些数据丢失 例2.5 float x,y; i=1 2. y=(float ) printf ("i= %d, y= %fn",i, y)i printf("x=%f,j=%d\n, x,j)i 运行结果为 000000 这里y是由i转换而得到的,其值与i只是形式上不同,而j是由x转换得到的由于是 从转高的foat型转换为较低的int型,这时,小数点后面的内容被省略掉了 第六节增和减运算符 C语言对增加和减少变量的值提供了两个独特的运算符: 单目运算符++表示对变量加1 单目运算符一一表示对变量减1 +和一一既可用作前缀也可用作后缀如 +i(先把i值加1,然后再引用 i++(先引用i值,然后把i值加1) 在有些场合,前缀和后缀效果是一样的,如 while (line < PAGESIZE) 和 while (line<=PAGESIZE) 得到相同的结果。在这种情况下,你可以凭自己的喜好采用任何一种方式,而在另外一些场 合,效果却是不同的
例2.6 ino printf("i=%d, j=%d,k=%d, I=%d\n", i, j, k, D): 开始时都被赋初值3,语句 k=i++ 先把此时的i值3赋给k使k的值为3,然后i自己加1,值变为4。而语句 先是j自身加1,值变为4然后把值4赋给变量l的值也是4于是输出的结果为 需要注意的是: 增1减1运算都要求运算对象是变量 因此 ++5 都是错误的 +和一一运算符有和单目减一样的优先级,也就是说,比*、,%都要高,它们同样是 按从右到左结合的。 printi("%dn”,-i++); printf("%d\n",i); 输出结果为 程序中的表达式 相当于 i++) 也就是先取i的值2,求负后输出-2,然后i自身加1,输出3 需要提醒注意的是
增1减1操作有可能带来副作用 例2. 3 printf("‰d,%d,%d",i,i十+,i十+); 先考虑一下,结果应该是多少是345吗?在多数C中prnt中各输出参数的求值是 从右向左的也就是先求最后一个计++的值得到3后i自增1,再求前一个计+,得到值4 后i再自增1,最后求最左边的i值,变成了5,所以输出是 如果你希望输出3、4、5的话,可把输出语句改写成 printf("%d, %d, %dn",i,i+1, i+2); 结果将是 这里你可以看出 i++ +1 并不是一回事儿 第七节赋值运算符和赋值表达式 2.7.1赋值运算符 C语言中的赋值运算符是“=”,它的功能是把其右侧表达式的值赋给左侧的变量赋值 的一般形式为 变量=表达式 表示把数值1赋给变量a,也就是让变量a具有数值1 赋值运算符“=”不表示其左右两侧的内容相等(C语言中判断相等用符号“==”),而 表示把表达式的值送到变量代表的存储单元中去。由此,赋值运算符的左侧只能是变量,因 为它表示一个存放值的地方象 这样的赋值显然是不合法的 2.72赋值中的类型转换 当赋值运算符两边的运算对象类型不同时,将要发生类型转换,转换的规则是: 把赋值运算符右侧表达式的类型转换为左侧变量的类型
具体的转换如下 1.浮点型与整型 将浮点数(单双精度)转换为整数时,将舍弃浮点数的小数部分,只保留整数部分 将整型值赋给浮点型变量,数值不变,只将形式改为浮点形式,即小数点后带若干个0。 我们把例2.5稍做修改去掉强制转换操作把语句 oat )1: 改成 其余不变,运行结果仍是 i=1,y=1.00000 归此可以看出赋值时的类型转换实际上是强制的。 2.单、双精度浮点型 由于C语言中的浮点值总是用双精度表示的,所以foat型数据只是在尾部加0延长为 ouble型数据参加运算,然后直接赋值 double型数据转换为foat型时,通过截尾数来实现,截断前要进行四舍五入操作。 3char型与int型 int型数值赋给char型变量时,只保留其最低8位,高位部分舍弃。 char型数值赋给int型变量时,一些编译程序不管其值大小都作正数处理,而另一些编 程序在转换时,若char型数据值大于127,就作为负数处理。对于使用者来讲如果原来 har型数据取正值,转换后仍为正值;如果原来char型值可正可负则转换后也仍然保持原 值,只是数据的内部表示形式有所不同 4.int型与long型 long型数据赋给int型变量时,将低16位值送给int型变量,而将高16位截断舍弃。(这 里假定int型占两个字节)。 将int型数据送给long型变量时,其外部值保持不变,而内部形式有所改变。 5.无符号整数 将一个 unsigned型数据赋给一个占据同样长度存储单元的整型变量时(如; unsigned→ nt, unsigned long→long, unsigned short→ short),原值照赋,内部的存储方式不变,但外部值 却可能改变 将一个非 unsigned整型数据赋给长度相同的 unsigned型变量时,内部存储形式不变 但外部表示时总是无符号的。 例
it 1. a=65535; b nsigned)%u(int)%d\n",a,j); printf("(int)%d+(unsigned )%un",i, b) 运行结果为 (unsigned )65535-(int)-1 (int)-1-+(unsigned)65535 这里‰u用来输出一个无符号数图27给出了转换的过程 111111l11111111 l1ll11l1111111111 符号位 (an11 (unsigned)1111111111111111 符号位 a)无符号数转为有符号数 b)有符号数转为无符号数 计算机中数据用补码表示,int型量最高位是符号位,为1时表示负值,为0时表示正 值。如果一个无符号数的值小于32768则最高位为0,赋给int型变量后得到正值。如果无 符号数大于等于32768则最高位为1,赋给整型变量后就得到一个负整数值。反之,当一个 负整数赋给 unsigned型变量时,得到的无符号值是一个大于32768的值。 C语言这种赋值时的类型转换形式可能会使人感到不精密和不严格,因为不管表达式 的值怎样系统都自动将其转为赋值运算符左部变量的类型而转变后数据可能有所不同, 在不加注意时就可能带来错误。这确实是个缺点也遭到许多人们批评。但不应忘记的是 C语言最初是为了替代汇编语言而设计的,所以类型变换比较随意。当然,用强制类型转换 是一个好习惯这样,至少从程序上可以看出想干什么 2.7.3复合型赋值运算符 i=i+2 的表达式其意思是把i的内容取出加工,然后再赋给i,这时可用一个复合的赋值式运算符 写成如下形式 这样表示更紧凑也易于理解我们可以把它解释为“加2到i”。当变量名较长时,我们不必 把注意力放在关注两边变量否一致上 复合赋值运算符的形式是: