那些年面试官搞的“骚”操作!! 用一篇文章彻底搞懂自增自减

自增运算符在笔试的时候出现的概率很高,这种题目也很恶心,分析起来很废脑细胞,而且一旦有一步分析错误,结果就不对了。

下面给大家总结一些常见的题目,基本上覆盖了所有和单目运算符相关的题型。

做题目之前,先要弄懂前置和后置的区别,也许题目会很复杂,但基本原则是不会变的。

a++:执行a所在语句之后,a的值加1;
++a:执行a所在语句之前,a的值加1。

先来看一道入门题

#include <stdio.h>int main()
{    
	int a = 1;printf("a = %d\n", a++);    
	printf("a = %d\n", ++a);return 0;
}

运行结果如下:
在这里插入图片描述
分析:​

后置++先执行a所在语句,所以可以默认把++运算符去掉,于是,语句变成了输出整数a,只不过在语句运行结束后,记得还有个后置的++没有执行,a的值还要加1。于是结果就变成了输出1,但是a的值实际已经变成了2。

前置++先执行a加1操作,即a变成了3(2+1),最后再执行输出语句。所以结束是打印3。

难度加大一点

#include <stdio.h>int main()
{    
	int a = 4;    
	a += a++;     
	printf("a = %d\n", a);​    
	
	a = 4;    
	a += ++a;    
	printf("a = %d\n", a);​    

	a = 4;   
	++a += a;    
	printf("a = %d\n", a);​    

	a = 4;    
	++a += a++;        
	printf("a = %d\n", a);​    

	a = 4;    
	++a += ++a;    
	printf("a = %d\n", a);return 0;
}

注意:编译的时候,选择C++的编译器(g++)编译,C编译器不支持前置++作为左值!!

运行结果:

在这里插入图片描述
分析:

这个题目很多同学会急着把+=运算符展开,如果展开的话,结果就容易出问题。第一个,先不要管后置++,当作:

a += a;

a的值是8。但是后置++运算符是被我们默认去掉的,所以最后还得记得a加1,于是结果是9;

第二个,前置++,a先要加1,变成了5,5+5=10;

第三个,同第二个,都是前置++;

第四个,后置++先不要看,有一个前置++,执行a加1变成了5,5+5=10,最后再执行后置++操作,结果是11;

第五个,两个前置的++,于是a变成了6,结果6+6=12。

自增运算符结合逻辑运算符

#include <stdio.h>int main()
{    
	int x = 1, y = 1;if (x++ == 2 && ++y == 2)    
	{           
		printf("helloworld!\n");    
	}printf("x = %d, y = %d\n", x, y);return 0;
}

在这里插入图片描述
分析:

逻辑运算符具有短路原则,很多同学忽略了这一点。判断语句:

x++ == 2

等价于:

x == 2; x = x + 1;

很显然判断不成立,但是此时x变成了2。逻辑运算符具有短路原则,所以:

++y == 2;

并不会执行!

再来一个升级版本

#include <stdio.h>int main()
{    
	int x = 5, y = 6, z;​    
	z = ++x + y++;    
	printf("x = %d, y = %d, z = %d\n", x, y, z);​    
	
	x = 5, y = 6;    
	z = ++x + x++;    
	printf("x = %d, y = %d, z = %d\n", x, y, z);​    
	
	x = 5, y = 6;    
	x = ++x + x++;    
	printf("x = %d, y = %d, z = %d\n", x, y, z);​    
	
	x = 5, y = 6;    
	z = x > y ? ++x : y++;     
	printf("x = %d, y = %d, z = %d\n", x, y, z);return 0;
}

Ubuntu运行结果:

在这里插入图片描述

Visual Studio 2012运行结果:

在这里插入图片描述
这个题目就比较恶心了,因为不同的编译器处理的结果还不一样。我们来看VS的结果吧,这个结果还比较符合常规思想。

第一个,等价于:

z = 6 + 6;

只是运算结束了,y的值还要再加1;

第二个,等价于:

z = 6 + 6;

只是运算结束了,x的值再加1;

第三个,等价于:

x = 6 + 6;

运算完成,x的值再加1,结果是13;

第四个,++x不会执行,执行y++,结果没有疑问。

最后再来一个终极装逼版

#include <stdio.h>int main()
{    
	int i = 3, k;    
	k = (++i) + (++i) + (i++);    
	printf("i = %d, k = %d\n", i, k);​    
	
	i = 3;    
	k = (++i) + (++i) + (++i);    
	printf("i = %d, k = %d\n", i, k);​   
	
	i = 3;    
	k = (i++) + (i++) + (i++);    
	printf("i = %d, k = %d\n", i, k);return 0;
}

Ubuntu运行结果:

在这里插入图片描述

Visual Studio 2012运行结果:

在这里插入图片描述

此时,我的心情是:

在这里插入图片描述

遇到这种笔试题,你可以鄙视他一下,扔掉考卷走人(想想就行,找工作要紧)! 这种题目不同的平台运行结果不同,如果不指定编译器,根本没有结果。 出这个题目的面试官可能自己也没有搞清楚,纯粹出于装逼的考虑。不看别的,就扫一眼这个代码,怎一个“骚”字了得。开发中谁没事写这样惨绝人寰代码?

继续分析!

第一个简单,先运算两次前置++,i变成了5,计算一次结果10;再运算10+5,结果为15,但是i还要再加1。(其实VS和Linux编译器过程不一样,这题只是个巧合)

第二个,Linux先运行两次前置++,i变成了5,进行一次计算5+5结果为10,然后再运算最后一个++i,i变成了6,于是结果为16;VS的过程是先进行三次前置++操作,结果不一样!

第三个,Linux等价于:

k = 3 + 4 + 5;//第一个i++,结果是3,但是i的值变成了4作为第二个i++初值

VS编译器等价于:

k = 3 + 3 + 3

运算结束,i再加3次!

文章写完,键盘上又多了两根头发,笔试题确实比较费脑子!自增或者自减操作大家必须要把原理搞懂,这个才是最重要的。至于这些复杂的或者没有标准答案的题目,更多的是在考查大家对单目运算符的理解,多看多写多总结!

单目运算符还经常和指针结合,大家可以自己总结一下,对笔试有百利而无一害。

更多精彩视频、文章,关注 学益得智能硬件!

在这里插入图片描述

发布了10 篇原创文章 · 获赞 21 · 访问量 1324

猜你喜欢

转载自blog.csdn.net/xiaopengX6/article/details/104287171
今日推荐