条件操作符
条件操作符介绍
条件操作符也叫三⽬操作符,需要接受三个操作数的,形式如下:
exp1 ? exp2 : exp3
条件操作符的计算逻辑是:如果 exp1 为真, exp2 计算, exp2 计算的结果是整个表达式的结果;如果 exp1 为假, exp3 计算, exp3 计算的结果是整个表达式的结果。
这种三⽬操作符和 if 语句的逻辑⾮常相似,就是根据 exp1 的结果来选择执⾏ exp2 ,或者exp3 。⼀般使⽤在简单的逻辑判断中。
练习:
使⽤条件操作符表⽰下⾯代码的逻辑
#include <iostream>
using namespace std;
//改造前:未使⽤条件操作符
int main()
{
int a = 0;
int b = 0;
cin >> a;
if (a > 5)
b = 3;
else
b = -3;
cout << b << endl;
return 0;
}
//改造后:使⽤了条件操作符
#include <iostream>
using namespace std;
int main()
{
int a = 0;
int b = 0;
cin >> a >> b;
b = (a > 5 ? 3 : -3);
cout << b << endl;
return 0;
}
练习
B2049 最大数输出
#include <iostream>
using namespace std;
int a, b, c;
int main()
{
cin >> a >> b >> c;
int ret = 0;
if (a < b)
ret = b > c ? b : c;
else
ret = a > c ? a : c;
cout << ret << endl;
return 0;
}
特殊计算
#include <iostream>
using namespace std;
long long x, y;
int main()
{
cin >> x >> y;
long long z = 0;
if (y % x == 0)
z = x + y;
else
z = y - x;
cout << z << endl;
return 0;
}
int main()
{
cin >> x >> y;
long long z = 0;
z = (y % x == 0 ? x + y : y - x);
cout << z << endl;
return 0;
}
要注意数据范围的问题,选择适当的数据类型:
这样的数据范围,其实 int 类型是⽆法满⾜的,只能使⽤ long long 类型。
P5709 【深基2.习6】Apples Prologue / 苹果和虫子
#include <iostream>
using namespace std;
int m, t, s;
int main()
{
int ret = 0; //剩余的苹果数
cin >> m >> t >> s;
//处理t为0的特殊情况
if (0 == t)
{
cout << 0 << endl;
return 0; //main函数直接返回
}
if (s % t == 0)
ret = m - s / t;
else
ret = m - s / t - 1;
if (ret < 0)
ret = 0;
cout << ret << endl;
return 0;
}
特殊情况分析
- t可能是0,t会被当做除数,⽽除数不能是0,所以可能会导致运⾏时错误的。如果不增加特殊处理,就会有问题,题⽬最后有提示。
- 根据题⽬给出的数据,算出的吃掉的苹果数可能要⽐真实的苹果还多,这样会计算出负数,这也是不允许的,最多就是吧苹果吃完,⼀个都不剩余。
- 题⽬中有些特殊情况,没有提⽰,有时候需要从数据上做推断。
逻辑操作符
逻辑运算符提供逻辑判断功能,⽤于构建更复杂的表达式,主要有下⾯三个运算符。
符号 | 名称 | 功能 |
---|---|---|
! | 逻辑取反运算符 | 改变单个表达式的真假状态。如果表达式为真,则结果为假;如果表达式为假,则结果为真。 |
&& | 逻辑与运算符 | 两侧的表达式都需要为真时,结果才为真。如果任何⼀个表达式为假,结果就为假。 |
|| | 逻辑或运算符 | 两侧的表达式中,只要有⼀个为真,结果就为真。只有当两个表达式都为假时,结果才为假。 |
C/C++中,⾮0表⽰真,0表⽰假 |
逻辑取反运算符
a | !a |
---|---|
非0 | 0 |
0 | 1 |
⽐如,我们有⼀个变量叫 flag ,如果 flag 为假的时候,就做某些事情,可以这样写代码: |
#include <iostream>
using namespace std;
int main()
{
int flag = 0;
if (!flag)
{
cout << "do something" << endl;
}
return 0;
}
如果 flag 为真, !flag 就是假,如果 flag 为假, !flag 就是真,所以上⾯的代码的意思就是flag 为假,执⾏if语句中的代码。
逻辑与运算符
a | b | a&&b |
---|---|---|
非0 | 非0 | 1 |
非0 | 0 | 0 |
0 | 非0 | 0 |
0 | 0 | 0 |
&& 就是与运算符,也是并且的意思, && 是⼀个双⽬操作符,使⽤的⽅式是 a&&b , && 两边的表达式都是真的时候,整个表达式才为真,只要有⼀个是假,则整个表达式为假。 | ||
⽐如: | ||
如果我们说⽉份是3⽉到5⽉,是春天 |
int month = 0;
cin >> month;
if (month >= 3 && month <= 5)
{
cout << "春季" << endl;
}
这⾥表达的意思就是 month 既要⼤于等于3,⼜要⼩于等于5,必须同时满⾜。
逻辑或运算符
a | b | a||b |
---|---|---|
非0 | 非0 | 1 |
非0 | 0 | 1 |
0 | 非0 | 1 |
0 | 0 | 0 |
|| 就是或运算符,也就是或者的意思, || 也是⼀个双⽬操作符,使⽤的⽅式是 a || b , || 两边的表达式只要有⼀个是真,整个表达式就是真,两边的表达式都为假的时候,才为假。
⽐如:
我们说⼀年中⽉份是12⽉或者1⽉或者2⽉是冬天
int month = 0;
cin >> month;
if (month == 12 || month == 1 || month == 2)
{
cout << "冬季" << endl;
}
短路
逻辑运算符还有⼀个特点,它总是先对左侧的表达式求值,再对右边的表达式求值,这个顺序是保证的。
如果左边的表达式就能确定整个表达式的结果,就不再对右边的表达式求值。这种情况称为“短路”。
if ( month >= 3 && month <= 5 )
表达式中 && 的左操作数是 month >= 3 ,右操作数是 month <= 5,当左操作数 month >= 3的结果是0的时候,即使不判断 month <= 5 ,整个表达式的结果也是 0 (不是春季)。
所以,对于 && 操作符来说,左边操作数的结果是 0 的时候,右边操作数就不再执⾏。
if ( month == 12 || month == 1 || month == 2 )
如果 month == 12 ,则不⽤再判断 month 是否等于 1 或者 2 ,整个表达式的结果也是 1 (是冬季)。
所以, || 操作符的左操作数的结果不为 0 时,就⽆需执⾏右操作数。
像这种仅仅根据左操作数的结果就能知道整个表达式的结果,不再对右操作数进⾏计算的运算称为短路求值。
习题
P5711 【深基3.例3】闰年判断
#include <iostream>
using namespace std;
int n;
int main()
{
cin >> n;
if (n % 4 == 0 && n % 100 != 0)
cout << 1 << endl;
else if (n % 400 == 0)
cout << 1 << endl;
else
cout << 0 << endl;
return 0;
}
int main()
{
cin >> n;
if ((n % 4 == 0 && n % 100 != 0) || (n % 400 == 0))
cout << 1 << endl;
else
cout << 0 << endl;
return 0;
}
闰年判断的规则:
- 能被4整除并且不能被100整除是闰年
- 能被400整除是闰年
⼝诀:四年⼀闰,百年不闰,四百年再闰
B2045 晶晶赴约会
#include <iostream>
using namespace std;
int n;
int main()
{
cin >> n;
if (n == 1 || n == 3 || n == 5)
cout << "NO" << endl;
else
cout << "YES" << endl;
return 0;
}
⼀定要注意输出信息⼤⼩写的要求,写错了,是不能AC的
B2050 三角形判断
#include <iostream>
using namespace std;
int a, b, c;
int main()
{
cin >> a >> b >> c;
if (a + b > c && a + c > b && b + c > a)
cout << 1 << endl;
else
cout << 0 << endl;
return 0;
}
三⻆形的任意两条边的和⼤于第三条边。
B2043 判断能否被 3,5,7 整除
#include <iostream>
using namespace std;
int x;
int main()
{
cin >> x;
int flag = 1;
if (x % 3 == 0)
{
cout << 3 << ' ';
flag = 0;
}
if (x % 5 == 0)
{
cout << 5 << ' ';
flag = 0;
}
if (x % 7 == 0)
{
cout << 7 << ' ';
flag = 0;
}
if (flag)
cout << 'n' << endl;
return 0;
}
B2043 判断能否被 3,5,7 整除
#include <iostream>
using namespace std;
int x;
int main()
{
cin >> x;
if (x % 3 == 0 && x % 5 == 0 && x % 7 == 0)
cout << "3 5 7" << endl;
else if (x % 3 == 0 && x % 5 == 0)
cout << "3 5" << endl;
else if (x % 3 == 0 && x % 7 == 0)
cout << "3 7" << endl;
else if (x % 5 == 0 && x % 7 == 0)
cout << "5 7" << endl;
else if (x % 3 == 0)
cout << "3" << endl;
else if (x % 5 == 0)
cout << "5" << endl;
else if (x % 7 == 0)
cout << "7" << endl;
else
cout << "n" << endl;
return 0;
}
#include <iostream>
using namespace std;
int x;
int main()
{
cin >> x;
if (x % 3 == 0)
cout << 3 << " ";
if (x % 5 == 0)
cout << 5 << " ";
if (x % 7 == 0)
cout << 7 << " ";
if (x % 3 != 0 && x % 5 != 0 && x % 7 != 0)
cout << "n" << endl;
return 0;
}
P5710 【深基3.例2】数的性质
#include <iostream>
using namespace std;
int x;
int main()
{
cin >> x;
if (x % 2 == 0 && (x > 4 && x <= 12))
cout << 1 << " ";
else
cout << 0 << " ";
if (x % 2 == 0 || (x > 4 && x <= 12))
cout << 1 << " ";
else
cout << 0 << " ";
if ((x % 2 == 0) + (x > 4 && x <= 12) == 1)
cout << 1 << " ";
else
cout << 0 << " ";
if ((x % 2 == 0) + (x > 4 && x <= 12) == 0)
cout << 1 << " ";
else
cout << 0 << " ";
return 0;
}