Skip to content

Commit 9be1d98

Browse files
authored
新第6~8章を作成 (#69)
1 parent b2899eb commit 9be1d98

19 files changed

Lines changed: 1249 additions & 14 deletions

File tree

docs/.vitepress/config.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,35 @@ export default withMermaid({
136136
},
137137
],
138138
},
139+
{
140+
text: "[WIP] 6. 繰り返し処理",
141+
link: "/cpp/chapter-6/",
142+
items: [
143+
{ text: "[WIP] 6.1 for文", link: "/cpp/chapter-6/1" },
144+
{ text: "[WIP] 6.2 while文", link: "/cpp/chapter-6/2" },
145+
{ text: "[WIP] 6.3 配列", link: "/cpp/chapter-6/3" },
146+
{ text: "[WIP] 6.4 string型②とchar型", link: "/cpp/chapter-6/4" },
147+
{ text: "[WIP] 6.5 continueとbreak", link: "/cpp/chapter-6/5" },
148+
],
149+
},
150+
{
151+
text: "[WIP] 7. 関数",
152+
link: "/cpp/chapter-7/",
153+
items: [
154+
{ text: "[WIP] 7.1 関数とは", link: "/cpp/chapter-7/1" },
155+
{ text: "[WIP] 7.2 引数", link: "/cpp/chapter-7/2" },
156+
{ text: "[WIP] 7.3 返り値", link: "/cpp/chapter-7/3" },
157+
{ text: "[WIP] 7.4 [発展] 参照渡し", link: "/cpp/chapter-7/4" },
158+
],
159+
},
160+
{
161+
text: "[WIP] 8. 構造体",
162+
link: "/cpp/chapter-8/",
163+
items: [
164+
{ text: "[WIP] 8.1 構造体とは", link: "/cpp/chapter-8/1" },
165+
{ text: "[WIP] 8.2 メソッド", link: "/cpp/chapter-8/2" },
166+
],
167+
},
139168
{
140169
text: "2025年度版テキスト",
141170
link: "/text/chapter-0/",

docs/cpp/chapter-6/1.md

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,52 @@
1-
# 6.1 for文
1+
# [WIP] 6.1 for文
2+
3+
繰り返しの処理 `for` は以下のように記述する。
4+
5+
```cpp:line-numbers
6+
for (int i=0; i<5; i++) {
7+
cout << i << endl;
8+
}
9+
```
10+
11+
```
12+
[output]
13+
0
14+
1
15+
2
16+
3
17+
4
18+
```
19+
20+
新しい演算`++` が出ているが、これは **変数の値を1増やす** という演算である。 `i = i+1;` と同値。
21+
22+
for 文がどのように動作しているかを解説すると、`for` の後に `;` 区切りで 3 つ情報を指定している。
23+
24+
```cpp
25+
for ([初期化];[条件];[継続処理]) {
26+
[実行文]
27+
}
28+
```
29+
30+
```mermaid
31+
flowchart LR
32+
start[Start] --> init[[初期化]]
33+
subgraph for
34+
init[[初期化]] --> cond[[条件]]
35+
cond --> |Yes| work[["処理"]] --> cont[["継続処理"]] --> cond
36+
end
37+
cond --> |No| e["End"]
38+
```
39+
40+
例示したコードで当てはめると以下のようになる。
41+
42+
```mermaid
43+
flowchart LR
44+
start[Start] --> init[[初期化]]
45+
subgraph for
46+
init[[int i=0]] --> cond[[i<5]]
47+
cond --> |Yes| work[[cout << i]] --> cont[[i++]] --> cond
48+
end
49+
cond --> |No| e["End"]
50+
```
51+
52+
つまり、0,1,2,3,4 の整数を出力するプログラムである。これを使えば、例えば $7^4$ 等がプログラムで計算できる。

docs/cpp/chapter-6/2.md

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,23 @@
1-
# 6.2 while文
1+
# [WIP] 6.2 while文
2+
3+
```cpp:line-numbers
4+
int a = 10;
5+
while (a > 0) {
6+
cout << a << endl;
7+
a--;
8+
}
9+
```
10+
11+
while文は、 `while` の中の条件文が真の間実行される繰り返し処理。
12+
13+
上記のコードだと、 10,9,8,7,6,5,4,3,2,1 と順に出力される。
14+
15+
```mermaid
16+
flowchart LR
17+
start[Start] --> init[[int a = 10]]
18+
init --> cond[[a>0]]
19+
subgraph while
20+
cond --> |Yes| work[[cout << a]] --> cont[[a--]] --> cond
21+
end
22+
cond --> |No| e["End"]
23+
```

docs/cpp/chapter-6/3.md

Lines changed: 84 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,84 @@
1-
# 6.3 配列
1+
# [WIP] 6.3 配列
2+
3+
プログラミングでは、同じ様な変数を複数作りたいときがある。例えば、100人の点数の平均点を取りたい時に変数は100個必要となる。このときに、配列を使う。
4+
5+
配列とは、変数の集合のようなものである。
6+
7+
C++ において配列を使う時は、`vector` を用いる。`string` と同様にして、`vector`をインクルードする。
8+
9+
```cpp:line-numbers
10+
#include <vector>
11+
```
12+
13+
以下のようにして、`<>`内に型を宣言することで、配列を定義することができる。
14+
15+
```cpp:line-numbers
16+
vector<int> array;
17+
vector<string> strarray;
18+
```
19+
20+
このように記述すると空の配列が作成される。以下のように、初めから配列に値を入れることもできる
21+
22+
```cpp:line-numbers
23+
vector<int> arr = {10, 20, 30, 40, 50};
24+
```
25+
26+
以下のように、 `[]` の中に数字を書くことで要素を取得できる。数列を考えた時の $a_i$ の $i$ だと思うと良い。この時要素番号は*
27+
*0始まり**である。
28+
29+
```cpp:line-numbers
30+
vector<int> arr = {10, 20, 30, 40, 50};
31+
cout << arr[2] << endl;
32+
arr[1] = 100;
33+
cout << arr[1] << endl;
34+
```
35+
36+
```
37+
[output]
38+
30
39+
100
40+
```
41+
42+
`.size()` とすると、配列の要素数を調べることができる。
43+
44+
```cpp:line-numbers
45+
vector<int> arr = {10, 20, 30, 40, 50};
46+
int siz = arr.size();
47+
cout << siz << endl;
48+
```
49+
50+
```
51+
[output]
52+
5
53+
```
54+
55+
これと、`for` を用いれば、配列の要素を全て取得することができる。
56+
57+
```cpp:line-numbers
58+
vector<int> arr = {10, 20, 30, 40, 50};
59+
for (int i=0; i < arr.size(); i++) {
60+
cout << arr[i] << endl;
61+
}
62+
```
63+
64+
`for` 文の中で、 `arr[0]` から `arr[4]` までが1つずつ出力されるコードだという事が理解できるだろうか。`i < arr.size()`
65+
の条件から、`i` は 0 から 4 までの場合で実行される。(5 は `5 < 5` となり条件を満たさない。)
66+
67+
`.push_back()` を用いると、配列の末尾に新しい要素を追加することができる。
68+
69+
```cpp:line-numbers
70+
vector<int> arr = {10, 20, 30, 40, 50};
71+
arr.push_back(-10);
72+
73+
cout << arr[5] << endl;
74+
cout << arr.size() << endl;
75+
```
76+
77+
```
78+
[output]
79+
-10
80+
6
81+
```
82+
83+
for文と組み合わせると、できる事が非常に広がる。
84+

docs/cpp/chapter-6/4.md

Lines changed: 166 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,166 @@
1-
# 6.4 string型②とchar型
1+
# [WIP] 6.4 string型②とchar型
2+
3+
string は、実際には文字の配列であると捉えると、文字列に対する操作を行うことができる。
4+
5+
一度、アルファベットと数字・一部の記号だけ、いわゆる「**1バイト文字**」のみで考えよう。ひらがなやカタカナについては後で説明する。
6+
7+
:::warning
8+
ひらがな・カタカナ・漢字などの文字を使うと、以下の説明が成り立たなくなってしまうことがある。
9+
:::
10+
11+
配列と同じようにして、長さを取得したり、1文字ずつ取得したりすることができる。
12+
13+
```cpp:line-numbers
14+
string s = "traP";
15+
cout << s.size() << endl; // 配列と捉えて配列の要素数を取得する。
16+
cout << s.length() << endl; // length() によって文字列の長さを取得する
17+
18+
for (int i=0; i<s.size(); i++) {
19+
cout << s[i];
20+
}
21+
```
22+
23+
## 6.4.1. バイト・ビット
24+
25+
**ビット**(bit) は、1ビットは `0``1` かの情報のみを持つ。
26+
27+
**バイト**(Byte) は、パソコンが一般的に処理するデータの単位。基本的に 8bit = 1Byte。
28+
よくスマホの通信量とかの「キロバイト」等のバイトはこれを指している。
29+
30+
8bit なので、1バイトで扱える情報は `0` から `255` の256($=2^8$)種類である。
31+
32+
## 6.4.2. char 型
33+
34+
文字1文字を扱う時は、 `char` 型を用いる。
35+
36+
```cpp:line-numbers
37+
string s = "Hello";
38+
char c = s[1];
39+
cout << c << endl; // output: e
40+
```
41+
42+
1文字を扱う時は、`''`**シングル**クォーテーション)で囲う。
43+
44+
```cpp:line-numbers
45+
string s = "traP";
46+
s[3] = 'Q';
47+
48+
cout << s << endl; // output: traQ
49+
```
50+
51+
## 6.4.3. ASCII
52+
53+
各文字には、文字コード(ASCIIコード)と呼ばれる番号が定められていて、内部的に char 型には数値が格納されている。
54+
55+
```cpp:line-numbers
56+
char c = 'e';
57+
int a = c;
58+
cout << a << endl; // output: 101
59+
```
60+
61+
ASCII コード表:https://e-words.jp/p/r-ascii.html
62+
ここで、アルファベットは順番に並んでいるという事実は覚えておくと良い。
63+
64+
逆に、char に数値を代入によって文字を代入することもできる。
65+
66+
```cpp:line-numbers
67+
char c = 81;
68+
cout << c << endl; // output: Q
69+
```
70+
71+
## 6.4.4. 文字の比較
72+
73+
4.4.3. によれば、1文字1文字は、実際は数値として扱われているのであった。よって、数値と同じように扱えるということは、以下のように比較できるということである。
74+
75+
```cpp:line-numbers
76+
cout << ('A' < 'B') << endl;
77+
```
78+
79+
ここで、アルファベットはASCIIコード上で順番に並んでいるということを思い返すと、
80+
`('A' <= x && x <= 'Z')` で「文字$x$が大文字アルファベットかどうか」が判定できる。
81+
更にこれと for 文をうまく使えば、(アルファベットの)辞書順でどちらが先かを実装することができるだろう。
82+
83+
::: tip
84+
85+
実際には、文字列の辞書順で先かどうかは、`<` `>` の不等号演算子で簡単に実装できる。
86+
87+
```cpp:line-numbers
88+
string s = "Hello";
89+
string t = "Bello";
90+
cout << (s < t) << endl;
91+
```
92+
93+
```
94+
[output]
95+
0
96+
```
97+
98+
string 型同士で比較するときに、1文字目を比較→同じなら2文字目を比較→… という処理を行って比較されている。
99+
100+
:::
101+
102+
## 6.4.5. マルチバイト文字
103+
104+
::: tip
105+
完全なおまけセクションです。講習の進行状況次第で飛ばします…
106+
:::
107+
108+
ところで、ASCIIコード表には日本語特有の文字(ひらがな・カタカナ・漢字)が存在しないことに気づくだろうか。
109+
110+
これは1バイトで扱える情報が 256 通りしかないから、日本語は1バイトだけでは扱うことができない。
111+
それゆえ、日本語(ひらがなカタカナ等)はマルチバイト文字で表現されている(複数バイトで1文字を表す方式)。
112+
113+
ここで、`char` 型は、正確には「1バイトの整数型」である。よって、`char`
114+
型ではひらがな等の字を扱うことができない。実際に試してみると、5文字なのに長さは15と表示されてしまうし、1文字目を出力してみようと思ってもうまく出力されない。例えば「こ」の場合は、3文字出力してようやく「こ」が表示されるのである。
115+
116+
```cpp:line-numbers
117+
string dame = "こんにちは";
118+
cout << dame.length() << endl;
119+
cout << dame[0] << endl;
120+
cout << dame[0] << dame[1] << dame[2] << endl;
121+
```
122+
123+
```
124+
[output]
125+
15
126+
127+
128+
```
129+
130+
多バイト文字を扱える型も存在するが、非常に扱いが面倒なのでここでは扱わない。
131+
C++ 以外の言語でも大体は文字列を扱えるが、マルチバイト文字に対する扱いは言語によってまちまちだったりするので、よく調べること。
132+
133+
::: tip
134+
135+
### 6.4.5.1. 文字化け
136+
137+
ここで横道に逸れてしまうが、せっかくの機会なので「文字化け」についても触れておこう。
138+
139+
**歴史的な経緯**
140+
141+
ASCII では日本語文字を扱えないのは明らかだったので、1文字で2バイトを使う文字コード体系が考案された。2バイトであれば
142+
$2^{16}=65536$ 文字を扱えるので、これだけあれば十分だという事である。
143+
しかし、結果としては国内で文字コードが乱立し(Shift-JIS, EUC-JP
144+
等…)、様々衝突するようになった上、国内にとどまらず各国で独自の文字コードが作成されてしまい、混乱を極めてしまったのである(ASCII
145+
で表せないのは日本語だけではなく、アラビア文字・簡体字・ギリシャ文字など様々…)。
146+
147+
最終的には、世界の全文字を扱う文字コードとして Unicode (≒ UTF-8)
148+
が策定され、今日ではこれが普及している。しかし完全に普及している訳でもなく、よって、今日見かける文字化けはもっぱら「UTF-8 か
149+
UTF-8 以外か」の文字コードを使って発生しているパターンである。
150+
151+
**CJK 問題**
152+
153+
また、日本語の漢字が中国語のフォントで表示されている、という謎の現象に遭遇したこともあるかもしれない。これは、Unicode
154+
を制定した際に日本語・中国語(簡体字・繁体字)・韓国語の漢字について、似ている漢字を全て一緒くたにしてしまった事が原因である。 → [Your Code Displays Japanese Wrong](https://heistak.github.io/your-code-displays-japanese-wrong/)
155+
156+
**横道**
157+
158+
(横道の横道はもう獣道では…?)
159+
日本国内は2バイト文字コードの覇権を争うために揉めていたが、その間ヨーロッパでは自国専用の1バイト文字が乱立していて同じように揉めていたらしい。
160+
:::
161+
162+
::: tip
163+
`int` 型は 4バイトの整数型である。扱える情報は $2^{32}$ で、整数は負と正の値を取るから非負整数の部分にに $2^{31}$
164+
個を割り当てる。$2^{31}=2147483648
165+
$ なのだが、実はこの値は既にテキストで一度出現している。さてどこだろうか?
166+
:::

0 commit comments

Comments
 (0)