赋值运算符和赋值表达式

1. 赋值运算符

赋值符号“=”就是赋值运算符,它的作用是将一个数据赋给一个变量。如“a=3”的作用是执行一次赋值操作(或称赋值运算)。把常量3赋给变量a。也可以将一个表达式的值赋给一个变量。

2.类型转换

如果赋值运算符两侧的类型不一致,但都是数值型或字符型时,在赋值时要进行类型转换。

(1)将实型数据(包括单、双精度)赋给整型变量时,舍弃实数的小数部分。如i为整型变量,执行“i=3.56”的结果是使i的值为3,在内存中以整数形式存储。

(2)将整型数据赋给单、双精度变量时,数值不变,但以浮点数形式存储到变量中,如将23 赋给 float 变量f,即 f=23,先将23转换成23.00000,再存储在f中。如将23赋给 double 型变量d,即d=23,则将23补足有效位数字为23.000oopoooo0000,然后以双精度浮点数形式存储到d中。

(3)将一个double型数据赋给float变量时,截取其前面7位有效数字,存放到float变量的存储单元(32位)中。但应注意数值范围不能溢出。如:

float f;

double d=123.456789e100;

f=d;

就出现溢出的错误。

将一个float型数据赋给double变量时,数值不变,有效位数扩展到16位,在内存中以64位(bit)存储。

(4)字符型数据赋给整型变量时,由于字符只占1个字节,而整型变量为2个字节,因此将字符数据(8位)放到整型变量低8位中。有两种情况:

①如果所用系统将字符处理为无符号的量或对unsigned char型变量赋值,则将字符的8位放到整型变量低8位,高8位补零。例如:将字符‘\376’赋给int型变量i,如图3.11(a)所示。

②如果所用系统(如TurboC)将字符处理为带符号的(即signed char),若字符最高位为0,则整型变量高8位补0;若字符最高位为1,则高8位全补1(图3.11(b))。这称为“符号扩展”,这样做的目的是使数值保持不变,如变量c(字符‘\376’)以整数形式输出为一2,i的值也是一2。

(5)将一个 int,short,long型数据赋给一个char 型变量时,只将其低8位原封不动地送到char

型变量(即截断)。例如:

inti=289;

char c='a';

c=i;

赋值情况见图 3.12。c的值为 33,如果用“%c”输出c,将得到字符“!”(其ASCI码为 33)。

(6)将带符号的整型数据(int型)赋给long型变量时,要进行符号扩展,将整型数的16位送到long型16位中,如果int型数据为正值(符号位为0),则long型变量的高16位补0;如果int型变量为负值(符号位为1),则long型变量的高16位补1,以保持数值不改变。

反之,若将一个long型数据赋给一个int型变量,只将long型数据中低16位原封不动地送到整型变量(即截断)。例如:

int a;

long b=8;

a=b;

赋值情况见图 3.13。如果b=65536(八进制数0200000),则赋值后a值为0。见图

3.14。如果b=020000000000(八进制数),赋值后a也为 0。请读者自己分析。

(7)将unsigned int型数据赋给long int型变量时,不存在符号扩展问题,只需将高位补0即可。将一个unsigned类型数据赋给一个占字节数相同的整型变量(例如: unsigned int→int,unsigned long→long,unsigned short→short),将unsigned型变量的内容原样送到非unsigned型变量中,但如果数据范围超过相应整型的范围,则会出现数据错误。如:

unsigned int a=65535;

int b;

b=a;

将a整个送到b中(图3.15),由于b是int型,第1位是符号位,成了负数。根据补码知识

可知,b的值为-1,可以用

printf("%d",b);

来验证。

(8)将非unsigned型数据赋给长度相同的 unsigned型变量,也是原样照赋(连原有的符号位也作为数值一起传送)。如:

例3.9 有符号数据传送给无符号变量。

main()

{unsigned a;

int b=-1;

a=b;

printf("%u",a);

}

“%u”是输出无符号数时所用的格式符。运行结果为:65535

赋值情况见图3.16。如果b为正值,且在0~32767之间,则赋值后数值不变。

以上的赋值规则看起来比较复杂,其实,不同类型的整型数据间的赋值归根到底就是

一条:按存储单元中的存储形式直接传送。只要学过补码知识的,对以上规则是不难理解的。由于C语言使用灵活,在不同类型数据之间赋值时,常常会出现意想不到的结果,而编译系统并不提示出错,全靠程序员的经验来找出问题。这就要求编程人员对出现问题的原因有所了解,以便迅速排除故障。根据作者的经验,相当多的初学者(甚至还有不少有一定编程经验的人)在这方面常出错,而且不能很快地找出原因。因此本书对此做了较详细的说明,使读者在编程序和对程序排错时有所遵循。在学习本书时不必死记,这部分内容可以通过学生自学和上机实践来掌握。

3.复合的赋值运算符

在赋值符“=”之前加上其他运算符,可以构成复合的运算符。如果在“一”前加一个“十”运算符就成了复合运算符“+=”。例如,可以有:

a+=3 等价于 a=a+3

x*=y+8 等价于 x =x*(y+8)

x%=3 等价于 x=x%3

以“a+=3”为例来说明,它相当于使a进行一次自加(3)的操作。即先使a加3,再赋给a。同样,“x*=y+8”的作用是使x乘以(y+8),再赋给x。

为便于记忆,可以这样理解:

凡是二元(二目)运算符,都可以与赋值符一起组合成复合赋值符。C语言规定可以使用10种复合赋值运算符。即:

+=,-=.*=,/=,%=,<<=,>>=,&=.∧=,|=

后5种是有关位运算的。

C采用这种复合运算符,一是为了简化程序,使程序精炼,二是为了提高编译效率(这样写法与“逆波兰”式一致,有利于编译,能产生质量较高的目标代码。学过编译原理的读者对此容易理解,其他读者可不必深究)。

4.赋值表达式

由赋值运算符将一个变量和一个表达式连接起来的式子称为“赋值表达式”。

它的一般形式为

<变量><赋值运算符><表达式>

如“a=5”是一个赋值表达式。对赋值表达式求解的过程是:将赋值运算符右侧的"表达式”的值赋给左侧的变量,赋值表达式的值就是被赋值的变量的值.例如,“a=5”这个赋值表达式的值为5(变量a的值也是5)。

上述一般形式的赋值表达式中的“表达式”,又可以是一个赋值表达式。如:

a=(b=5)

括弧内的“b=5”是一个赋值表达式,它的值等于5.“a=(b=5)”相当于“b=5”和“a=b”两个赋值表达式,因此a的值等于5,整个赋值表达式的值也等于5。从附录Ⅱ可以知道赋值运算符按照“自右而左”的结合顺序,因此,“b=5”外面的括弧可以不要,即“a=(b=5)”和“a=b=5”等价,都是先求“b=5”的值(得 5),然后再赋给a,下面是赋值表达式的例子:

a=b=c=5 (赋值表达式值为5,a、b、c值均为5)

a=5+(c=6) (表达式值为11,a值为11.c值为6)

a=(b=4)+(c=6) (表达式值为10.a值为10,b等于4c等于6)

a=(b=10)/(c=2) (表达式值为5,a等于5.b等于10,c等于2)

赋值表达式也可以包含复合的赋值运算符。如:

a+=a-=a*a

也是一个赋值表达式。如果a的初值为12,此赋值表达式的求解步骤如下:①先进行“a-=a*a”的运算,它相当于a=a-a*a,a 的值为12-144=-132。②再进行“a+= -132”的运算,相当于a=a+(-132),a的值为-132-132=-264。

将赋值表达式作为表达式的一种,使赋值操作不仅可以出现在赋值语句中,而且可以以表达式形式出现在其他语句(如输出语句、循环语句等)中,如:

printf(" %d" ,a=b);

如果b的值为3,则输出a的值(也是表达式a=b的值)为3。在一个语句中完成了赋值和输出双重功能。这是C语言灵活性的一种表现。在第6章中将进一步看到这种应用及其优越性。

  • 13
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阳光向日葵之沈阳

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值