岔路口、自增与自减

By | 2015年11月22日

在前面的循环中,我们已经简单的介绍了自增和自减,我们今天就来正式的谈谈这种写法

很多时候,我们需要为某一个变量增加1,或是减少1

特别是在循环中。

我们可以使用常规的运算

假设:int foo = 0;

要使得此变量增加1,我们可以写为foo = foo + 1;

自减则可写成foo = foo – 1;

对于这种对变量自身进行加减的,可以使用+=和-=来代替

foo += 1;

foo -=1;

前后两种写法是等价的,不过值得注意的是,尽管两种写法的结果相同,但是+=和-=是两个单独的运算符!它们不是上述运算的简写!

C语言提供了前缀和后缀的自增和自减运算符,即++和–

这两个操作符都是单目操作符,它们的操作对象必须是一个可以修改的左值(例如变量)

显然(foo+1)++这样的操作是不合法的

 

foo += 1和++foo的效果是相同的

同理,foo -= 1与–foo效果相同

前两种写法不再做讨论,我们先从自增开始

前面已经说道过,自增操作分为前缀和后缀两种,而它们是有区别的,我们下面就用程序来展现这一区别

#include <stdio.h>

int main(void)
{
	int foo = 1;
	

	printf("%d\n", foo);
	printf("%d\n", foo++);
	printf("%d\n", foo);


	return 0;
}

编译并执行此代码后,显示如下(切记,不要随意删除或调整printf的结构,原因稍后谈到)

测试结果

测试1

第一个printf显示的是foo的初始化结果。我们在第二个printf中使用后缀自增,而printf输出的值却仍然为1

直到第三个printf我们才发现foo的值发生了改变

这说明对于后缀自增来说,它并不会立即改变操作的变量的值,而是等到下一个操作完成后才将其自增+1

这一点和使用i+=1是不一样的,如下图

测试2

测试2


对于后缀自减呢?请自行修改上面的代码并尝试(同样,不要因为偷懒把三个printf写为一个)

对于前缀自增(请将第九行替换为 printf(“%d\n”, ++foo);

你将得到和第二次试验相同的结果

这说明前缀自增会立即将变量的值+1,其效果类似与foo += 1

那么对于下面这个程序

#include <stdio.h>

int main(void)
{
	int foo = 0;
	int bar = 0;

	bar = foo++ +1;

	printf("%d", bar);

	return 0;
}

运行后会得到什么结果?

 

答案是比1大1的数

因为使用后缀自增,所以foo的值不会立即改变,于是上面程序就变成了

bar = 0 + 1

foo = foo + 1

你可以将后缀改为前缀,再看会有什么变化

 

如果你搞定了上面一个,请看下面的表达式

(foo++)+(++foo)+(foo++)

foo的初始值为0,请问运行后表达式的值为多少?

这是国内许多教材里的内容,而且考试中还会遇到如此的题目。

那么这样的式子到底应该怎么计算呢?

答案是:不知道

这个表达式的值是不确定的,在不同编译器上,甚至是在同一个编译器上使用不同的方式编译

得到的结果可能都是不一样的!

这种行为称为UB(undefine behavior),未定义行为,对于这个概念,我们将在后面讲到

切记,你不应该在一个表达式内多次使用自增,自减操作!

发表评论

电子邮件地址不会被公开。 必填项已用*标注