上一期说了两个分别和sizeof运算符和求模运算符:%,讲解了他们的作用和相关的应用。具体来讲讲余下的两个,分别是递增运算符++和递减运算符--。
递增运算符++
说白了就是对作用对象加一。有两种加一的方式,一种是放在变量之前(前缀模式),另一种则是放在变量之后(后缀模式)。他们的区别在于作用的时间不同,演示一个书上的例子
/*add_one.c -- 递增:前缀和后缀*/
#include <stdio.h>
int main (void)
{
int ultra = 0;
int super = 0;
while(super < 5)
{
super++;//super = super + 1;
++ultra;//ultra = ultra + 1
printf("super = %d, ultra = %d \n", super, ultra);
}
return 0;
}
程序输出结果为:
super = 1, ultra = 1
super = 2, ultra = 2
super = 3, ultra = 3
super = 4, ultra = 4
super = 5, ultra = 5
这个程序中没有让人感觉到两种用法有什么区别,只是显示了++运算符的作用, 和注释里的语句效果也是一样的。那么问题来了,既然有了注释中的那种简单的语句,干嘛还要加入递增运算符这种东西呢?
答案是为了让程序更美观,看上去更简洁,提高可读性,书上也给出了例子,修改本章的引入程序shoes2.c
原程序是这样的:
/*shoes2.c -- 把鞋码换成英寸*/
#include <stdio.h>
#define ADJUST 7.13
int main(void)
{
const double SCALE = 0.333;
double shoe, foot;
shoe = 3.0;
printf("Shoe size (men's) foot length\n");
while(shoe <= 18)
{
foot = SCALE * shoe + ADJUST;
printf("%10.1f %15.2f inches\n", shoe, foot);
shoe = shoe + 1;
}
return 0;
}
现在对while循环中的语句进行改动,很容易可以看出,可以改动shoe = shoe + 1;这条语句,将其改成++shoe;或者shoe++;效果也是一样的。但这还是不够简洁,还可以接着该,将这条语句去掉,改动while()内的内容,
while(++shoe <= 18)
{
foot = SCALE * shoe + ADJUST;
printf("%10.1f %15.2f inches\n", shoe, foot);
}
这样的结构在C语言中很普遍,我们顺便借着这次机会再将一讲while循环的工作原理。
在while的判断语句中,先对变量shoe加了1,然后将加过1的shoe值赋给shoe,说白了就是shoe = shoe + 1;的意思。赋值之后开始进行判断,true就继续执行{}内的语句,false就退出循环。如果你直接将这里的一小段复制粘贴到你的程序当中,运行之后你会发现少了一个shoe = 3的输出结果,这是因为这段程序在循环时先给shoe加了1,所以为了解决这个问题,你可以在shoe初始化时少赋值个1,如此运行结果就没什么问题了。
这样做的好处就是使得程序更加简洁。更重要的是,它将控制循环的两个过程放在同一个地方。该循环的主要过程是判断是否继续循环(shoe是否<=18),次要过程是改变待测元素(shoe的值)。
想像一下,如果将这里的++去掉或者忘记了原来的shoe = shoe + 1;会发生什么?
没错程序会不停的运行下去,一直输出shoe=3时的结果,输出无数行。
将两个控制放在同一个地方,一定程度上可以避免这样的情况发生。
但是缺点也同样存在,这种做法使得程序让人难以理解,而且会产生刚刚说的漏掉一组数据的情况。
递增运算符还有一个特性,在某些场合里会有一些作用,如下面的例子:
/*post_pre.c -- 前缀和后缀*/
#include <stdio.h>
int main(void)
{
int a = 1, b = 1;
int a_post, b_pre;
a_post = a++;//后缀递增
b_pre = ++b;//前缀递增
printf("a a_post b b_pre\n");
printf("%1d %6d %1d %5d\n", a, a_post, b, b_pre);
return 0;
}
输出结果如下:
a a_post b b_pre
2 1 2 2
从输出结果中我们可以看出,a 和 b 的值分别增加了1,这没什么好解释的了。重点在于a_post 和 b_pre。
先看看a_post ,它的值为1,他得到的是a的初始值1,说明++并没有对他产生影响。再来看 b_pre ,它的值是2,他得到的是b的最终值,说明是++的作用。两者对比,不难看出++放在前还是后是有区别的。放在前面会先给变量加上1,完后赋值;放在后面会先执行语句再加上1 。
总的来说就是一个先执行一个后执行的区别。
递减运算符:--
递减运算符和递加运算符差不多,区别就是一个是加一个是减。
优先级
在讲述基本运算符的时候,曾经讲过优先级的问题,就是小学生都会的结合律,这里又多了几个常用运算符,那么我们在来强调一下。
如下例:
x = 2 ;
y = 3 ;
z = x + y++*6 ;
现在有几种方式,A.(x + y++) * 6 B.(x + y)++ * 6 C.x + (y++ * 6)
这当然应该选择C了 ,可算到结果为(2+3 )*6=30,用其他方法算出的可能是不同的结果,但一定不是正确答案。
So,递增递减运算符有很高的优先级,只有圆括号的优先级比他高。
友情提示:正如上面所说,计算顺序出错可能在成严重的错误,为了避免这样的错误,最好不要使用很长的算式
在机房写今天的内容,手贱把网页关了,还好在word上保存过一部分,不然今天就凉了。