短路现象(陷阱)

这个刚开始学的时候还是比较容易出错的.

直接把老师给的复习题拿出来.

目录

题目一:

题目二:

题目三:

编译器:


题目一:

#include<stdio.h>
int main(){
	int x,y,z,w;
	x=y=z=0;
	w=++x||++y&&++z;
	printf("x=%d,y=%d,z=%d,w=%d\n",x,y,z,w);
	return 0;
}

第一次看到这种题目我人是懵的,首先对他分析就是从左往右执行,先执行++x,因为++在前面,所以他是先对他的值进行自增操作再计算整个表达式的值,所以x的值变成了1,那么或运算右边的值还需要计算吗,其实程序他是直接没运算了,这种就是短路现象,或运算是两边只要有一个值为true他的结果就是true了,C语言里面true就是1,非零数都是true,(应该可以这样说吧,说的不对的话,希望大家可以指正),于是程序想反正左边的结果已经是true了,那么右边我就不运算了,反正最后的结果已经确定是true.故而导致++y和++z都没有参与运算,所以y=z=0,但是x已经变成1了,w也因为x的值为1,整个表达式的值就是1,

x=1,y=0,z=0,w=1
Press any key to continue

不知道大家写对了不,那就趁热打铁写下一道题.

题目二:

#include<stdio.h>
int main(){
	int x,y,z,w;
	x=y=z=0;
	w=x++||y++&&z++;
	printf("x=%d,y=%d,z=%d,w=%d\n",x,y,z,w);
	return 0;
}

直接公布答案

x=1,y=1,z=0,w=0
Press any key to continue

相信大家都写对了,没有写对了也不用灰心,听我细细道来.

x++的++在x的后面,所以他是先把x值参与运算,在运算之后将x的值进行自增操作.

#include<stdio.h>
int main(){
	int x1,x2;
	x1=x2=1;
	x1=++x1*10;
	x2=x2++*10;
	printf("x1=%d\n",x1);//x1=20
	printf("x2=%d\n",x2);//x2=11
	return 0;
}

进行x++操作之后,或运算左边的值依旧为0,对于逻辑值就是false,所以还是会就行右边的与运算,执行y++语句y的值仍旧是false,对于与运算来说,已经有一边的值为false,我的结果就已经确定了,那我另一边的运算我就不管了.所以z++就不会执行,整个表达式的值因为都是后自增,所以w的值为false,x++,y++都有执行,所以值变成了1,z++没有执行,所以他的值还是0.

接着再写最后一题检测一下自己会了不.

题目三:

#include<stdio.h>
int main(){
	int x,y,z,w;
	x=y=z=-1;
	w=++x&&++y||++z;
	printf("x=%d,y=%d,z=%d,w=%d\n",x,y,z,w);
	return 0;
}
x=0,y=-1,z=0,w=0
Press any key to continue

这个题目不知道大家有没有疑问,我当时写这个的时候是写错了的,先执行++x之后,x的值变成了0,所以与运算的右边是需要执行的吧,但是结果是++z执行了,++y却没有执行,不应该是++x之后运算式子就变成了++y||++z吗,然后先执行++y操作.这个其实和第二个题目就是对应的,当时我就感觉这两个总有一个程序出错了,但是程序不会骗人.

这种想法直到我考虑到了优先级,一切就变得清晰明了了,逻辑与(&&)优先级是11,而逻辑或(||)优先级是12,所以会先执行&&运算,那这个在程序中又怎么看呢?

后面我询问学长,他教了我一种方法就是,可以给表达式加上括号,w=x++||y++&&z++;就变成了w=x++||(y++&&z++);这是没问题的把,括号的优先级是1,把括号里面看成一个整体,当或运算左边为true的时候,右边就不用执行了,当左边为false的时候,把括号里面的与运算看成一个新的表达式来进行计算.

w=++x&&++y||++z;就变成了w=(++x&&++y)||++z;这个也就可以解释了,当++x变成0之后,与运算的结果就变成了false,所以他左边的++y也就不会执行了,但是++z还需要执行,因为尽管他左边括号里面的值为false,但是他整个表达式的还是需要右边来确定,当++z为true,整个表达式就是true,当++z为false,整个表达式的值就为false.

编译器:

其实之前我还是挺纠结编译器的,因为我当时发现有些运算结果的不一样,但是我又不知道其中的原理,

 后面两个运行结果是一致的.这些还算正常,直到我学到了虚函数.一切就变得不一样了.

#include<iostream>
using namespace std;
class base{
public:
	int a;
};
class base1:virtual public base{
public :
	int b1;
};

class base2:virtual public base{
public:
	int b2;
};
class base3:public base1{
public:
	int b3;
};
class base4:public base2{
public:
	int b4;
};
class base5: public base{ 
 public: 
	int b5;
 };
class base6: public base5{ 
 public:
	 int b6;
};
class  der: public base3,public base4,public base6{ 
public: 
	int d;
 };
int main(){ 
	cout<<"sizeof(base)="<<sizeof(base)<<endl;
	cout<<"sizeof(base1)="<<sizeof(base1)<<endl;
	cout<<"sizeof(base2)="<<sizeof(base2)<<endl;
	cout<<"sizeof(base3)="<<sizeof(base3)<<endl;
	cout<<"sizeof(base4)="<<sizeof(base4)<<endl;
	cout<<"sizeof(base5)="<<sizeof(base5)<<endl;
	cout<<"sizeof(base6)="<<sizeof(base6)<<endl;
	cout<<"sizeof(der)="<<sizeof(der)<<endl;
	return 0;
}

继承关系好理解,那么直接上运行结果.

Visual C++6.0

 Visual Studio2022

 Dev-C++

 当然这些其中的原理我目前还不知道,现在就是避免这些的发生,希望有知道的大佬可以告诉我,对了,大家可以自己验证一下,这结果是不是正确,是我故意改了一下程序,导致结果不一样的也说不定.

最后希望能够帮助到大家!!!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

封奚泽优

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

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

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

打赏作者

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

抵扣说明:

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

余额充值