学习 › JavaScript
流程控制 · 08
布尔值与三元运算符
把真假存进变量、在两个值里选一个、问“是不是其中之一”。
在“条件语句”一课里,比较是直接写在 if 里的。
这次把比较的结果当作值来用。
下面的例子读入星期和游客的年龄,把“是不是周末”和“有没有儿童”存进变量,再输出门票的总和:周末每人 12,平日每人 8。
day = input().strip()ages = list(map(int, input().split())) weekend = day in ("sat", "sun") # 포함 검사의 결과(참·거짓)를 변수에 담아요child = False # 깃발: 아직 어린이를 못 봤어요for age in ages: if age < 13: child = True price = 12 if weekend else 8 # 두 값 중 하나를 골라요print("weekend" if weekend else "weekday")print(price * len(ages))print("child" if child else "adults")const lines = require("fs").readFileSync(0, "utf8").split("\n");const day = lines[0].trim();const ages = lines[1].trim().split(/\s+/).map(Number); const weekend = ["sat", "sun"].includes(day); // 포함 검사의 결과(참·거짓)를 변수에 담아요let child = false; // 깃발: 아직 어린이를 못 봤어요for (const age of ages) { if (age < 13) child = true;} const price = weekend ? 12 : 8; // 두 값 중 하나를 골라요console.log(weekend ? "weekend" : "weekday");console.log(price * ages.length);console.log(child ? "child" : "adults");import { readFileSync } from "node:fs";const lines: string[] = readFileSync(0, "utf8").split("\n");const day: string = lines[0].trim();const ages: number[] = lines[1].trim().split(/\s+/).map(Number); const weekend: boolean = ["sat", "sun"].includes(day); // 포함 검사의 결과(참·거짓)를 변수에 담아요let child: boolean = false; // 깃발: 아직 어린이를 못 봤어요for (const age of ages) { if (age < 13) child = true;} const price: number = weekend ? 12 : 8; // 두 값 중 하나를 골라요console.log(weekend ? "weekend" : "weekday");console.log(price * ages.length);console.log(child ? "child" : "adults");import java.util.List;import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); String day = sc.nextLine().strip(); String[] ages = sc.nextLine().strip().split(" +"); boolean weekend = List.of("sat", "sun").contains(day); // 포함 검사의 결과(참·거짓)를 변수에 담아요 boolean child = false; // 깃발: 아직 어린이를 못 봤어요 for (String age : ages) { if (Integer.parseInt(age) < 13) child = true; } int price = weekend ? 12 : 8; // 두 값 중 하나를 골라요 System.out.println(weekend ? "weekend" : "weekday"); System.out.println(price * ages.length); System.out.println(child ? "child" : "adults"); }}using System;using System.Linq; class Program{ static void Main() { string day = Console.ReadLine().Trim(); string[] ages = Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries); string[] rest = { "sat", "sun" }; bool weekend = rest.Contains(day); // 포함 검사의 결과(참·거짓)를 변수에 담아요 bool child = false; // 깃발: 아직 어린이를 못 봤어요 foreach (string age in ages) { if (int.Parse(age) < 13) child = true; } int price = weekend ? 12 : 8; // 두 값 중 하나를 골라요 Console.WriteLine(weekend ? "weekend" : "weekday"); Console.WriteLine(price * ages.Length); Console.WriteLine(child ? "child" : "adults"); }}#include <algorithm>#include <iostream>#include <string>#include <vector> int main() { std::string day; std::cin >> day; std::vector<int> ages; int age; while (std::cin >> age) ages.push_back(age); std::vector<std::string> rest = {"sat", "sun"}; bool weekend = std::find(rest.begin(), rest.end(), day) != rest.end(); // 포함 검사의 결과(참·거짓)를 변수에 담아요 bool child = false; // 깃발: 아직 어린이를 못 봤어요 for (int a : ages) { if (a < 13) child = true; } int price = weekend ? 12 : 8; // 두 값 중 하나를 골라요 std::cout << (weekend ? "weekend" : "weekday") << '\n'; std::cout << price * ages.size() << '\n'; std::cout << (child ? "child" : "adults") << '\n';}#include <stdbool.h>#include <stdio.h>#include <string.h> int main(void) { char day[16]; int ages[100], n = 0; scanf("%15s", day); while (scanf("%d", &ages[n]) == 1) n++; const char *rest[] = {"sat", "sun"}; bool weekend = false; // 포함 검사 도구가 없어서 하나씩 견줘요 for (int i = 0; i < 2; i++) { if (strcmp(day, rest[i]) == 0) weekend = true; } bool child = false; // 깃발: 아직 어린이를 못 봤어요 for (int i = 0; i < n; i++) { if (ages[i] < 13) child = true; } int price = weekend ? 12 : 8; // 두 값 중 하나를 골라요 printf("%s\n", weekend ? "weekend" : "weekday"); printf("%d\n", price * n); printf("%s\n", child ? "child" : "adults"); return 0;}day = 控制台.读行().去空白();ages = 控制台.读数字(); // 포함 검사의 결과(참·거짓)를 변수에 담아요weekend = ["sat", "sun"].包含(day);// 깃발: 아직 어린이를 못 봤어요child = 假;遍历 (age 在 ages){ 如果 (age < 13) { child = 真; }} // 두 값 중 하나를 골라요price = weekend ? 12 : 8;控制台.输出(weekend ? "weekend" : "weekday");控制台.输出(price * ages.数量);控制台.输出(child ? "child" : "adults");sat 35 41 9
weekend 36 child
要点
- 比较的结果(
age < 13)是一个布尔值(真或假)。
它和数字、字符串一样,可以存进变量反复使用。
存好的值直接写在条件的位置:if (weekend)就够了,不用加== true。 - 标记是把布尔变量和循环一起用的写法。
循环前先设为假,遇到要找的东西就改成真。
循环结束后,它就告诉你“有没有至少一个”。 - 三元运算符按条件在两个值里选一个。
if选的是要做的事,三元选的是值,所以可以直接写在赋值的右边或输出里面。 - 三元只在很短的时候用。
一旦要在三元里再套三元,改用if和else写会更容易读。 - 包含判断问的是“这个值是不是这些值中的一个”。
不用把==用||连成一长串,而是把这些值放进列表,只问一次“在不在里面”。
答案是布尔值。 - 直接输出布尔值,各语言不一样:Python 和 C# 输出
True,JavaScript、Java、Craykon 输出true,C 和 C++ 输出1。
所以例子用三元选出字符串再输出。
各语言的写法
| Python | weekend = day in ("sat", "sun"),标记从 child = False 变成 True。三元写作 12 if weekend else 8 — 为真时的值在最前面。取反是 not weekend |
|---|---|
| JavaScript | const weekend = ["sat", "sun"].includes(day);,三元是 weekend ? 12 : 8。in 不是包含判断:"sat" in ["sat", "sun"] 是 false(它问的是有没有这个下标,不是值) |
| TypeScript | 和 JavaScript 一样。 类型名是 boolean |
| Java | boolean weekend = List.of("sat", "sun").contains(day);,三元是 weekend ? 12 : 8。和单个字符串比较用 day.equals("sat") |
| C# | bool weekend = rest.Contains(day); — 用在数组上需要 using System.Linq;。三元是 weekend ? 12 : 8 |
| C++ | bool weekend = std::find(rest.begin(), rest.end(), day) != rest.end();(<algorithm>),三元是 weekend ? 12 : 8。直接输出 bool 得到 1,先送入 std::boolalpha 才是 true |
| C | 要写 #include <stdbool.h> 才能用 bool、true、false。没有包含判断的工具,只能用循环逐个看 strcmp(day, rest[i]) == 0。单个字符可以用 strchr("aeiou", c) != NULL。三元是 weekend ? 12 : 8 |
| Craykon | weekend = ["sat", "sun"].包含(day);,标记从 child = 假; 变成 真。三元是 weekend ? 12 : 8。字符串也可以这样问: "aeiou".包含("e") |
常见错误
用 == "sat" or "sun" 问是不是二者之一Python · JavaScript · TypeScript · C · C++ · Craykon
day = "mon"
if day == "sat" or "sun":
print("weekend")
else:
print("weekday")→ weekend — 明明是星期一却成了周末。它被读成 (day == "sat") or "sun",前面为假时 "sun" 就成了条件,而非空字符串算作真
两边都写成比较(day == "sat" or day == "sun")。
用包含判断更短(day in ("sat", "sun"))。
Java 和 C# 会用编译错误拦住这段代码。
在 else 里把标记改回了假
int[] ages = {9, 35, 41};
boolean child = false;
for (int age : ages) {
if (age < 13) child = true;
else child = false;
}
System.out.println(child ? "child" : "adults");→ adults — 明明有 9 岁的,却说没有儿童。标记在 9 时变成真,又在 35 和 41 时被改回假。这样写,标记里只剩下“最后一位游客是不是儿童”。用哪种语言写都一样
删掉 else。
标记只在循环前设一次假,循环里只把它改成真。
在循环里写 child = age < 13; 这样每次重新赋值,也是同样的错误。
三元不加括号就接在 + 后面JavaScript · TypeScript · Python · C++ · Craykon
const ok = false;
console.log("Result: " + ok ? "yes" : "no");→ yes — + 先算。字符串 "Result: false" 成了条件,非空字符串永远为真。Craykon 也输出 yes。Python 的 "Result: " + "yes" if ok else "no" 只输出 no,C++ 的 std::cout << ok ? "yes" : "no"; 输出 0
把整个三元用括号括起来:"Result: " + (ok ? "yes" : "no")。
Java 和 C# 在没有括号时会报编译错误。
各语言的差异
把不是布尔值的东西写在条件的位置时,各语言分成两派。
Java 和 C# 用编译错误拦住。
C、C++、Python、JavaScript、TypeScript、Craykon 会把
什么算作假,各语言也不一样:空列表在 Python 里是假,在 JavaScript 和 Craykon 里却是真。
第一个和第三个错误悄悄给出错误答案,原因就在这里。
养成只在条件里写比较或布尔变量的习惯,就安全了。
把不是布尔值的东西写在条件的位置时,各语言分成两派。
Java 和 C# 用编译错误拦住。
C、C++、Python、JavaScript、TypeScript、Craykon 会把
"sun" 这样的值也当作真,继续往下走。什么算作假,各语言也不一样:空列表在 Python 里是假,在 JavaScript 和 Craykon 里却是真。
第一个和第三个错误悄悄给出错误答案,原因就在这里。
养成只在条件里写比较或布尔变量的习惯,就安全了。