Skip to content

Commit 36f9224

Browse files
authored
旧第Ⅲ章を第4章と第5章へ移行 (#66)
1 parent c6ee8c7 commit 36f9224

10 files changed

Lines changed: 427 additions & 7 deletions

File tree

docs/.vitepress/config.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,23 @@ export default withMermaid({
8686
},
8787
],
8888
},
89+
{
90+
text: "[WIP] 4. 条件分岐",
91+
link: "/cpp/chapter-4/",
92+
items: [
93+
{ text: "[WIP] 4.1 if文", link: "/cpp/chapter-4/1" },
94+
{ text: "[WIP] 4.2 演算子", link: "/cpp/chapter-4/2" },
95+
],
96+
},
97+
{
98+
text: "[WIP] 5. 型",
99+
link: "/cpp/chapter-5/",
100+
items: [
101+
{ text: "[WIP] 5.1 bool型", link: "/cpp/chapter-5/1" },
102+
{ text: "[WIP] 5.2 double型", link: "/cpp/chapter-5/2" },
103+
{ text: "[WIP] 5.3 string型①", link: "/cpp/chapter-5/3" },
104+
],
105+
},
89106
{
90107
text: "2025年度版テキスト",
91108
link: "/text/chapter-0/",

docs/cpp/chapter-4/1.md

Lines changed: 163 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,171 @@
1-
# 4.1 if文
1+
# [WIP] 4.1 if文
22

33
## 4.1.1 if
44

5+
特定の条件を満たす時だけ実行したい時は、if 文を用いる。if の後に条件を記し、その後の `{}` に条件を満たしていた時だけ実行したい命令を記述する。
6+
7+
以下は、入力された点数が60点以上であれば「合格」、そうでなければ「不合格」と表示するプログラムである。
8+
9+
```cpp:line-numbers
10+
#include <iostream>
11+
using namespace std;
12+
13+
int main() {
14+
cout << "点数を入力してください。" << endl;
15+
int score = 0;
16+
cin >> score;
17+
18+
if (score >= 60) {
19+
cout << "合格です。" << endl;
20+
}
21+
if (score < 60) {
22+
cout << "不合格です。" << endl;
23+
}
24+
}
25+
```
26+
27+
フローチャートで表すと以下のようになる。
28+
29+
```mermaid
30+
flowchart LR
31+
start[Start] --> condover{{"score >= 60?"}}
32+
condover --> |Yes| printover["合格"]
33+
printover --> condunder
34+
condover --> |No| condunder{{"score < 60?"}}
35+
condunder --> |Yes| printunder["不合格"]
36+
printunder --> e
37+
condunder --> |No| e[End]
38+
```
39+
40+
`score >= 60` は、 $score \geq 60$ と同じである。 `+-/*` と同じくして、条件を記述する演算子も存在する。演算子は以下の通り。
41+
42+
| 演算子 | 数学の記号 |
43+
|------|--------|
44+
| `>=` | $\geq$ |
45+
| `>` | $>$ |
46+
| `<` | $<$ |
47+
| `<=` | $\leq$ |
48+
| `==` | $=$ |
49+
| `!=` | $\neq$ |
50+
51+
:::warning
52+
`==``=` を混同しないように注意。 `=`**代入**`==`**等価** である。
53+
:::
54+
555
## 4.1.2 else
656

57+
3.1.1. で示した例は、60点以上「でない」ときを `if (score < 60)` と記述することで実装した。ただ、実際には「そうでない時」を else
58+
文によって簡単に記述できる。
59+
60+
```cpp:line-numbers
61+
#include <iostream>
62+
using namespace std;
63+
64+
int main() {
65+
cout << "点数を入力してください。" << endl;
66+
int score = 0;
67+
cin >> score;
68+
69+
if (score >= 60) {
70+
cout << "合格です" << endl;
71+
} else {
72+
cout << "不合格です" << endl;
73+
}
74+
}
75+
```
76+
77+
::: tip
78+
else 文は、if文の終わり( = `}` )の次に書く必要がある。
79+
:::
80+
81+
```mermaid
82+
flowchart LR
83+
start[Start] --> condover{{"score >= 60?"}}
84+
condover --> |Yes| printover("合格")
85+
printover --> e[End]
86+
condover --> |else| printunder("不合格")
87+
printunder --> e
88+
```
89+
790
## 4.1.3 else if
891

92+
3.1.2. のコード に「満点だったら」という条件を足す。
93+
94+
```cpp:line-numbers
95+
#include <iostream>
96+
using namespace std;
97+
98+
int main() {
99+
cout << "点数を入力してください。" << endl;
100+
int score = 0;
101+
cin >> score;
102+
103+
if (score == 100) {
104+
cout << "満点です" << endl;
105+
} else {
106+
if (score >= 60) {
107+
cout << "合格です" << endl;
108+
} else {
109+
cout << "不合格です" << endl;
110+
}
111+
}
112+
}
113+
```
114+
115+
```mermaid
116+
flowchart LR
117+
start[Start] --> condperfect{{"score == 100?"}}
118+
condperfect --> |Yes| printperfect("満点")
119+
printperfect --> e[End]
120+
condperfect --> |else| condover{{"score >= 60?"}}
121+
condover --> |Yes| printover("合格")
122+
condover --> |else| printunder("不合格")
123+
printover --> e
124+
printunder --> e
125+
```
126+
127+
ただ、このように書くのは冗長なので、`else if` と短縮する事が許されている。
128+
129+
```cpp:line-numbers
130+
#include <iostream>
131+
using namespace std;
132+
133+
int main() {
134+
cout << "点数を入力してください。" << endl;
135+
int score = 0;
136+
cin >> score;
137+
138+
if (score == 100) {
139+
cout << "満点です" << endl;
140+
} else if (score >= 60) {
141+
cout << "合格です" << endl;
142+
} else {
143+
cout << "不合格です" << endl;
144+
}
145+
}
146+
```
147+
148+
こちらの方が、若干ではあるがコードを読みやすいと感じるだろう。
149+
9150
## 4.1.4 変数のスコープ
151+
152+
変数が使える範囲には制限があり、これを変数のスコープと呼ぶ。
153+
154+
具体的には、 `{}` の外からは変数にアクセスできない。
155+
156+
例えば次のソースコードで言えば、 変数 `z` は 4 ~ 6 行目でしか使用できない。
157+
**8 行目は正しく実行できない。(コンパイルエラーとなる)**
158+
159+
変数 `x` は 1行目から 9 行目まで好きなところで使用できる。
160+
161+
```cpp:line-numbers
162+
int x = 8;
163+
164+
if (x < 10) {
165+
int z = 10;
166+
cout << z << endl; // OK !
167+
cout << x << endl; // OK !
168+
}
169+
cout << z << endl; // NG
170+
cout << x << endl; // OK !
171+
```

docs/cpp/chapter-4/2.md

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,45 @@
1-
# 4.2 演算子
1+
# [WIP] 4.2 演算子
22

33
## 4.2.1 比較演算子
44

55
## 4.2.2 論理演算子
66

7+
条件が1つの変数のみに依存する時は `if``else` でわかりやすく書けた。
8+
しかし、条件が2つ以上になるとif と else だけでは煩雑になっていく。
9+
数学では「または」、「かつ」 「でない」($\lor,\land, \lnot$) をよく使ったと思うが、プログラミングでもそれに当たるものが存在する。
10+
11+
| 演算子 | 意味 | 意味・数学記号 |
12+
|------|-----|-------------|
13+
| `&&` | AND | かつ $\land$ |
14+
| `\|\|` | OR | または $\lor$ |
15+
| `!` | NOT | でない $\lnot$ |
16+
17+
```cpp:line-numbers
18+
int x = 8;
19+
int y = 5;
20+
21+
if (x < 10 && y < 10) {
22+
cout << "x も y も 10より小さい" << endl;
23+
}
24+
if (!(y >= 10)) {
25+
cout << "y は 10 より大きくない" << endl;
26+
}
27+
```
28+
729
## 4.2.3 演算子の優先順位
30+
31+
数学と同じように、演算子には優先順位がついている。優先順位自体は覚えなくても良いが、たまに優先順位が自分の想定と違うときがある。そのようなときは `()`
32+
で式をくくることで、計算順序を変えられるので覚えると良い(数学と同じ)。
33+
34+
特に、 `<<` は比較演算子より優先順位が高い。
35+
`cout << a <= b << endl;` と書くとコンパイルエラーとなってしまうので2行目のように書かなければならない。
36+
37+
```cpp:line-numbers
38+
cout << ((a + b) * c) << endl;
39+
cout << (a <= b) << endl;
40+
```
41+
42+
::: tip
43+
「じゃあ `<<` 演算子の優先度を一番低くすればいいじゃん」と思ったかもしれない。
44+
しかし、実際には複雑な事情があるのだ……。
45+
:::

docs/cpp/chapter-4/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
# 4. 条件分岐
1+
# [WIP] 4. 条件分岐

docs/cpp/chapter-5/1.md

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,47 @@
1-
# 5.1 bool型
1+
# [WIP] 5.1 bool型
2+
3+
何気なく if 文の中に `score >= 60` と書いているが、これ自体も `+` の演算などと同じように実際は値が定まっている。
4+
5+
if 文の前に `cout` を挟んで、どんな値が出力されるか確かめてみよう。
6+
7+
```cpp:line-numbers
8+
#include <iostream>
9+
using namespace std;
10+
11+
int main() {
12+
cout << "点数を入力してください。" << endl;
13+
int score = 0;
14+
cin >> score;
15+
16+
cout << (score >= 60) << endl;
17+
if (score >= 60) {
18+
cout << "合格です" << endl;
19+
} else {
20+
cout << "不合格です" << endl;
21+
}
22+
}
23+
```
24+
25+
返り値は `1` もしくは `0` である。真のときに `1` となり、偽のときに `0` となる。
26+
この0と1のみを持つ型を bool 型と呼ぶ。
27+
28+
bool型の変数を使って、コードを以下のように書き換える事ができる。
29+
30+
```cpp:line-numbers
31+
#include <iostream>
32+
using namespace std;
33+
34+
int main() {
35+
cout << "点数を入力してください。" << endl;
36+
int score = 0;
37+
cin >> score;
38+
39+
bool isGood = score >= 60;
40+
if (isGood) {
41+
cout << "合格です" << endl;
42+
}
43+
if (!isGood) {
44+
cout << "不合格です" << endl;
45+
}
46+
}
47+
```

docs/cpp/chapter-5/2.md

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,55 @@
1-
# 5.2 double型
1+
# [WIP] 5.2 double型
2+
3+
小数について扱いたい時もあるだろう。小数は `double` 型によって表される。
4+
5+
```cpp
6+
double y = 3.5;
7+
```
8+
9+
### 3.2.2.1. 小数型に潜む罠
10+
11+
小数型は基本的に扱わない方が良いと言われている。以下のコードを見て欲しい。
12+
13+
```cpp:line-numbers
14+
double x = 0.1;
15+
double y = 0.2;
16+
double z = 0.3;
17+
bool b = x+y == z;
18+
19+
cout << b << endl;
20+
```
21+
22+
このコードの出力を考えて欲しい。明らかに `true` なはずである。
23+
しかし、実際に実行してみると `false` と表示される。
24+
25+
これは簡潔に言ってしまえば **double 型は2進数の小数に近似する型** だからである。
26+
27+
おそらく高校数学で勉強したと思うが、10進数の世界において 2 と 5 以外を因数に持つ整数で 1 を割った時、それは循環小数になる。
28+
(例: $\dfrac13=0.\dot3_{(10)}=0.3333..._{(10)}$ )
29+
30+
コンピューターの扱う 2 進数の世界でも同じ事が言えて、2進数で `0.1``0.2` 等の値は循環小数となる。
31+
(例えば $0.2_{(10)}=0.\dot001\dot1_{(2)}=0.00110011..._{(2)}$ )
32+
33+
この時、コンピューターは小数をある程度の位で打ち切って、値を丸め込んで保存する。この時に誤差が発生してしまい、故に上記のコードは `false`
34+
を出力するのである。
35+
36+
実際に `x+y` の値を出力すると良いだろう。
37+
38+
```cpp:line-numbers
39+
double x = 0.1;
40+
double y = 0.2;
41+
42+
cout << x+y << endl;
43+
```
44+
45+
```
46+
[output]
47+
0.30000000000000004
48+
```
49+
50+
その為に、小数値を使って**正確な**演算をするのは基本的には**避けた方が良い**
51+
と言われる。例えば単位の60点を超えているかどうかの判定で、60点ぴったりなはずだったのに誤差の関係で不合格と言われたらたまったものではない。
52+
(ゲーム製作においては座標計算の都合でどうしても小数を使うのだが…)
53+
54+
ちなみに、整数でデータを上手に持つ事で小数を正確に扱う方法もある。(例えば 分母と分子で 2
55+
変数を持ってしまえば、有理数は常に正確に計算できる)。また、有理数・有限小数を正確に扱えるパッケージ(ライブラリ)も存在する。

0 commit comments

Comments
 (0)