diff --git a/public/docs/cpp/0-intro/1-1-feature.md b/public/docs/cpp/0-intro/1-1-feature.md index fda0db0a..e90848f6 100644 --- a/public/docs/cpp/0-intro/1-1-feature.md +++ b/public/docs/cpp/0-intro/1-1-feature.md @@ -14,6 +14,6 @@ question: 他の言語と比較したC++の特徴は以下の通りです。 * **パフォーマンス 🚀:** C++は、OSやハードウェアに近い低レベルな操作が可能で、実行速度が非常に高速です。このため、パフォーマンスが最重要視される場面で絶大な信頼を得ています。 - * **静的型付け:** 変数の型はコンパイル時に決定されます。これにより、実行前に多くのエラーを発見でき、大規模な開発でもコードの安全性を保ちやすくなります。 + * **静的型付け:** [[変数]]の型は[[コンパイル]]時に決定されます。これにより、実行前に多くのエラーを発見でき、大規模な開発でもコードの安全性を保ちやすくなります。 * **マルチパラダイム:** 手続き型プログラミング、オブジェクト指向プログラミング、ジェネリックプログラミングなど、様々なプログラミングスタイルをサポートしています。これにより、問題の性質に合わせて最適なアプローチを選択できます。 - * **C言語との互換性:** C言語のコードの多くは、ほとんどそのままC++のコードとしてコンパイルできます。C言語で書かれた膨大なソフトウェア資産を活用できるのは大きな利点です。 + * **C言語との互換性:** C言語のコードの多くは、ほとんどそのままC++のコードとして[[コンパイル]]できます。C言語で書かれた膨大なソフトウェア資産を活用できるのは大きな利点です。 diff --git a/public/docs/cpp/0-intro/3-1-run.md b/public/docs/cpp/0-intro/3-1-run.md index b61641dd..09a22ed9 100644 --- a/public/docs/cpp/0-intro/3-1-run.md +++ b/public/docs/cpp/0-intro/3-1-run.md @@ -7,6 +7,8 @@ question: - コンパイルに失敗した場合、どのようなメッセージが表示されますか? - なぜPythonやJavaScriptはコンパイルが不要なのですか? - コンパイルすると、どのようなファイルが生成されますか? +term: + - コンパイル --- ### コンパイルと実行 diff --git a/public/docs/cpp/0-intro/4-1-include.md b/public/docs/cpp/0-intro/4-1-include.md index 00b6c4eb..a5bac600 100644 --- a/public/docs/cpp/0-intro/4-1-include.md +++ b/public/docs/cpp/0-intro/4-1-include.md @@ -7,6 +7,8 @@ question: - iostreamがないとstd::coutは使えないのですか? - ヘッダファイルとは何ですか? - '#includeを書き忘れたらどうなりますか?' +term: + - インクルード --- ### `#include ` - ヘッダファイルのインクルード @@ -14,4 +16,4 @@ question: `#include` は、他のファイルに書かれた機能を利用するための**プリプロセッサ命令**です。ここでは、コンソールへの入出力機能を提供する `iostream` という標準ライブラリのヘッダファイルを読み込んでいます。これにより、`std::cout` などが使えるようになります。 * `< >` で囲む: 標準ライブラリのヘッダファイルをインクルードする場合 - * `" "` で囲む: 自分で作成したヘッダファイルをインクルードする場合 (後の章で学びます) + * `" "` で囲む: 自分で作成した[[ヘッダファイル]]をインクルードする場合 ([[./5]]で学びます) diff --git a/public/docs/cpp/0-intro/4-2-main.md b/public/docs/cpp/0-intro/4-2-main.md index 141871d2..19fe4d9b 100644 --- a/public/docs/cpp/0-intro/4-2-main.md +++ b/public/docs/cpp/0-intro/4-2-main.md @@ -7,6 +7,9 @@ question: - main関数は必ずint型を返さなければなりませんか? - return 0;と書かないとどうなりますか? - 引数を取るmain関数はどのような場合に使うのですか? +term: + - main関数 + - main 関数 --- ### `int main()` - main関数 diff --git a/public/docs/cpp/0-intro/4-3-namespace.md b/public/docs/cpp/0-intro/4-3-namespace.md index 70ce9640..afc587eb 100644 --- a/public/docs/cpp/0-intro/4-3-namespace.md +++ b/public/docs/cpp/0-intro/4-3-namespace.md @@ -12,7 +12,7 @@ question: ### `std::cout` と `std::endl` - 名前空間 (namespace) - * `std::cout`: "character output stream" の略で、コンソールへの標準出力を担当します。 + * [[`std::cout`]]: "character output stream" の略で、コンソールへの標準出力を担当します。 * `<<`: **ストリーム挿入演算子**と呼ばれ、右側のデータを左側のストリーム(ここでは `std::cout`)に流し込むイメージです。 - * `std::endl`: "end line" の略で、改行を出力し、出力バッファをフラッシュ(強制的に出力)します。 - * `std::`: `cout` や `endl` が `std` という**名前空間 (namespace)** に属していることを示します。名前空間は、大規模なプログラムで関数や変数の名前が衝突するのを防ぐための仕組みです。`std` はC++の標準ライブラリが定義されている名前空間です。 + * [[`std::endl`]]: "end line" の略で、改行を出力し、出力バッファをフラッシュ(強制的に出力)します。 + * `std::`: `cout` や `endl` が `std` という**名前空間 (namespace)** に属していることを示します。名前空間は、大規模なプログラムで関数や[[変数]]の名前が衝突するのを防ぐための仕組みです。`std` はC++の標準ライブラリが定義されている名前空間です。 diff --git a/public/docs/cpp/0-intro/5-0-summary.md b/public/docs/cpp/0-intro/5-0-summary.md index f4886ce1..19c949ce 100644 --- a/public/docs/cpp/0-intro/5-0-summary.md +++ b/public/docs/cpp/0-intro/5-0-summary.md @@ -8,8 +8,8 @@ question: [] ## この章のまとめ * C++は、**パフォーマンス**と**多機能性**を両立した強力なプログラミング言語です。 - * C++の開発フローは、「**ソースコード作成 → コンパイル → 実行**」が基本です。 - * すべてのC++プログラムは `main` 関数から実行が始まります。 + * C++の開発フローは、「**ソースコード作成 → [[コンパイル]] → 実行**」が基本です。 + * すべてのC++プログラムは [[`main` 関数]]から実行が始まります。 * `#include` で外部ライブラリの機能を読み込み、`namespace` で名前の衝突を避けます。 -これであなたもC++プログラマの仲間入りです!次の章では、C++の根幹をなす型システムとメモリの仕組みについて学んでいきましょう。 +これであなたもC++プログラマの仲間入りです![[./next]]では、C++の根幹をなす型システムとメモリの仕組みについて学んでいきましょう。 diff --git a/public/docs/cpp/1-types-control/-intro.md b/public/docs/cpp/1-types-control/-intro.md index b6d09790..88c3de50 100644 --- a/public/docs/cpp/1-types-control/-intro.md +++ b/public/docs/cpp/1-types-control/-intro.md @@ -1 +1 @@ -C++は**静的型付け言語**です。PythonやJavaScriptのような動的型付け言語とは異なり、コンパイル時に変数の型が確定している必要があります。これにより、実行時のエラーを未然に防ぎ、高いパフォーマンスを実現します。 +C++は**静的型付け言語**です。PythonやJavaScriptのような動的型付け言語とは異なり、[[コンパイル]]時に[[変数]]の型が確定している必要があります。これにより、実行時のエラーを未然に防ぎ、高いパフォーマンスを実現します。 diff --git a/public/docs/cpp/1-types-control/1-0-basic-types.md b/public/docs/cpp/1-types-control/1-0-basic-types.md index 58e7801f..4f222bad 100644 --- a/public/docs/cpp/1-types-control/1-0-basic-types.md +++ b/public/docs/cpp/1-types-control/1-0-basic-types.md @@ -8,6 +8,18 @@ question: - charとstd::stringはどちらも文字を扱うのに使うようですが、違いは何ですか? - 変数のサイズが環境によって異なる場合があるとは、どういうことですか? - intが32bit以上であることが保証されているというのは、どういう意味ですか? +term: + - 基本型 + - 整数型 + - 浮動小数点型 + - 文字型 + - ブール型 + - int + - long + - double + - float + - char + - bool --- ## 基本的なデータ型 @@ -16,7 +28,7 @@ C++には多くの型がありますが、まずは以下の基本型を押さ * **整数型**: `int` (通常4バイト), `long long` (8バイト, 大きな整数) * **浮動小数点型**: `double` (倍精度, 基本的にこれを使う), `float` (単精度) - * **文字型**: `char` (1バイト文字), `std::string` (文字列クラス。厳密には基本型ではありませんが、実用上必須) + * **文字型**: `char` (1バイト文字), `std::string` ([[文字列]]クラス。厳密には基本型ではありませんが、実用上必須) * **ブール型**: `bool` (`true` または `false`) -C++では変数のサイズ(ビット幅)が環境によって異なる場合がありますが、現代的な環境では `int` は32bit以上であることが保証されています。 +C++では[[変数]]のサイズ(ビット幅)が環境によって異なる場合がありますが、現代的な環境では `int` は32bit以上であることが保証されています。 diff --git a/public/docs/cpp/1-types-control/2-0-uniform-init.md b/public/docs/cpp/1-types-control/2-0-uniform-init.md index eaf2fa9c..b01572f8 100644 --- a/public/docs/cpp/1-types-control/2-0-uniform-init.md +++ b/public/docs/cpp/1-types-control/2-0-uniform-init.md @@ -8,13 +8,16 @@ question: - int height{170.5}; のようにエラーになる方が安全とはどういうことですか? - int rough_height = 170.9; のように値が切り捨てられてしまうのは、問題ないのでしょうか? - 常に波括弧{}で初期化すれば良いのでしょうか? +term: + - 変数 + - 初期化 --- ## 変数の初期化:ユニフォーム初期化 `{}` C++には変数を初期化する方法がいくつもありますが、C++11以降では **波括弧 `{}` を使った初期化(ユニフォーム初期化)** が推奨されています。 -なぜ `{}` が良いのでしょうか? それは、**縮小変換(Narrowing Conversion)** を防げるからです。例えば、少数のデータを整数型変数に無理やり入れようとした時、`=` なら黙って切り捨てられますが、`{}` ならコンパイルエラーにしてくれます。 +なぜ `{}` が良いのでしょうか? それは、**縮小変換(Narrowing Conversion)** を防げるからです。例えば、小数のデータを[[整数型]]変数に無理やり入れようとした時、`=` なら黙って切り捨てられますが、`{}` ならコンパイルエラーにしてくれます。 ```cpp:initialization.cpp #include diff --git a/public/docs/cpp/1-types-control/3-1-const.md b/public/docs/cpp/1-types-control/3-1-const.md index 107eea20..b772469e 100644 --- a/public/docs/cpp/1-types-control/3-1-const.md +++ b/public/docs/cpp/1-types-control/3-1-const.md @@ -8,11 +8,13 @@ question: - constを付け忘れた場合、どのような問題が起こりうるのですか? - PIのように定数を宣言するとき、変数名を大文字にするのはルールですか? - constはどんなデータ型にでも使えるのですか? +term: + - const --- ### `const`による不変性の保証 -`const` (constantの略) は、変数を**読み取り専用**にするためのキーワードです。一度`const`で初期化された変数の値は、後から変更しようとするとコンパイルエラーになります。 +`const` (constantの略) は、[[変数]]を**読み取り専用**にするためのキーワードです。一度`const`で初期化された[[変数]]の値は、後から変更しようとするとコンパイルエラーになります。 なぜ`const`が重要なのでしょうか? diff --git a/public/docs/cpp/1-types-control/3-2-auto.md b/public/docs/cpp/1-types-control/3-2-auto.md index 4e2991d1..e4c4a195 100644 --- a/public/docs/cpp/1-types-control/3-2-auto.md +++ b/public/docs/cpp/1-types-control/3-2-auto.md @@ -7,11 +7,13 @@ question: - autoを使いすぎるとコードが読みにくくなることはありませんか? - auto z = "hello"; がconst char* になるのはなぜですか?std::stringにはならないのですか? - autoを使うことで、プログラムの実行速度に影響はありますか? +term: + - auto --- ### `auto`による型推論 -C++11から導入された`auto`キーワードを使うと、コンパイラが初期化式から変数の型を自動で推論してくれます。これにより、特に型名が長い場合にコードを簡潔に書くことができます。 +C++11から導入された`auto`キーワードを使うと、コンパイラが初期化式から[[変数]]の型を自動で推論してくれます。これにより、特に型名が長い場合にコードを簡潔に書くことができます。 ```cpp // autoを使わない場合 @@ -21,7 +23,7 @@ std::vector::iterator it = my_vector.begin(); auto it = my_vector.begin(); // コンパイラが it の型を std::vector::iterator と推論してくれる ``` -ただし、`auto`はあくまで「型を書く手間を省く」ものであり、変数が型を持たないわけではありません(動的型付け言語とは異なります)。初期化と同時に使う必要があり、型が明確な場面で適切に使うことが推奨されます。 +ただし、`auto`はあくまで「型を書く手間を省く」ものであり、[[変数]]が型を持たないわけではありません(動的型付け言語とは異なります)。初期化と同時に使う必要があり、型が明確な場面で適切に使うことが推奨されます。 ```cpp auto x = 10; // x は int型になる diff --git a/public/docs/cpp/1-types-control/4-0-console.md b/public/docs/cpp/1-types-control/4-0-console.md index 561331f6..c2fa0250 100644 --- a/public/docs/cpp/1-types-control/4-0-console.md +++ b/public/docs/cpp/1-types-control/4-0-console.md @@ -8,6 +8,10 @@ question: - std::endlは「バッファをフラッシュする」とありますが、バッファをフラッシュするとはどういうことですか? - キーボードから複数の値を入力する際、値と値の間はスペースで区切れば良いのですか? - 数値が期待される入力に対して文字列が入力された場合など、入力エラーへの対処はどうすれば良いですか? +term: + - std::cout + - std::cin + - std::endl --- ## コンソール入出力 (`std::cin`, `std::cout`) diff --git a/public/docs/cpp/1-types-control/5-1-if.md b/public/docs/cpp/1-types-control/5-1-if.md index d8f3534b..9a5b356e 100644 --- a/public/docs/cpp/1-types-control/5-1-if.md +++ b/public/docs/cpp/1-types-control/5-1-if.md @@ -6,6 +6,8 @@ question: - if文の条件式はboolに変換可能なものである必要があるとありますが、具体的にどういうことですか? - if文の中にさらにif文を入れることはできますか? - else ifやelseは必ず書かないといけないものですか? +term: + - if --- ### `if`文 diff --git a/public/docs/cpp/1-types-control/5-2-switch.md b/public/docs/cpp/1-types-control/5-2-switch.md index 85c46481..859a6d74 100644 --- a/public/docs/cpp/1-types-control/5-2-switch.md +++ b/public/docs/cpp/1-types-control/5-2-switch.md @@ -8,11 +8,16 @@ question: - breakを書き忘れた場合、プログラムはどのように動作するのですか? - switch文のcaseに書ける値の型に制限はありますか? - defaultのcaseは必ず書くべきですか? +term: + - switch --- ### `switch`文とフォールスルー -`switch` 文は `break` を書かない限り、次の `case` へ処理が流れます(フォールスルー)。意図的なフォールスルーでない限り、`break` を忘れないように注意が必要です。C++17以降では `[[fallthrough]];` 属性をつけることで、「意図的なものである」とコンパイラに伝え、警告を抑制できます。 +`switch` 文は `break` を書かない限り、次の `case` へ処理が流れます(フォールスルー)。意図的なフォールスルーでない限り、`break` を忘れないように注意が必要です。 + +> [!TIP] +> C++17以降では `[[fallthrough]];` 属性をつけることで、「意図的なものである」とコンパイラに伝え、警告を抑制できます。 ```cpp:control-switch.cpp #include diff --git a/public/docs/cpp/1-types-control/5-3-loop.md b/public/docs/cpp/1-types-control/5-3-loop.md index 9d3e43c4..94345848 100644 --- a/public/docs/cpp/1-types-control/5-3-loop.md +++ b/public/docs/cpp/1-types-control/5-3-loop.md @@ -8,12 +8,13 @@ question: - whileループの具体的な使い方の例も見てみたいです。 - 無限ループを防ぐためにはどうすれば良いですか? - ループを途中で抜け出す方法や、次のイテレーションに進む方法はC++にもありますか? +term: + - while + - for --- ### ループ構文 -`while`, `for` も標準的です。 - ```cpp:control-loop.cpp #include diff --git a/public/docs/cpp/1-types-control/6-0-summary.md b/public/docs/cpp/1-types-control/6-0-summary.md index 33660f2d..25f4edd7 100644 --- a/public/docs/cpp/1-types-control/6-0-summary.md +++ b/public/docs/cpp/1-types-control/6-0-summary.md @@ -7,8 +7,8 @@ question: [] ## この章のまとめ - * **型システム**: `int`, `double`, `bool` などの基本型があり、静的に管理される。 - * **初期化**: `int x{10};` のような波括弧 `{}` を使う初期化が推奨される(縮小変換の防止)。 - * **型推論と定数**: `auto` で型推論を行い、変更しない変数には `const` を付ける。 - * **入出力**: `std::cout`, `std::cin` を使い、`<<`, `>>` 演算子でデータを流す。 + * **型システム**: `int`, `double`, `bool` などの[[基本型]]があり、静的に管理される。 + * **初期化**: `int x{10};` のような波括弧 `{}` を使う[[初期化]]が推奨される(縮小変換の防止)。 + * **型推論と定数**: [[`auto`]] で型推論を行い、変更しない変数には [[`const`]] を付ける。 + * **入出力**: [[`std::cout`]], [[`std::cin`]] を使い、`<<`, `>>` 演算子でデータを流す。 * **制御構文**: 基本は他言語と同じだが、`switch` のフォールスルー挙動などに注意する。 diff --git a/public/docs/cpp/1-types-control/6-1-practice1.md b/public/docs/cpp/1-types-control/6-1-practice1.md index 09779757..2a044055 100644 --- a/public/docs/cpp/1-types-control/6-1-practice1.md +++ b/public/docs/cpp/1-types-control/6-1-practice1.md @@ -10,7 +10,7 @@ question: ## 練習問題1:うるう年判定機 -西暦(整数)を変数 `year` に代入し、その年がうるう年かどうかを判定して結果を出力するプログラムを書いてください。 +西暦(整数)を[[変数]] `year` に代入し、その年がうるう年かどうかを判定して結果を出力するプログラムを書いてください。 > **うるう年の条件** > diff --git a/public/docs/cpp/1-types-control/6-2-practice2.md b/public/docs/cpp/1-types-control/6-2-practice2.md index cc886039..00efb17e 100644 --- a/public/docs/cpp/1-types-control/6-2-practice2.md +++ b/public/docs/cpp/1-types-control/6-2-practice2.md @@ -17,7 +17,7 @@ question: * 両方で割り切れるときは "FizzBuzz" と出力。 * それ以外は数値をそのまま出力。 -出力はスペース区切りまたは改行区切りどちらでも構いません。変数の初期化には `{}` を、ループカウンタの型には `auto` を使用してみてください。 +出力はスペース区切りまたは改行区切りどちらでも構いません。[[変数]]の[[初期化]]には `{}` を、ループカウンタの型には [[`auto`]] を使用してみてください。 ```cpp:practice2_2.cpp #include diff --git a/public/docs/cpp/10-stl-containers/1-0-about.md b/public/docs/cpp/10-stl-containers/1-0-about.md index 4555e88f..01efff1f 100644 --- a/public/docs/cpp/10-stl-containers/1-0-about.md +++ b/public/docs/cpp/10-stl-containers/1-0-about.md @@ -11,8 +11,8 @@ question: STLは、主に3つの要素から構成されています。 -1. **コンテナ (Containers)**: データを格納するためのデータ構造です。`vector`(可変長配列)や`map`(連想配列)など、様々な種類があります。 +1. **コンテナ (Containers)**: データを格納するためのデータ構造です。[[`std::vector`]](可変長配列)や`std::map`(連想配列)など、様々な種類があります。 2. **アルゴリズム (Algorithms)**: ソート、検索、変換など、コンテナ上のデータに対して操作を行う関数群です。 -3. **イテレータ (Iterators)**: コンテナの要素を指し示し、アルゴリズムがコンテナの種類に依存せずに各要素にアクセスするための統一的なインターフェースを提供します。ポインタを一般化したようなものです。 +3. **イテレータ (Iterators)**: コンテナの要素を指し示し、アルゴリズムがコンテナの種類に依存せずに各要素にアクセスするための統一的なインターフェースを提供します。[[ポインタ]]を一般化したようなものです。 -これら3つが連携することで、C++プログラマは効率的で再利用性の高いコードを素早く書くことができます。この章では「コンテナ」を、次の章では「アルゴリズム」と、それらをつなぐ「イテレータ」の応用を詳しく見ていきます。 +これら3つが連携することで、C++プログラマは効率的で再利用性の高いコードを素早く書くことができます。この章では「コンテナ」を、[[./11]]では「アルゴリズム」と、それらをつなぐ「イテレータ」の応用を詳しく見ていきます。 diff --git a/public/docs/cpp/10-stl-containers/2-0-vector.md b/public/docs/cpp/10-stl-containers/2-0-vector.md index cc732ba6..cc4c820b 100644 --- a/public/docs/cpp/10-stl-containers/2-0-vector.md +++ b/public/docs/cpp/10-stl-containers/2-0-vector.md @@ -12,7 +12,7 @@ question: ## `std::vector`: 最もよく使う可変長配列 -`std::vector`は、最も基本的で最もよく使われるコンテナです。他の言語でいうところの「リスト」や「動的配列」に相当し、要素を連続したメモリ領域に格納します。 +[[`std::vector`]]は、最も基本的で最もよく使われるコンテナです。他の言語でいうところの「リスト」や「動的配列」に相当し、要素を連続したメモリ領域に格納します。 **主な特徴**: @@ -20,7 +20,7 @@ question: * **高速なランダムアクセス**: インデックス(添字)を使って `[i]` の形式で要素に高速にアクセスできます (`O(1)`)。 * **末尾への高速な追加・削除**: `push_back()` や `pop_back()` を使った末尾への操作は非常に高速です。 -`std::vector`を使うには、``ヘッダをインクルードする必要があります。 +`std::vector`を使うには、``ヘッダを[[インクルード]]する必要があります。 ```cpp:vector_example.cpp #include diff --git a/public/docs/cpp/10-stl-containers/3-0-map.md b/public/docs/cpp/10-stl-containers/3-0-map.md index aec007bc..a93811f1 100644 --- a/public/docs/cpp/10-stl-containers/3-0-map.md +++ b/public/docs/cpp/10-stl-containers/3-0-map.md @@ -21,7 +21,7 @@ question: * **キーによる高速な検索**: キーに基づいて要素が自動的にソートされて格納されるため、検索、挿入、削除が高速です (`O(log n)`)。 * **一意なキー**: `std::map`内のキーは重複しません。同じキーで値を挿入しようとすると、既存の値が上書きされます。 -`std::map`を使うには、``ヘッダをインクルードする必要があります。 +`std::map`を使うには、``ヘッダを[[インクルード]]する必要があります。 ```cpp:map_example.cpp #include diff --git a/public/docs/cpp/10-stl-containers/4-0-other.md b/public/docs/cpp/10-stl-containers/4-0-other.md index 3a2598e6..687ae098 100644 --- a/public/docs/cpp/10-stl-containers/4-0-other.md +++ b/public/docs/cpp/10-stl-containers/4-0-other.md @@ -19,4 +19,4 @@ STLには、他にも特定の目的に特化したコンテナが多数用意 * `std::unordered_map`: `std::map`と同様にキーと値のペアを管理しますが、内部的にハッシュテーブルを使うため、平均的な検索・挿入・削除がさらに高速 (`O(1)`) です。ただし、要素はソートされません。``ヘッダが必要です。 * `std::queue`, `std::stack`: それぞれ先入れ先出し (FIFO)、後入れ先出し (LIFO) のデータ構造を実装するためのコンテナアダプタです。 -どのコンテナを選択するかは、プログラムの要件(データのアクセスパターン、挿入・削除の頻度など)によって決まります。まずは`std::vector`を基本とし、必要に応じて他のコンテナを検討するのが良いアプローチです。 +どのコンテナを選択するかは、プログラムの要件(データのアクセスパターン、挿入・削除の頻度など)によって決まります。まずは[[`std::vector`]]を基本とし、必要に応じて他のコンテナを検討するのが良いアプローチです。 diff --git a/public/docs/cpp/10-stl-containers/5-2-practice2.md b/public/docs/cpp/10-stl-containers/5-2-practice2.md index cd92a0f8..b03fee27 100644 --- a/public/docs/cpp/10-stl-containers/5-2-practice2.md +++ b/public/docs/cpp/10-stl-containers/5-2-practice2.md @@ -14,7 +14,7 @@ question: 英文(スペースで区切られた単語の列)を読み込み、各単語が何回出現したかをカウントするプログラムを`std::map`を使って作成してください。最後に、出現した全単語とその出現回数をアルファベット順に表示してください。 -> 文字列を単語ごとに分割するには、以下のように`std::istringstream`を使うと便利です。 +> [[文字列]]を単語ごとに分割するには、以下のように`std::istringstream`を使うと便利です。 ```cpp #include diff --git a/public/docs/cpp/11-stl-algorithms/-intro.md b/public/docs/cpp/11-stl-algorithms/-intro.md index 6e0f4032..564ca962 100644 --- a/public/docs/cpp/11-stl-algorithms/-intro.md +++ b/public/docs/cpp/11-stl-algorithms/-intro.md @@ -1,3 +1,3 @@ -前の章ではSTLのコンテナについて学び、様々なデータを効率的に格納する方法を見てきました。しかし、データを格納するだけではプログラムは完成しません。そのデータを並べ替えたり、検索したり、特定の処理を施したりといった「操作」が必要です。 +[[./10]]ではSTLのコンテナについて学び、様々なデータを効率的に格納する方法を見てきました。しかし、データを格納するだけではプログラムは完成しません。そのデータを並べ替えたり、検索したり、特定の処理を施したりといった「操作」が必要です。 この章では、STLのもう一つの強力な柱である**アルゴリズム**ライブラリを学びます。これらのアルゴリズムは、コンテナ内のデータを操作するための汎用的な関数群です。そして、アルゴリズムをさらに柔軟かつ強力にするための現代的なC++の機能、**ラムダ式**についても解説します。これらをマスターすれば、驚くほど少ないコードで複雑なデータ操作が実現できるようになります。 diff --git a/public/docs/cpp/11-stl-algorithms/1-0-about.md b/public/docs/cpp/11-stl-algorithms/1-0-about.md index d2b25f13..9a70c448 100644 --- a/public/docs/cpp/11-stl-algorithms/1-0-about.md +++ b/public/docs/cpp/11-stl-algorithms/1-0-about.md @@ -14,9 +14,9 @@ question: ## イテレータ:コンテナとアルゴリズムを繋ぐ架け橋 -アルゴリズムは、特定のコンテナ(`std::vector` や `std::list` など)に直接依存しないように設計されています。では、どうやってコンテナ内の要素にアクセスするのでしょうか?そこで登場するのが**イテレータ (Iterator)** です。 +アルゴリズムは、特定のコンテナ([[`std::vector`]] や `std::list` など)に直接依存しないように設計されています。では、どうやってコンテナ内の要素にアクセスするのでしょうか?そこで登場するのが**イテレータ (Iterator)** です。 -イテレータは、コンテナ内の要素を指し示す「ポインタのような」オブジェクトです。ポインタのように `*` で要素の値を参照したり、`++` で次の要素に進んだりできます。 +イテレータは、コンテナ内の要素を指し示す「[[ポインタ]]のような」オブジェクトです。[[ポインタ]]のように `*` で要素の値を参照したり、`++` で次の要素に進んだりできます。 ほとんどのコンテナは、以下の2つの重要なイテレータを取得するメンバ関数を持っています。 @@ -25,7 +25,11 @@ question: アルゴリズムは、この `begin()` と `end()` から得られるイテレータのペアを使い、操作対象の「範囲」を指定します。範囲は半開区間 `[begin, end)` で表され、`begin` が指す要素は範囲に含まれ、`end` が指す要素は含まれません。 -簡単な例を見てみましょう。イテレータを使って `vector` の全要素を表示するコードです。 +> [!TIP] +> [[範囲ベース for ループ]] では内部でイテレータが使われており、 [[`std::vector`]] などに限らずイテレータが取得できるオブジェクトに対して使用できます。 + +簡単な例を見てみましょう。イテレータを使って [[`std::vector`]] の全要素を表示するコードです。 +このように、イテレータはコンテナの種類を問わず、統一的な方法で要素にアクセスする仕組みを提供します。これが、アルゴリズムが様々なコンテナに対して汎用的に機能する理由です。 ```cpp:iterator_example.cpp #include @@ -41,7 +45,7 @@ int main() { } std::cout << std::endl; - // C++11以降の範囲ベースforループ (内部ではイテレータが使われている) + // C++11以降の範囲ベースforループ std::cout << "Numbers (range-based for): "; for (int num : numbers) { std::cout << num << " "; @@ -56,5 +60,3 @@ int main() { Numbers: 0 1 2 3 4 Numbers (range-based for): 0 1 2 3 4 ``` - -このように、イテレータはコンテナの種類を問わず、統一的な方法で要素にアクセスする仕組みを提供します。これが、アルゴリズムが様々なコンテナに対して汎用的に機能する理由です。 diff --git a/public/docs/cpp/11-stl-algorithms/2-3-foreach.md b/public/docs/cpp/11-stl-algorithms/2-3-foreach.md index 6c21dfde..d48adec7 100644 --- a/public/docs/cpp/11-stl-algorithms/2-3-foreach.md +++ b/public/docs/cpp/11-stl-algorithms/2-3-foreach.md @@ -10,7 +10,7 @@ question: ### `std::for_each`: 各要素に処理を適用する -指定された範囲の全ての要素に対して、特定の関数(処理)を適用します。ループを書くよりも意図が明確になる場合があります。 +指定された範囲の全ての要素に対して、特定の関数(処理)を適用します。 [[`for`]] ループを書くよりも意図が明確になる場合があります。 ```cpp // 3番目の引数に関数を渡す diff --git a/public/docs/cpp/11-stl-algorithms/3-0-lambda.md b/public/docs/cpp/11-stl-algorithms/3-0-lambda.md index 3373bab8..e57f1b38 100644 --- a/public/docs/cpp/11-stl-algorithms/3-0-lambda.md +++ b/public/docs/cpp/11-stl-algorithms/3-0-lambda.md @@ -21,11 +21,11 @@ question: [キャプチャ](引数リスト) -> 戻り値の型 { 処理本体 } ``` - * `[]` **キャプチャ句**: ラムダ式の外にある変数を取り込んで、式の中で使えるようにします。 + * `[]` **キャプチャ句**: ラムダ式の外にある[[変数]]を取り込んで、式の中で使えるようにします。 * `[]`: 何もキャプチャしない。 - * `[=]`: 外の変数を全て値渡し(コピー)でキャプチャする。 - * `[&]`: 外の変数を全て参照渡しでキャプチャする。 - * `[x, &y]`: 変数 `x` は値渡し、変数 `y` は参照渡しでキャプチャする。 + * `[=]`: 外の変数を全て[[値渡し]](コピー)でキャプチャする。 + * `[&]`: 外の変数を全て[[参照渡し]]でキャプチャする。 + * `[x, &y]`: 変数 `x` は[[値渡し]]、変数 `y` は[[参照渡し]]でキャプチャする。 * `()` **引数リスト**:通常の関数と同じ引数を取ることができます。 * `-> 戻り値の型`: 戻り値の型を指定します。多くの場合、コンパイラが推論できるため省略可能です。 * `{}` **処理本体**: 関数の処理内容を記述します。 diff --git a/public/docs/cpp/11-stl-algorithms/4-1-practice1.md b/public/docs/cpp/11-stl-algorithms/4-1-practice1.md index d7ea52d1..600986ff 100644 --- a/public/docs/cpp/11-stl-algorithms/4-1-practice1.md +++ b/public/docs/cpp/11-stl-algorithms/4-1-practice1.md @@ -10,7 +10,7 @@ question: ### 練習問題1: 文字列の長さでソート -`std::vector` を用意し、格納されている文字列を、文字数が短い順にソートして、結果を出力するプログラムを作成してください。`std::sort` とラムダ式を使用してください。 +`std::vector` を用意し、格納されている[[文字列]]を、文字数が短い順にソートして、結果を出力するプログラムを作成してください。`std::sort` とラムダ式を使用してください。 **ヒント**: ラムダ式は2つの文字列を引数に取り、1つ目の文字列の長さが2つ目の文字列の長さより短い場合に `true` を返すように実装します。 diff --git a/public/docs/cpp/11-stl-algorithms/4-2-practice2.md b/public/docs/cpp/11-stl-algorithms/4-2-practice2.md index 74dd06f2..b98f0ef6 100644 --- a/public/docs/cpp/11-stl-algorithms/4-2-practice2.md +++ b/public/docs/cpp/11-stl-algorithms/4-2-practice2.md @@ -15,7 +15,7 @@ question: 1. 正の偶数である要素の数 2. 負の奇数である要素の数 -**ヒント**: カウント用の変数を2つ用意し、ラムダ式のキャプチャ句で参照キャプチャ (`[&]`) して、式の中でインクリメントします。 +**ヒント**: カウント用の[[変数]]を2つ用意し、ラムダ式のキャプチャ句で参照キャプチャ (`[&]`) して、式の中でインクリメントします。 ```cpp:practice12_2.cpp #include diff --git a/public/docs/cpp/12-raii-smart-ptrs/-intro.md b/public/docs/cpp/12-raii-smart-ptrs/-intro.md index 25581898..a3b29f71 100644 --- a/public/docs/cpp/12-raii-smart-ptrs/-intro.md +++ b/public/docs/cpp/12-raii-smart-ptrs/-intro.md @@ -1,3 +1,3 @@ -これまでの章で、`new` と `delete` を使った動的なメモリ管理を学びました。しかし、これらの手動管理は `delete` の呼び忘れによるメモリリークや、複雑なコードでのリソース管理の煩雑さを引き起こす原因となりがちです。 +[[./3]]で、[[`new`]] と [[`delete`]] を使った動的なメモリ管理を学びました。しかし、これらの手動管理は `delete` の呼び忘れによるメモリリークや、複雑なコードでのリソース管理の煩雑さを引き起こす原因となりがちです。 C++11以降の「モダンC++」では、こうした問題を解決するための洗練された仕組みが導入されました。この章では、エラーハンドリングのための**例外処理**、リソース管理の基本思想である **RAIIイディオム**、そしてそれを具現化する**スマートポインタ** (`std::unique_ptr`, `std::shared_ptr`) について学び、より安全で堅牢なコードを書くための流儀を身につけます。 diff --git a/public/docs/cpp/12-raii-smart-ptrs/1-1-leak.md b/public/docs/cpp/12-raii-smart-ptrs/1-1-leak.md index d34991c1..679ad666 100644 --- a/public/docs/cpp/12-raii-smart-ptrs/1-1-leak.md +++ b/public/docs/cpp/12-raii-smart-ptrs/1-1-leak.md @@ -11,7 +11,7 @@ question: ### 例外とリソースリーク -ここで、`new` と `delete` を使った手動のメモリ管理と例外処理が組み合わさると、問題が発生します。 +ここで、[[`new`]] と [[`delete`]] を使った手動のメモリ管理と例外処理が組み合わさると、問題が発生します。 ```cpp:raw_pointer_problem.cpp #include @@ -48,6 +48,6 @@ Data allocated. Error: Something went wrong during processing! ``` -この例では、`process_data` 関数内で `throw` が実行されると、関数の実行が中断され `catch` ブロックにジャンプします。その結果、`delete[] data;` の行が実行されず、確保されたメモリが解放されない**メモリリーク**が発生します。 +この例では、`process_data` 関数内で `throw` が実行されると、関数の実行が中断され `catch` ブロックにジャンプします。その結果、`delete[] data;` の行が実行されず、確保されたメモリが解放されない**[[メモリリーク]]**が発生します。 この問題を解決するのが、C++の最も重要な設計思想の一つである **RAII** です。 diff --git a/public/docs/cpp/12-raii-smart-ptrs/2-0-raii.md b/public/docs/cpp/12-raii-smart-ptrs/2-0-raii.md index 998402ff..87b9c8f1 100644 --- a/public/docs/cpp/12-raii-smart-ptrs/2-0-raii.md +++ b/public/docs/cpp/12-raii-smart-ptrs/2-0-raii.md @@ -14,9 +14,9 @@ question: **RAII (Resource Acquisition Is Initialization)** は、「リソースの確保は、オブジェクトの初期化時に行い、リソースの解放は、オブジェクトの破棄時に行う」という設計パターンです。日本語では「リソース取得は初期化である」と訳されます。 -C++では、オブジェクトがそのスコープ(変数が宣言された `{}` の範囲)を抜けるときに、そのオブジェクトの**デストラクタ**が自動的に呼び出されます。この仕組みは、関数が正常に終了した場合だけでなく、**例外が投げられてスコープを抜ける場合でも保証されています**。 +C++では、オブジェクトがそのスコープ([[変数]]が宣言された `{}` の範囲)を抜けるときに、そのオブジェクトの**デストラクタ**が自動的に呼び出されます。この仕組みは、関数が正常に終了した場合だけでなく、**例外が投げられてスコープを抜ける場合でも保証されています**。 -RAIIはこの性質を利用して、リソースの解放処理をデストラクタに記述することで、リソースの解放を自動化し、`delete` の呼び忘れや例外発生時のリソースリークを防ぎます。 +RAIIはこの性質を利用して、リソースの解放処理をデストラクタに記述することで、リソースの解放を自動化し、[[`delete`]] の呼び忘れや例外発生時のリソースリークを防ぎます。 簡単なRAIIクラスの例を見てみましょう。 diff --git a/public/docs/cpp/12-raii-smart-ptrs/3-0-smartptr.md b/public/docs/cpp/12-raii-smart-ptrs/3-0-smartptr.md index 631896e0..0e2f962a 100644 --- a/public/docs/cpp/12-raii-smart-ptrs/3-0-smartptr.md +++ b/public/docs/cpp/12-raii-smart-ptrs/3-0-smartptr.md @@ -10,6 +10,6 @@ question: ## スマートポインタ: new/deleteを自動化する -スマートポインタは、RAIIを実装したクラステンプレートで、生ポインタ (`int*` など) のように振る舞いながら、リソース (確保したメモリ) の所有権を管理し、適切なタイミングで自動的に解放してくれます。 +スマートポインタは、RAIIを実装したクラステンプレートで、生[[ポインタ]] (`int*` など) のように振る舞いながら、リソース (確保したメモリ) の所有権を管理し、適切なタイミングで自動的に解放してくれます。 -モダンC++では、メモリ管理に生ポインタを直接使うことはほとんどなく、スマートポインタを使うのが基本です。主に2種類のスマートポインタを使い分けます。 +モダンC++では、メモリ管理に生[[ポインタ]]を直接使うことはほとんどなく、スマートポインタを使うのが基本です。主に2種類のスマートポインタを使い分けます。 diff --git a/public/docs/cpp/12-raii-smart-ptrs/3-2-sharedptr.md b/public/docs/cpp/12-raii-smart-ptrs/3-2-sharedptr.md index 8c5986a1..b42d6093 100644 --- a/public/docs/cpp/12-raii-smart-ptrs/3-2-sharedptr.md +++ b/public/docs/cpp/12-raii-smart-ptrs/3-2-sharedptr.md @@ -16,7 +16,7 @@ question: `std::shared_ptr` は、管理するオブジェクトの**所有権を複数のポインタで共有できる**スマートポインタです。 * **共有された所有権**: `shared_ptr` は自由にコピーできます。コピーされるたびに、内部の**参照カウンタ**が増加します。 - * **自動解放**: `shared_ptr` が破棄される(デストラクタが呼ばれる)と参照カウンタが減少し、**参照カウンタが0になったとき**に、管理しているオブジェクトが解放(`delete`)されます。 + * **自動解放**: `shared_ptr` が破棄される(デストラクタが呼ばれる)と参照カウンタが減少し、**参照カウンタが0になったとき**に、管理しているオブジェクトが解放([[`delete`]])されます。 * **オーバーヘッド**: 参照カウンタを管理するための追加のメモリと処理が必要なため、`unique_ptr` よりもわずかにオーバーヘッドが大きいです。 `shared_ptr` を作成するには、`std::make_shared` を使うのが効率的で安全です。 diff --git a/public/docs/cpp/12-raii-smart-ptrs/4-0-summary.md b/public/docs/cpp/12-raii-smart-ptrs/4-0-summary.md index a137263a..6ad99463 100644 --- a/public/docs/cpp/12-raii-smart-ptrs/4-0-summary.md +++ b/public/docs/cpp/12-raii-smart-ptrs/4-0-summary.md @@ -11,8 +11,8 @@ question: * **例外処理**は `try`, `catch`, `throw` を使い、エラーが発生してもプログラムを安全に継続させるための仕組みです。 * 手動のメモリ管理下で例外が発生すると、**リソースリーク**を引き起こす危険があります。 * **RAIIイディオム**は、リソースの確保をコンストラクタ、解放をデストラクタで行うことで、リソース管理を自動化するC++の重要な設計思想です。 - * **スマートポインタ**はRAIIを動的メモリ管理に適用したもので、`new` と `delete` の手動管理を不要にします。 + * **スマートポインタ**はRAIIを動的メモリ管理に適用したもので、[[`new`]] と [[`delete`]] の手動管理を不要にします。 * **`std::unique_ptr`** はオブジェクトの**唯一の所有権**を管理します。軽量であり、所有権が明確な場合に第一の選択肢となります。 * **`std::shared_ptr`** はオブジェクトの**所有権を共有**します。参照カウントによって管理され、最後の所有者がいなくなったときにオブジェクトを解放します。 -モダンC++プログラミングでは、`new` と `delete` を直接書くことは極力避け、RAIIとスマートポインタを全面的に活用することが、安全でメンテナンス性の高いコードへの第一歩です。 +モダンC++プログラミングでは、[[`new`]] と [[`delete`]] を直接書くことは極力避け、RAIIとスマートポインタを全面的に活用することが、安全でメンテナンス性の高いコードへの第一歩です。 diff --git a/public/docs/cpp/12-raii-smart-ptrs/4-1-practice1.md b/public/docs/cpp/12-raii-smart-ptrs/4-1-practice1.md index 44fbe031..77311629 100644 --- a/public/docs/cpp/12-raii-smart-ptrs/4-1-practice1.md +++ b/public/docs/cpp/12-raii-smart-ptrs/4-1-practice1.md @@ -11,7 +11,7 @@ question: `Employee` という名前のクラスを作成してください。このクラスは、コンストラクタで社員名を受け取って表示し、デストラクタで「(社員名) is leaving.」というメッセージを表示します。 -`main` 関数で、`"Alice"` という名前の `Employee` オブジェクトを `std::make_unique` で作成し、その `unique_ptr` を `promote_employee` という関数に渡してください。`promote_employee` 関数は `unique_ptr` を引数として受け取り(所有権が移動します)、「(社員名) has been promoted\!」というメッセージを表示します。 +[[`main` 関数]]で、`"Alice"` という名前の `Employee` オブジェクトを `std::make_unique` で作成し、その `unique_ptr` を `promote_employee` という関数に渡してください。`promote_employee` 関数は `unique_ptr` を引数として受け取り(所有権が移動します)、「(社員名) has been promoted\!」というメッセージを表示します。 プログラムを実行し、コンストラクタとデストラクタのメッセージが期待通りに表示されることを確認してください。 diff --git a/public/docs/cpp/12-raii-smart-ptrs/4-2-practice2.md b/public/docs/cpp/12-raii-smart-ptrs/4-2-practice2.md index fbe22482..d104a2eb 100644 --- a/public/docs/cpp/12-raii-smart-ptrs/4-2-practice2.md +++ b/public/docs/cpp/12-raii-smart-ptrs/4-2-practice2.md @@ -11,7 +11,7 @@ question: `Project` という名前のクラスを作成してください。コンストラクタでプロジェクト名を受け取り、デストラクタで「Project (プロジェクト名) is finished.」と表示します。 -`main` 関数で、`"Project Phoenix"` という名前の `Project` オブジェクトを `std::make_shared` で作成してください。 +[[`main` 関数]]で、`"Project Phoenix"` という名前の `Project` オブジェクトを `std::make_shared` で作成してください。 次に、`std::vector>` を作成し、作成した `shared_ptr` を2回 `push_back` してください。 その後、`shared_ptr` の参照カウント (`use_count()`) を表示してください。 最後に、`vector` を `clear()` して、再度参照カウントを表示してください。 diff --git a/public/docs/cpp/2-data-containers/-intro.md b/public/docs/cpp/2-data-containers/-intro.md index eebfba3f..a42fb7fb 100644 --- a/public/docs/cpp/2-data-containers/-intro.md +++ b/public/docs/cpp/2-data-containers/-intro.md @@ -1,3 +1,3 @@ -他の言語(Python, JavaScript, C\#など)経験者がC++を学び始めるとき、最も躓きやすいのが「文字や配列の扱い」です。古いC言語の教科書では、ポインタ操作やメモリ管理が必須となる「Cスタイル」のやり方から入ることが多いのですが、**現代の実務的なC++(モダンC++)では、もっと安全で便利な「クラス(コンテナ)」を使います。** +他の言語(Python, JavaScript, C\#など)経験者がC++を学び始めるとき、最も躓きやすいのが「文字や配列の扱い」です。古いC言語の教科書では、[[ポインタ]]操作やメモリ管理が必須となる「Cスタイル」のやり方から入ることが多いのですが、**現代の実務的なC++(モダンC++)では、もっと安全で便利な「クラス(コンテナ)」を使います。** この章では、ポインタの複雑な話を抜きにして、他の高級言語と同じくらい直感的にデータを扱えるツールを紹介します。 diff --git a/public/docs/cpp/2-data-containers/1-0-string.md b/public/docs/cpp/2-data-containers/1-0-string.md index 79145b68..a1cf041b 100644 --- a/public/docs/cpp/2-data-containers/1-0-string.md +++ b/public/docs/cpp/2-data-containers/1-0-string.md @@ -8,21 +8,25 @@ question: - 文字列を結合する際に、+演算子をたくさん使うとパフォーマンスに影響はありますか? - std::stringを使うためには必ず#include が必要ですか? - std::stringの.size()メソッドは、半角英数字以外の文字(日本語など)でも正しく文字数を数えられますか? +term: + - 文字列 + - std::string --- ## 文字列の扱い:`std::string` -C言語では文字列を扱うために `char*` や `char[]` を使い、ヌル終端文字 `\0` を意識する必要がありました。これはバグの温床です。 +C言語では文字列を扱うために [[`char*`]] や `char[]` を使い、ヌル終端文字 `\0` を意識する必要がありました。これはバグの温床です。 C++では、標準ライブラリの `std::string` クラスを使用します。これはPythonの `str` や Javaの `String` のように直感的に扱えます。 **主な機能** - * **代入・初期化**: 文字列リテラルをそのまま代入可能。 + * **代入・[[初期化]]**: 文字列リテラルをそのまま代入可能。 * **結合**: `+` 演算子で結合可能。 * **比較**: `==`, `!=` などで中身の文字列比較が可能(C言語の `strcmp` は不要)。 * **サイズ取得**: `.size()` または `.length()` メソッドを使用。 - +> [!NOTE] +> `std::string` は必要に応じて自動的にメモリを拡張します。プログラマがメモリ確保(malloc/free)を気にする必要はありません。 ```cpp:string_demo.cpp #include @@ -61,5 +65,3 @@ Length: 13 Greeting matches 'Hello'. Modified: hello, World! ``` - -> **Note:** `std::string` は必要に応じて自動的にメモリを拡張します。プログラマがメモリ確保(malloc/free)を気にする必要はありません。 diff --git a/public/docs/cpp/2-data-containers/2-0-vector.md b/public/docs/cpp/2-data-containers/2-0-vector.md index 10ed711d..a9b4bc24 100644 --- a/public/docs/cpp/2-data-containers/2-0-vector.md +++ b/public/docs/cpp/2-data-containers/2-0-vector.md @@ -8,6 +8,9 @@ question: - .push_back()以外に、std::vectorの途中に要素を追加する方法はありますか? - intやdouble以外の型、例えばstd::stringや自分で作ったクラスのオブジェクトも格納できますか? - C++11以前の環境では初期化リストを使えないとのことですが、その場合はどうやって初期化すればいいですか? +term: + - 可変長配列 + - std::vector --- ## 可変長配列:`std::vector` diff --git a/public/docs/cpp/2-data-containers/3-0-array.md b/public/docs/cpp/2-data-containers/3-0-array.md index fb89a931..24fce885 100644 --- a/public/docs/cpp/2-data-containers/3-0-array.md +++ b/public/docs/cpp/2-data-containers/3-0-array.md @@ -9,14 +9,17 @@ question: 3>の違いをもっと詳しく知りたいです。なぜstd::arrayの方が良いのですか? - std::arrayは宣言時にサイズが固定されますが、後からサイズを変更することはできませんか? - 「スタック確保」とありますが、スタックとは何ですか?ヒープとは違うのですか? +term: + - 固定長配列 + - std::array --- ## 固定長配列:`std::array` -データの個数が決まっている場合(例えば、3次元座標、RGB値、固定バッファなど)は、`std::vector` よりも `std::array` が適しています。 +データの個数が決まっている場合(例えば、3次元座標、RGB値、固定バッファなど)は、[[`std::vector`]] よりも `std::array` が適しています。 -「なぜ昔ながらの `int arr[5];` を使わないの?」と思われるかもしれません。 -Cスタイルの配列は、他のコンテナ(vectorなど)と操作感が異なり、サイズ情報を自分で管理しなければならないなどの欠点があります。`std::array` はC配列のパフォーマンス(スタック確保)と、コンテナの利便性(`.size()`などが使える)を両立させたものです。 +> [!NOTE] +> 固定長の配列として、[[Cスタイルの配列]] (`int coords[3];` など) もあります。しかし、Cスタイルの配列は、他のコンテナ(vectorなど)と操作感が異なり、サイズ情報を自分で管理しなければならないなどの欠点があります。`std::array` はC配列のパフォーマンス([[スタック]]確保)と、コンテナの利便性(`.size()`などが使える)を両立させたものです。 ```cpp:array_demo.cpp #include diff --git a/public/docs/cpp/2-data-containers/4-0-range-based-for.md b/public/docs/cpp/2-data-containers/4-0-range-based-for.md index 79c5ccd1..0b9dfbd2 100644 --- a/public/docs/cpp/2-data-containers/4-0-range-based-for.md +++ b/public/docs/cpp/2-data-containers/4-0-range-based-for.md @@ -8,11 +8,13 @@ question: - 「要素を『コピー』して取り出す」とは具体的にどういうことですか? - 「const auto& item」の「&」は何を意味するのですか?なぜコピーコストを避けられるのですか? - 従来のforループ (int i = 0; ...) と範囲ベースforループでは、パフォーマンスに違いはありますか? +term: + - 範囲ベース for ループ --- ## 範囲ベース `for` ループ (Range-based for) -`std::vector` や `std::array` の中身を順番に処理する場合、インデックス `i` を使った `for (int i = 0; i < n; ++i)` は書くのが面倒ですし、境界外アクセスのリスクがあります。 +[[`std::vector`]] や [[`std::array`]] の中身を順番に処理する場合、インデックス `i` を使った [[`for`]] 文 (`for (int i = 0; i < n; ++i)`) は書くのが面倒ですし、境界外アクセスのリスクがあります。 モダンC++では、PythonやC\#の `foreach` に相当する **範囲ベース for ループ** が使えます。 @@ -22,7 +24,13 @@ for (要素の型 変数名 : コンテナ) { } ``` -ここで便利なのが、**`auto` キーワード**です。`auto` を使うと、コンパイラが型を自動推論してくれるため、型名を詳しく書く必要がなくなります。 +> [!TIP] +> ここで便利なのが、**[[`auto`]] キーワード**です。`auto` を使うと、コンパイラが型を自動推論してくれるため、型名を詳しく書く必要がなくなります。 + + + +> [!WARNING] +> 以下のコードの `auto item` は、要素を「コピー」して取り出します。[[`std::string`]] のような大きなデータを扱う場合、コピーコストを避けるために `const auto& item` (参照)を使うのが一般的ですが、これについては[[./5]]で詳しく解説します。今の段階では「`auto` でループが回せる」と覚えておけば十分です。 ```cpp:range_for_demo.cpp #include @@ -60,7 +68,3 @@ int main() { - Potion Total Score: 307 ``` - -> **Advanced Hint:** -> 上記の `auto item` は、要素を「コピー」して取り出します。`std::string` のような大きなデータを扱う場合、コピーコストを避けるために `const auto& item` (参照)を使うのが一般的ですが、これについては**第5章**で詳しく解説します。今の段階では「`auto` でループが回せる」と覚えておけば十分です。 - diff --git a/public/docs/cpp/2-data-containers/5-0-summary.md b/public/docs/cpp/2-data-containers/5-0-summary.md index f35a4848..73c74dcc 100644 --- a/public/docs/cpp/2-data-containers/5-0-summary.md +++ b/public/docs/cpp/2-data-containers/5-0-summary.md @@ -7,9 +7,9 @@ question: [] ## この章のまとめ -1. **文字列**: `char*` ではなく `std::string` を使う。結合や比較が簡単で安全。 -2. **動的配列**: データの増減がある場合は `std::vector` を使う。`push_back()` で追加できる。 -3. **固定配列**: サイズ固定の場合は `std::array` を使う。Cスタイル配列のモダンな代替。 -4. **ループ**: コンテナの全要素走査には「範囲ベース for ループ」と `auto` を使うとシンプルに書ける。 +1. **文字列**: [[`char*`]] ではなく [[`std::string`]] を使う。結合や比較が簡単で安全。 +2. **動的配列**: データの増減がある場合は [[`std::vector`]] を使う。`push_back()` で追加できる。 +3. **固定配列**: サイズ固定の場合は [[`std::array`]] を使う。Cスタイル配列のモダンな代替。 +4. **ループ**: コンテナの全要素走査には「[[範囲ベース for ループ]]」と [[`auto`]] を使うとシンプルに書ける。 これらの「標準ライブラリ(STL: Standard Template Library)」のコンテナを活用することで、メモリ管理の苦労を飛ばして、アプリケーションのロジックに集中できるようになります。 diff --git a/public/docs/cpp/2-data-containers/5-1-practice1.md b/public/docs/cpp/2-data-containers/5-1-practice1.md index bcf567b8..60ce51f8 100644 --- a/public/docs/cpp/2-data-containers/5-1-practice1.md +++ b/public/docs/cpp/2-data-containers/5-1-practice1.md @@ -9,8 +9,8 @@ question: ### 練習問題1: 数値リストの統計 -`std::vector` を使用して、好きな整数を5つほど格納してください(コード内で直接初期化して構いません)。 -その後、範囲ベース for ループを使用して、その数値の「合計」と「最大値」を求めて出力するプログラムを作成してください。 +`std::vector` を使用して、好きな整数を5つほど格納してください(コード内で直接[[初期化]]して構いません)。 +その後、[[範囲ベース for ループ]]を使用して、その数値の「合計」と「最大値」を求めて出力するプログラムを作成してください。 ```cpp:practice3_1.cpp #include diff --git a/public/docs/cpp/2-data-containers/5-2-practice2.md b/public/docs/cpp/2-data-containers/5-2-practice2.md index 25b13fe8..81a038c9 100644 --- a/public/docs/cpp/2-data-containers/5-2-practice2.md +++ b/public/docs/cpp/2-data-containers/5-2-practice2.md @@ -9,7 +9,9 @@ question: ### 練習問題2: 単語のフィルタリング 以下の単語リスト `words` の中から、**文字数(長さ)が5文字より大きい単語だけ**を選んで表示するプログラムを作成してください。 -(ヒント:`std::string` の `.size()` または `.length()` メソッドと `if` 文を使用します) + +> [!TIP] +> [[`std::string`]] の `.size()` または `.length()` メソッドと [[`if`]] 文を使用します) ```cpp:practice3_2.cpp #include diff --git a/public/docs/cpp/3-pointers/-intro.md b/public/docs/cpp/3-pointers/-intro.md index 00082dbb..685e1d61 100644 --- a/public/docs/cpp/3-pointers/-intro.md +++ b/public/docs/cpp/3-pointers/-intro.md @@ -1,6 +1,6 @@ ようこそ、C++学習の最大の山場へ。 -第3章までは、`std::vector`や`std::string`といった便利な機能を使ってきましたが、今回はその「裏側」で何が起きているかを覗き込みます。 +[[./2]]では、[[`std::vector`]]や[[`std::string`]]といった便利な機能を使ってきましたが、今回はその「裏側」で何が起きているかを覗き込みます。 他の言語(Java, Python, C\#など)では言語機能やガベージコレクション(GC)が隠蔽してくれている「メモリ」という物理的なリソースを、C++では直接操作することができます。これがC++の強力な武器であり、同時にバグの温床でもあります。 -ここを理解すれば、第3章の機能がいかに偉大だったか、そしてコンピュータが実際にどう動いているかが手に取るようにわかるようになります。 +ここを理解すれば、[[./2]]の機能がいかに偉大だったか、そしてコンピュータが実際にどう動いているかが手に取るようにわかるようになります。 diff --git a/public/docs/cpp/3-pointers/1-0-basic.md b/public/docs/cpp/3-pointers/1-0-basic.md index 1061d10d..edeca570 100644 --- a/public/docs/cpp/3-pointers/1-0-basic.md +++ b/public/docs/cpp/3-pointers/1-0-basic.md @@ -6,12 +6,16 @@ question: - ポインタは具体的にどのような場面で使うと便利なのか、例を挙げてほしい。 - ポインタを使うことでプログラムにどんなメリットがあるのか。 - ポインタ自体も変数とのことだが、ポインタ変数のアドレスはどうやって確認するのか。 +term: + - ポインタ + - アドレス --- ## ポインタの基礎 ポインタとは、変数の「値」ではなく、その変数がメモリ上の**どこにあるか(アドレス)**を格納する変数です。 -変数の型に応じて、対応するポインタの型が存在します。例えば、`int`型の変数のアドレスを格納するなら `int*` 型、`double`型の変数のアドレスを格納するなら `double*` 型のポインタを使います。アスタリスク `*` がポインタ型であることを示します。 +[[変数]]の型に応じて、対応するポインタの型が存在します。例えば、[[`int`]]型の変数のアドレスを格納するなら `int*` 型、[[`double`]]型の変数のアドレスを格納するなら `double*` 型のポインタを使います。アスタリスク `*` がポインタ型であることを示します。 +> [!INFO] > ポインタ変数の宣言時に `*` を型の横に付けるか、変数名の横に付けるかは好みが分かれますが、意味は同じです (`int* p;` と `int *p;` は等価)。このチュートリアルでは `int* p;` のように型の側に付けます。 diff --git a/public/docs/cpp/3-pointers/1-1-address-operator.md b/public/docs/cpp/3-pointers/1-1-address-operator.md index 5b1495c7..62696ca6 100644 --- a/public/docs/cpp/3-pointers/1-1-address-operator.md +++ b/public/docs/cpp/3-pointers/1-1-address-operator.md @@ -11,8 +11,8 @@ question: ### アドレスと間接参照 - * **アドレス演算子 `&`**: 変数のメモリ上の住所(アドレス)を取得します。 - * **間接参照演算子 `*`**: ポインタが指し示している住所に行き、その中身(値)にアクセスします。 + * **アドレス演算子 `&`**: [[変数]]のメモリ上の住所([[アドレス]])を取得します。 + * **間接参照演算子 `*`**: [[ポインタ]]が指し示している住所に行き、その中身(値)にアクセスします。 @@ -48,4 +48,5 @@ ptrが指す中身 (*ptr): 42 書き換え後のnumber: 100 ``` -※ アドレス(0x...)は実行環境ごとに異なります。 +> [!NOTE] +> アドレス(0x...)は実行環境ごとに異なります。 diff --git a/public/docs/cpp/3-pointers/1-2-nullptr.md b/public/docs/cpp/3-pointers/1-2-nullptr.md index 26e1af4b..12e7127b 100644 --- a/public/docs/cpp/3-pointers/1-2-nullptr.md +++ b/public/docs/cpp/3-pointers/1-2-nullptr.md @@ -6,12 +6,14 @@ question: - 初期化されていないポインタが「不定な場所を指す」とは具体的にどういう意味か。何が危険なのか。 - '`nullptr`、`NULL`、`0` はどれも「何も指していない」ことを表すように見えるが、なぜモダンC++では`nullptr`を使うべきなのか。' - ポインタを`nullptr`で初期化した後、後から他の変数のアドレスを指すように変更できるのか。 +term: + - nullptr --- ### `nullptr` の使用 -ポインタが「どこも指していない」ことを示したい場合、C++では `nullptr` を使用します。 -古いC++やC言語では `NULL` や `0` が使われていましたが、モダンC++では型安全な `nullptr` を使うのが鉄則です。初期化されていないポインタは不定な場所を指すため、必ず初期化しましょう。 +[[ポインタ]]が「どこも指していない」ことを示したい場合、C++では `nullptr` を使用します。 +古いC++やC言語では `NULL` や `0` が使われていましたが、モダンC++では型安全な `nullptr` を使うのが鉄則です。[[初期化]]されていない[[ポインタ]]は不定な場所を指すため、必ず初期化しましょう。 ```cpp:pointer_declaration.cpp #include diff --git a/public/docs/cpp/3-pointers/2-0-array.md b/public/docs/cpp/3-pointers/2-0-array.md index d9408be5..86b6b2af 100644 --- a/public/docs/cpp/3-pointers/2-0-array.md +++ b/public/docs/cpp/3-pointers/2-0-array.md @@ -7,14 +7,18 @@ question: - 「配列名の減衰」とは、いつどのように発生するのか。常に配列名がポインタになるのか。 - ポインタ演算で`+1`すると「その型のサイズ分」アドレスが移動するとのことだが、これは`int`以外の型でも同じなのか。 - '`*(ptr + 1)`のように括弧が必要なのはなぜか。`*ptr + 1`と書くとどうなるのか。' +term: + - Cスタイルの配列 + - Cスタイル配列 + - 生配列 --- ## 配列とポインタの関係 -第3章では `std::vector` を使いましたが、C++にはC言語互換の「生の配列(Cスタイル配列)」も存在します。これはサイズが固定で、機能が制限されています。 +[[./2]]では [[`std::vector`]] や [[`std::array`]] を使いましたが、C++にはC言語互換の「生の配列(Cスタイル配列)」も存在します。これはサイズが固定で、機能が制限されています。 -* **配列名の減衰(Decay):** 配列の名前は式の中で使うと、**「先頭要素へのポインタ」**として扱われます。これを「減衰(Decay)」と呼びます。 -* **ポインタ演算:** ポインタに対して数値を足し引きすると、**「その型のサイズ分」**だけアドレスが移動します。`int`(通常4バイト)のポインタに `+1` すると、メモリアドレスは4増えます。 +* **配列名の減衰(Decay):** 配列の名前は式の中で使うと、**「先頭要素への[[ポインタ]]」**として扱われます。これを「減衰(Decay)」と呼びます。 +* **ポインタ演算:** [[ポインタ]]に対して数値を足し引きすると、**「その型のサイズ分」**だけ[[アドレス]]が移動します。[[`int`]](通常4バイト)のポインタに `+1` すると、メモリアドレスは4増えます。 ```cpp:array_decay.cpp #include diff --git a/public/docs/cpp/3-pointers/3-0-legacy-string.md b/public/docs/cpp/3-pointers/3-0-legacy-string.md index c12c4c34..66046405 100644 --- a/public/docs/cpp/3-pointers/3-0-legacy-string.md +++ b/public/docs/cpp/3-pointers/3-0-legacy-string.md @@ -6,15 +6,23 @@ question: - '`const char* c_str = "Hello";` の`c_str`が指す文字列を変更することはできるのか。' - Cスタイル文字列の終端文字`\0`を忘れた場合、何が起こるのか。 - '`std::string`が推奨されるとのことだが、`char*`の知識は完全に不要になるのか。' +term: + - Cスタイルの文字列 + - Cスタイル文字列 + - char* + - char * --- ## 文字列リテラルと `char*` -`std::string` が登場する前、文字列は単なる `char` 型の配列でした。これを「Cスタイル文字列」と呼びます。 +[[`std::string`]] が登場する前、文字列は単なる [[`char`]] 型の生配列でした。これを「Cスタイル文字列」と呼びます。 現在でも、ライブラリとの連携などで頻繁に目にします。 Cスタイル文字列は、文字の並びの最後に「終端文字 `\0`(ヌル文字)」を置くことで終わりを表します。 +> [!IMPORTANT] +> モダンC++では基本的に [[`std::string`]] を使いましょう。`char*` は参照用やAPI互換のために使います。 + ```cpp:legacy_string.cpp #include #include @@ -44,4 +52,3 @@ C++ String: World Converted to C-Style: World ``` -**重要:** モダンC++では基本的に `std::string` を使いましょう。`char*` は参照用やAPI互換のために使います。 diff --git a/public/docs/cpp/3-pointers/4-1-stack.md b/public/docs/cpp/3-pointers/4-1-stack.md index 22df4076..1fbe66e7 100644 --- a/public/docs/cpp/3-pointers/4-1-stack.md +++ b/public/docs/cpp/3-pointers/4-1-stack.md @@ -6,10 +6,12 @@ question: - スタックのサイズ制限とは、具体的にどのくらいのサイズを指すのか。 - 関数のスコープを抜けるとスタック上の変数が「自動的に消滅」するとは、メモリから完全に削除されるということか。 - 再帰呼び出しを多用するとスタックオーバーフローが起きると聞いたことがあるが、それはスタックの性質とどう関係があるのか。 +term: + - スタック --- ### スタック (Stack) - * これまでの変数は主にここに置かれます。 + * これまでの[[変数]]は主にここに置かれます。 * 関数のスコープ `{ ... }` を抜けると**自動的に消滅**します。 * 管理が楽で高速ですが、サイズに制限があります。 diff --git a/public/docs/cpp/3-pointers/4-2-heap.md b/public/docs/cpp/3-pointers/4-2-heap.md index d8d1e71e..2810abc4 100644 --- a/public/docs/cpp/3-pointers/4-2-heap.md +++ b/public/docs/cpp/3-pointers/4-2-heap.md @@ -6,6 +6,10 @@ question: - '`new int(10);`と`new int;`の違いは何か。' - '`delete pInt;`と`delete[] pArray;`で`[]`がある場合とない場合の違いは何か。間違えて使ったらどうなるのか。' - メモリを解放した後にポインタを`nullptr`に設定する理由は何か。設定しないとどうなるのか。 +term: + - ヒープ + - new + - delete --- ### ヒープ (Heap) 領域と `new`, `delete` diff --git a/public/docs/cpp/3-pointers/4-4-memory-leak.md b/public/docs/cpp/3-pointers/4-4-memory-leak.md index e8dd1836..d7ea5361 100644 --- a/public/docs/cpp/3-pointers/4-4-memory-leak.md +++ b/public/docs/cpp/3-pointers/4-4-memory-leak.md @@ -7,16 +7,20 @@ question: - '`std::vector`や`std::string`が内部で`new`と`delete`を自動的に行ってくれるとは、具体的にどのような仕組みなのか。' - RAIIとは何か。なぜそれが生の`new/delete`よりも安全なのか。 - 生の`new/delete`を「最後の手段」とするのは、どのような状況を指すのか。 +term: + - メモリリーク --- ### 恐怖の「メモリリーク」 -もし `delete` を忘れるとどうなるでしょう? +もし [[`delete`]] を忘れるとどうなるでしょう? 確保されたメモリは、プログラムが終了するまで「使用中」のまま残ります。これを**メモリリーク**と呼びます。長時間動くサーバーなどでこれが起きると、メモリを食いつぶしてシステムがクラッシュします。 -**第3章の振り返り:** -`std::vector` や `std::string` は、内部で `new` と `delete` を自動的に行ってくれています。 +> [!TIP] +> **[[./2]]の振り返り:** +> [[`std::vector`]] や [[`std::string`]] は、内部で [[`new`]] と [[`delete`]] を自動的に行ってくれています。 - * 作成時に `new` で確保。 - * スコープを抜けるときに自動で `delete`(デストラクタ)。 - これがC++のクラスの強力な機能(RAII)です。生の `new/delete` を直接使うことは、モダンC++では「最後の手段」あるいは「ライブラリを作る側の仕事」と考えられています。 + * 作成時に [[`new`]] で確保。 + * スコープを抜けるときに自動で [[`delete`]](デストラクタ)。 + +これがC++のクラスの強力な機能(RAII)です。生の `new/delete` を直接使うことは、モダンC++では「最後の手段」あるいは「ライブラリを作る側の仕事」と考えられています。 diff --git a/public/docs/cpp/3-pointers/5-0-summary.md b/public/docs/cpp/3-pointers/5-0-summary.md index f7868e23..1c949b84 100644 --- a/public/docs/cpp/3-pointers/5-0-summary.md +++ b/public/docs/cpp/3-pointers/5-0-summary.md @@ -7,9 +7,9 @@ question: [] ## この章のまとめ -1. **ポインタ**はメモリアドレスを保持する変数。`&`で取得、`*`でアクセス。 -2. ポインタの初期化には `nullptr` を使う。 +1. **[[ポインタ]]**はメモリアドレスを保持する[[変数]]。`&`で取得、`*`でアクセス。 +2. ポインタの[[初期化]]には [[`nullptr`]] を使う。 3. **配列名**は先頭要素へのポインタとして振る舞う(減衰)。 4. `ptr + i` は、`ptr` の指す型 `i` 個分先のアドレスを指す。 -5. **ヒープメモリ**は `new` で確保し、必ず `delete` で解放する。 -6. `delete` を忘れると**メモリリーク**になる。これを防ぐために `std::vector` などのコンテナクラスが存在する。 +5. **[[ヒープ]]メモリ**は [[`new`]] で確保し、必ず [[`delete`]] で解放する。 +6. `delete` を忘れると**[[メモリリーク]]**になる。これを防ぐために [[`std::vector`]] などのコンテナクラスが存在する。 diff --git a/public/docs/cpp/3-pointers/5-1-practice1.md b/public/docs/cpp/3-pointers/5-1-practice1.md index 5554b5db..ea630c2d 100644 --- a/public/docs/cpp/3-pointers/5-1-practice1.md +++ b/public/docs/cpp/3-pointers/5-1-practice1.md @@ -9,7 +9,7 @@ question: ### 練習問題1: ポインタによる配列操作 -`int` 型のCスタイル配列 `arr` について、 `int*` 型のポインタを使って走査し、**すべての値を2倍に書き換えてください**(`[]` 演算子は使わず、ポインタ演算 `*` と `++` または `+` を使用すること)。 +[[`int`]] 型の[[Cスタイル配列]] `arr` について、 `int*` 型の[[ポインタ]]を使って走査し、**すべての値を2倍に書き換えてください**(`[]` 演算子は使わず、ポインタ演算 `*` と `++` または `+` を使用すること)。 ```cpp:practice4_1.cpp #include diff --git a/public/docs/cpp/3-pointers/5-2-practice2.md b/public/docs/cpp/3-pointers/5-2-practice2.md index 77db1520..fc79e11b 100644 --- a/public/docs/cpp/3-pointers/5-2-practice2.md +++ b/public/docs/cpp/3-pointers/5-2-practice2.md @@ -9,7 +9,7 @@ question: ### 問題2:手動メモリ管理の体験 -`n` 個の整数を格納できる配列を**ヒープ領域(`new`)**に確保してください。 +`n` 個の整数を格納できる配列を**[[ヒープ]]領域([[`new`]])**に確保してください。 その配列に 0 から `n-1` までの数値を代入し、合計値を計算して表示してください。 最後に、確保したメモリを適切に解放してください。 diff --git a/public/docs/cpp/4-functions/-intro.md b/public/docs/cpp/4-functions/-intro.md index 580dbf6a..a1f36b51 100644 --- a/public/docs/cpp/4-functions/-intro.md +++ b/public/docs/cpp/4-functions/-intro.md @@ -1,3 +1,3 @@ -前章(第4章)では、C++のメモリモデルの核心である「ポインタ」について学びました。ポインタは強力ですが、構文が複雑になりがちで、バグの温床にもなりえます。 +[[./3]]では、C++のメモリモデルの核心である「[[ポインタ]]」について学びました。ポインタは強力ですが、構文が複雑になりがちで、バグの温床にもなりえます。 C++では、C言語から受け継いだポインタに加え、より安全で直感的な**「参照(Reference)」**という概念が導入されています。本章では、関数の設計を通して、この「参照」がいかに強力な武器になるかを学びます。「データをどう渡すか」は、C++のパフォーマンスと設計の良し悪しを決める最も重要な要素の一つです。 diff --git a/public/docs/cpp/4-functions/1-1-prototype-declaration.md b/public/docs/cpp/4-functions/1-1-prototype-declaration.md index 86830ef1..c8d33759 100644 --- a/public/docs/cpp/4-functions/1-1-prototype-declaration.md +++ b/public/docs/cpp/4-functions/1-1-prototype-declaration.md @@ -7,11 +7,13 @@ question: - 関数をmain関数の後に定義するメリットは何ですか? - プロトタイプ宣言では引数名を省略しても良いのですか? - プロトタイプ宣言の最後にセミコロンが必要な理由は何ですか? +term: + - プロトタイプ宣言 --- ### プロトタイプ宣言 -関数を `main` 関数の後に定義したい場合、事前に「こういう名前と引数の関数がありますよ」と宣言だけしておく必要があります。これを**プロトタイプ宣言**と呼びます。 +関数を [[`main` 関数]]の後に定義したい場合、事前に「こういう名前と引数の関数がありますよ」と宣言だけしておく必要があります。これを**プロトタイプ宣言**と呼びます。 ```cpp:declaration_intro.cpp #include @@ -45,4 +47,4 @@ Hello C++! Hello C++! ``` -実際の開発では、プロトタイプ宣言をヘッダーファイル(`.h`)に書き、定義をソースファイル(`.cpp`)に書くことで、大規模なプログラムを管理します(これについては次章で詳しく解説します)。 +実際の開発では、プロトタイプ宣言を[[ヘッダーファイル]](`.h`)に書き、定義を[[ソースファイル]](`.cpp`)に書くことで、大規模なプログラムを管理します(これについては[[./5]]で詳しく解説します)。 diff --git a/public/docs/cpp/4-functions/1-2-void.md b/public/docs/cpp/4-functions/1-2-void.md index 892ab104..1874815e 100644 --- a/public/docs/cpp/4-functions/1-2-void.md +++ b/public/docs/cpp/4-functions/1-2-void.md @@ -6,6 +6,8 @@ question: - void型は「型がない」とのことですが、具体的にどのような場面で使われることが多いですか? - void型の変数を定義できないのはなぜですか? - 戻り値がない関数の中で、`return;` とだけ書くことはできますか? +term: + - void --- ### 戻り値がない場合: `void`型 @@ -16,4 +18,4 @@ question: void printMessage(std::string message); ``` -第2章で学んだように、`int`や`double`などの型は変数を定義するために使えましたが、`void`は「型がない」ことを示す特殊な型なので、`void my_variable;` のように変数を定義することはできません。あくまで関数の戻り値の型としてのみ使います。 +[[./1]]で学んだように、`int`や`double`などの型は[[変数]]を定義するために使えましたが、`void`は「型がない」ことを示す特殊な型なので、`void my_variable;` のように[[変数]]を定義することはできません。あくまで関数の戻り値の型としてのみ使います。 diff --git a/public/docs/cpp/4-functions/2-1-arg-by-value.md b/public/docs/cpp/4-functions/2-1-arg-by-value.md index 6dc83d56..76274aa7 100644 --- a/public/docs/cpp/4-functions/2-1-arg-by-value.md +++ b/public/docs/cpp/4-functions/2-1-arg-by-value.md @@ -6,15 +6,20 @@ question: - 値渡しで変数の「コピーが作成される」とは、メモリ上で具体的に何が起きるのですか? - 巨大な配列やオブジェクトを渡す際、「コストが高い」とはどのくらいのサイズからを指しますか? - 関数内で引数の値を変更しても呼び出し元に影響しないのは、どのような場合にメリットになりますか? +term: + - 値渡し --- ### 1\. 値渡し (Pass by Value) -特に何も指定しない場合のデフォルトです。変数の**コピー**が作成され、関数に渡されます。 +特に何も指定しない場合のデフォルトです。[[変数]]の**コピー**が作成され、関数に渡されます。 - * **メリット:** 安全。関数内で値を変更しても、呼び出し元の変数には影響しない。 + * **メリット:** 安全。関数内で値を変更しても、呼び出し元の[[変数]]には影響しない。 * **デメリット:** コストが高い。巨大な配列やオブジェクトを渡す際、丸ごとコピーするためメモリと時間を浪費する。 +> [!TIP] +> `int` や `double` などの[[基本型]] → **値渡し** でOK。 + ```cpp:pass_by_value.cpp diff --git a/public/docs/cpp/4-functions/2-2-arg-by-pointer.md b/public/docs/cpp/4-functions/2-2-arg-by-pointer.md index 50c1f6f7..55eade7c 100644 --- a/public/docs/cpp/4-functions/2-2-arg-by-pointer.md +++ b/public/docs/cpp/4-functions/2-2-arg-by-pointer.md @@ -6,14 +6,16 @@ question: - ポインタ渡しで「構文が汚れる」とは具体的にどのようなことですか? - ポインタ渡しで`nullptr`チェックが必要な理由は何ですか? - '`nullptr`を渡してしまった場合、どのような問題が起こりえますか?' +term: + - ポインタ渡し --- ### 2\. ポインタ渡し (Pass by Pointer) -C言語からある手法です。第4章で学んだポインタ(アドレス)を渡します。 +C言語からある手法です。[[./3]]で学んだ[[ポインタ]](アドレス)を渡します。 - * **メリット:** コピーが発生しない(アドレス値のコピーのみ)。呼び出し元のデータを変更できる。 - * **デメリット:** 呼び出す際に `&` を付ける必要がある。関数内で `*` や `->` を使う必要があり、構文が汚れる。`nullptr` チェックが必要になることがある。 + * **メリット:** コピーが発生しない([[アドレス]]値のコピーのみ)。呼び出し元のデータを変更できる。 + * **デメリット:** 呼び出す際に `&` を付ける必要がある。関数内で `*` や `->` を使う必要があり、構文が汚れる。[[`nullptr`]] チェックが必要になることがある。 diff --git a/public/docs/cpp/4-functions/2-3-arg-by-reference.md b/public/docs/cpp/4-functions/2-3-arg-by-reference.md index 69428ffa..b1808b09 100644 --- a/public/docs/cpp/4-functions/2-3-arg-by-reference.md +++ b/public/docs/cpp/4-functions/2-3-arg-by-reference.md @@ -6,15 +6,20 @@ question: - 「参照(Reference)」が既存の変数に別の名前をつける機能とは、具体的にどのようなイメージですか? - 参照渡しは`nullptr`にならないとのことですが、なぜですか? - 参照渡しで「意図しない変更に注意」とありますが、どのような場合に問題になりますか? +term: + - 参照渡し --- ### 3\. 参照渡し (Pass by Reference) -C++の真骨頂です。**「参照(Reference)」**とは、既存の変数に別の名前(エイリアス)をつける機能です。引数の型に `&` を付けるだけで宣言できます。 +C++の真骨頂です。**「参照(Reference)」**とは、既存の[[変数]]に別の名前(エイリアス)をつける機能です。引数の型に `&` を付けるだけで宣言できます。 - * **メリット:** コピーが発生しない。**構文は「値渡し」と同じように書ける**(`*`や`&`を呼び出し側で意識しなくていい)。`nullptr` になることがないため安全性が高い。 + * **メリット:** コピーが発生しない。**構文は「[[値渡し]]」と同じように書ける**(`*`や`&`を呼び出し側で意識しなくていい)。[[`nullptr`]] になることがないため安全性が高い。 * **デメリット:** 関数内で値を変更すると、呼び出し元も変わる(意図しない変更に注意)。 +> [!TIP] +> 変更させたいデータ → **参照渡し** (`T&`)。 + ```cpp:pass_by_ref.cpp diff --git a/public/docs/cpp/4-functions/2-4-arg-by-const-reference.md b/public/docs/cpp/4-functions/2-4-arg-by-const-reference.md index 2c468721..1276748d 100644 --- a/public/docs/cpp/4-functions/2-4-arg-by-const-reference.md +++ b/public/docs/cpp/4-functions/2-4-arg-by-const-reference.md @@ -6,6 +6,8 @@ question: - '`const`参照渡しがC++で最も頻繁に使われるパターンとされるのはなぜですか?' - '`const`参照渡しで関数内で値を変更しようとするとコンパイルエラーになるのは、具体的にどのような仕組みですか?' - '`int`や`double`のような基本型では値渡しで良いとのことですが、なぜ`const`参照渡しを使う必要がないのですか?' +term: + - const 参照渡し --- ### 4\. const 参照渡し (Pass by const Reference) @@ -13,10 +15,13 @@ question: これが**C++で最も頻繁に使われるパターン**です。「コピーはしたくない(重いから)。でも、関数内で書き換えられたくもない」という要求を満たします。 * **構文:** `const 型& 引数名` - * **用途:** `std::string`、`std::vector`、クラスのオブジェクトなど、サイズが大きくなる可能性があるデータ。 + * **用途:** [[`std::string`]]、[[`std::vector`]]、クラスのオブジェクトなど、サイズが大きくなる可能性があるデータ。 +> [!TIP] +> 変更しないがサイズが大きいデータ([[`std::string`]], [[`std::vector`]]など) → **const参照渡し** (`const T&`)。 + ```cpp:const_ref.cpp #include #include @@ -42,9 +47,3 @@ int main() { ```cpp-exec:const_ref.cpp Message: This is a potentially very large string... ``` - -> **ガイドライン:** -> -> * `int` や `double` などの基本型 → **値渡し** でOK。 -> * 変更させたいデータ → **参照渡し** (`T&`)。 -> * 変更しないがサイズが大きいデータ(string, vectorなど) → **const参照渡し** (`const T&`)。 diff --git a/public/docs/cpp/4-functions/3-1-overload.md b/public/docs/cpp/4-functions/3-1-overload.md index e2dcf0a9..26a6c748 100644 --- a/public/docs/cpp/4-functions/3-1-overload.md +++ b/public/docs/cpp/4-functions/3-1-overload.md @@ -6,6 +6,8 @@ question: - C言語では関数名がユニークである必要があったのに、C++でオーバーロードが可能になったのはなぜですか? - 戻り値の型だけが異なる関数を同じ名前で定義することはできますか? - オーバーロードされた関数を呼び出す際に、意図しない関数が呼び出されるようなことはありませんか? +term: + - オーバーロード --- ### オーバーロード (Function Overloading) diff --git a/public/docs/cpp/4-functions/3-2-default-arg.md b/public/docs/cpp/4-functions/3-2-default-arg.md index 5ddee356..afef412a 100644 --- a/public/docs/cpp/4-functions/3-2-default-arg.md +++ b/public/docs/cpp/4-functions/3-2-default-arg.md @@ -6,11 +6,13 @@ question: - デフォルト引数を「後ろの引数から順に」設定する必要があるのはなぜですか? - デフォルト引数を設定した場合でも、すべての引数を明示的に指定して関数を呼び出すことはできますか? - デフォルト引数はプロトタイプ宣言と定義の両方に記述するべきですか? +term: + - デフォルト引数 --- ### デフォルト引数 -引数が省略された場合に使われるデフォルト値を設定できます。これはプロトタイプ宣言(または最初にコンパイラが見る定義)に記述します。 +引数が省略された場合に使われるデフォルト値を設定できます。これは[[プロトタイプ宣言]](または最初にコンパイラが見る定義)に記述します。 ※デフォルト引数は**後ろの引数から順に**設定する必要があります。 ```cpp:default_args.cpp diff --git a/public/docs/cpp/4-functions/4-0-summary.md b/public/docs/cpp/4-functions/4-0-summary.md index ab95c027..b053f1a6 100644 --- a/public/docs/cpp/4-functions/4-0-summary.md +++ b/public/docs/cpp/4-functions/4-0-summary.md @@ -7,9 +7,9 @@ question: [] ## この章のまとめ - * **プロトタイプ宣言**を使うことで、関数の定義順序に依存せずに記述できる。 - * **値渡し**は安全だが、大きなオブジェクトではコピーコストがかかる。 - * **参照渡し (`&`)** は、ポインタのような効率性を持ちながら、変数のエイリアスとして直感的に扱える。 - * **`const` 参照渡し (`const T&`)** は、大きなデータを「読み取り専用」で効率的に渡すC++の定石である。 - * **オーバーロード**により、同じ名前で異なる引数を受け取る関数を作れる。 - * **デフォルト引数**で、呼び出し時の記述を省略できる。 + * **[[プロトタイプ宣言]]**を使うことで、関数の定義順序に依存せずに記述できる。 + * **[[値渡し]]**は安全だが、大きなオブジェクトではコピーコストがかかる。 + * **[[参照渡し]] (`&`)** は、[[ポインタ]]のような効率性を持ちながら、[[変数]]のエイリアスとして直感的に扱える。 + * **[[`const` 参照渡し]] (`const T&`)** は、大きなデータを「読み取り専用」で効率的に渡すC++の定石である。 + * **[[オーバーロード]]**により、同じ名前で異なる引数を受け取る関数を作れる。 + * **[[デフォルト引数]]**で、呼び出し時の記述を省略できる。 diff --git a/public/docs/cpp/4-functions/4-1-practice1.md b/public/docs/cpp/4-functions/4-1-practice1.md index 7090b8ea..0d6fe376 100644 --- a/public/docs/cpp/4-functions/4-1-practice1.md +++ b/public/docs/cpp/4-functions/4-1-practice1.md @@ -9,8 +9,8 @@ question: ### 練習問題1: 値の入れ替え(Swap) -2つの `int` 変数を受け取り、その値を入れ替える関数 `mySwap` を作成してください。 -ポインタではなく、**参照渡し**を使用してください。 +2つの `int` [[変数]]を受け取り、その値を入れ替える関数 `mySwap` を作成してください。 +[[ポインタ]]ではなく、**[[参照渡し]]**を使用してください。 ```cpp:practice5_1.cpp #include diff --git a/public/docs/cpp/4-functions/4-2-practice2.md b/public/docs/cpp/4-functions/4-2-practice2.md index c32114bd..f5251ce8 100644 --- a/public/docs/cpp/4-functions/4-2-practice2.md +++ b/public/docs/cpp/4-functions/4-2-practice2.md @@ -13,7 +13,7 @@ question: `std::vector` を受け取り、その中の「最大値」を見つけて返す関数 `findMax` を作成してください。 ただし、以下の条件を守ってください。 -1. ベクターはコピーされないようにしてください(**参照渡し**)。 +1. ベクターはコピーされないようにしてください(**[[参照渡し]]**)。 2. 関数内でベクターの内容が変更されないことを保証してください(**const**)。 3. ベクターが空の場合は `0` を返すなどの処理を入れてください。 diff --git a/public/docs/cpp/5-project-build/1-0-header-and-source.md b/public/docs/cpp/5-project-build/1-0-header-and-source.md index 1c04d952..bb98798e 100644 --- a/public/docs/cpp/5-project-build/1-0-header-and-source.md +++ b/public/docs/cpp/5-project-build/1-0-header-and-source.md @@ -7,17 +7,21 @@ question: - ヘッダファイルの拡張子には.hと.hppのどちらを使うべきですか? - コンパイル時間の短縮とは、具体的にどのようなメリットがあるのですか? - 「関心の分離」によって、具体的にどんなコードの見通しが良くなるのでしょうか? +term: + - ヘッダファイル + - ヘッダーファイル + - ソースファイル --- ## ヘッダファイルとソースファイル C++では、プログラムを**ヘッダファイル**と**ソースファイル**という2種類のファイルに分割するのが一般的です。 - * **ヘッダファイル (`.h` または `.hpp`)**: 「宣言」を置く場所です。クラスの定義、関数のプロトタイプ宣言、定数、テンプレートなどを記述します。他のファイルに対して「何ができるか(インターフェース)」を公開する役割を持ちます。 + * **ヘッダファイル (`.h` または `.hpp`)**: 「宣言」を置く場所です。クラスの定義、関数の[[プロトタイプ宣言]]、定数、テンプレートなどを記述します。他のファイルに対して「何ができるか(インターフェース)」を公開する役割を持ちます。 * **ソースファイル (`.cpp`)**: 「実装」を置く場所です。ヘッダファイルで宣言された関数の具体的な処理内容などを記述します。ヘッダファイルが公開したインターフェースを「どのように実現するか」を記述する役割を持ちます。 **なぜ分割するのか? 🤔** 1. **関心の分離**: インターフェース(何ができるか)と実装(どうやるか)を分離することで、コードの見通しが良くなります。他の開発者はヘッダファイルを見るだけで、その機能の使い方がわかります。 2. **コンパイル時間の短縮**: ソースファイルを変更した場合、再コンパイルはそのファイルだけで済みます。プロジェクト全体を再コンパイルする必要がないため、大規模なプロジェクトでは開発サイクルが劇的に速くなります。 -3. **再利用性の向上**: よく使う関数やクラスをまとめておけば、別のプロジェクトでそのファイルをインクルードするだけで簡単に再利用できます。 +3. **再利用性の向上**: よく使う関数やクラスをまとめておけば、別のプロジェクトでそのファイルを[[インクルード]]するだけで簡単に再利用できます。 diff --git a/public/docs/cpp/5-project-build/1-2-split-example.md b/public/docs/cpp/5-project-build/1-2-split-example.md index d78b168c..6cea2553 100644 --- a/public/docs/cpp/5-project-build/1-2-split-example.md +++ b/public/docs/cpp/5-project-build/1-2-split-example.md @@ -11,7 +11,7 @@ question: 簡単な足し算を行う関数を別のファイルに分割してみましょう。 -まず、関数の「宣言」をヘッダファイルに記述します。 +まず、関数の「宣言」を[[ヘッダファイル]]に記述します。 ```cpp:math_utils.h // 関数の宣言を記述するヘッダファイル @@ -20,7 +20,7 @@ question: int add(int a, int b); ``` -次に、この関数の「実装」をソースファイルに記述します。 +次に、この関数の「実装」を[[ソースファイル]]に記述します。 ```cpp:math_utils.cpp // 関数の実装を記述するソースファイル @@ -32,7 +32,7 @@ int add(int a, int b) { } ``` -最後に、`main`関数を含むメインのソースファイルから、この`add`関数を呼び出します。 +最後に、[[`main`関数]]を含むメインの[[ソースファイル]]から、この`add`関数を呼び出します。 ```cpp:math_app.cpp #include diff --git a/public/docs/cpp/5-project-build/2-0-include-guard.md b/public/docs/cpp/5-project-build/2-0-include-guard.md index a3363d2f..ebad9e70 100644 --- a/public/docs/cpp/5-project-build/2-0-include-guard.md +++ b/public/docs/cpp/5-project-build/2-0-include-guard.md @@ -6,13 +6,15 @@ question: - 「翻訳単位」とは何ですか? - 複数のファイルで同じヘッダがインクルードされたとき、どのようなエラーメッセージが出ますか? - インクルードガードがないと、必ずコンパイルエラーになりますか? +term: + - インクルードガード --- ## インクルードガード -複数のファイルから同じヘッダファイルがインクルードされる状況はよくあります。例えば、`A.h`が`B.h`をインクルードし、ソースファイルが`A.h`と`B.h`の両方をインクルードするような場合です。 +複数のファイルから同じ[[ヘッダファイル]]が[[インクルード]]される状況はよくあります。例えば、`A.h`が`B.h`を[[インクルード]]し、[[ソースファイル]]が`A.h`と`B.h`の両方をインクルードするような場合です。 -もしヘッダファイルに何の対策もしていないと、同じ内容(クラス定義や関数宣言)が複数回読み込まれ、「再定義」としてコンパイルエラーが発生してしまいます。 +もし[[ヘッダファイル]]に何の対策もしていないと、同じ内容(クラス定義や関数宣言)が複数回読み込まれ、「再定義」としてコンパイルエラーが発生してしまいます。 ```cpp:A.h #include "B.h" // B.hをインクルード @@ -49,4 +51,4 @@ B.h:1:7: note: previous definition of 'class B' | ^ ``` -この問題を解決するのが**インクルードガード**です。インクルードガードは、ヘッダファイルの内容が1つの翻訳単位(ソースファイル)内で一度しか読み込まれないようにするための仕組みです。 +この問題を解決するのが**インクルードガード**です。インクルードガードは、[[ヘッダファイル]]の内容が1つの翻訳単位([[ソースファイル]])内で一度しか読み込まれないようにするための仕組みです。 diff --git a/public/docs/cpp/5-project-build/2-2-pragma-once.md b/public/docs/cpp/5-project-build/2-2-pragma-once.md index 1913e227..d8c9fb9a 100644 --- a/public/docs/cpp/5-project-build/2-2-pragma-once.md +++ b/public/docs/cpp/5-project-build/2-2-pragma-once.md @@ -20,4 +20,4 @@ question: std::string to_upper(const std::string& str); ``` -この一行をヘッダファイルの先頭に書くだけで、コンパイラがそのファイルが一度しかインクルードされないように処理してくれます。特別な理由がない限り、現在では `#pragma once` を使うのが主流です。 +この一行を[[ヘッダファイル]]の先頭に書くだけで、コンパイラがそのファイルが一度しか[[インクルード]]されないように処理してくれます。特別な理由がない限り、現在では `#pragma once` を使うのが主流です。 diff --git a/public/docs/cpp/5-project-build/3-0-build.md b/public/docs/cpp/5-project-build/3-0-build.md index 510e29af..93aa8d6c 100644 --- a/public/docs/cpp/5-project-build/3-0-build.md +++ b/public/docs/cpp/5-project-build/3-0-build.md @@ -10,6 +10,6 @@ question: ## プロジェクトのビルド -複数のソースファイル(`.cpp`)は、それぞれがコンパイルされて**オブジェクトファイル**(`.o` や `.obj`)になります。その後、**リンカ**がこれらのオブジェクトファイルと必要なライブラリを結合して、最終的な実行可能ファイルを生成します。 +複数の[[ソースファイル]](`.cpp`)は、それぞれが[[コンパイル]]されて**オブジェクトファイル**(`.o` や `.obj`)になります。その後、**リンカ**がこれらのオブジェクトファイルと必要なライブラリを結合して、最終的な実行可能ファイルを生成します。 この一連の作業を**ビルド**と呼びます。ファイルが増えてくると、これを手動で行うのは非常に面倒です。そこで、ビルド作業を自動化する**ビルドシステム**が使われます。 diff --git a/public/docs/cpp/5-project-build/3-1-gcc-manual.md b/public/docs/cpp/5-project-build/3-1-gcc-manual.md index a9685d41..c567b789 100644 --- a/public/docs/cpp/5-project-build/3-1-gcc-manual.md +++ b/public/docs/cpp/5-project-build/3-1-gcc-manual.md @@ -24,7 +24,7 @@ g++ main.o math_utils.o -o my_app ./my_app ``` -または、以下のように1回のg++コマンドで複数ソースファイルのコンパイルとリンクを同時に行うこともできます。 +または、以下のように1回のg++コマンドで複数[[ソースファイル]]のコンパイルとリンクを同時に行うこともできます。 ```bash g++ math_app.cpp math_utils.cpp -o my_app diff --git a/public/docs/cpp/5-project-build/4-0-summary.md b/public/docs/cpp/5-project-build/4-0-summary.md index c2abe20b..b27ecd64 100644 --- a/public/docs/cpp/5-project-build/4-0-summary.md +++ b/public/docs/cpp/5-project-build/4-0-summary.md @@ -7,6 +7,6 @@ question: [] ## この章のまとめ - * **プロジェクトの分割**: プログラムは「宣言」を記述する**ヘッダファイル** (`.h`) と、「実装」を記述する**ソースファイル** (`.cpp`) に分割することで、保守性や再利用性が向上します。 - * **インクルードガード**: ヘッダファイルの多重インクルードによる再定義エラーを防ぐために、`#pragma once` や `#ifndef`/`#define`/`#endif` を使用します。 + * **プロジェクトの分割**: プログラムは「宣言」を記述する**[[ヘッダファイル]]** (`.h`) と、「実装」を記述する**[[ソースファイル]]** (`.cpp`) に分割することで、保守性や再利用性が向上します。 + * **[[インクルードガード]]**: [[ヘッダファイル]]の多重インクルードによる再定義エラーを防ぐために、`#pragma once` や `#ifndef`/`#define`/`#endif` を使用します。 * **ビルドシステム**: 複数のファイルをコンパイル・リンクするプロセスを自動化するために、`make` や `CMake` といったツールが使われます。特に **CMake** はクロスプラットフォーム開発におけるデファクトスタンダードです。 diff --git a/public/docs/cpp/6-classes-basics/1-0-about.md b/public/docs/cpp/6-classes-basics/1-0-about.md index 8b92d70d..88653354 100644 --- a/public/docs/cpp/6-classes-basics/1-0-about.md +++ b/public/docs/cpp/6-classes-basics/1-0-about.md @@ -13,7 +13,7 @@ question: 他のプログラミング言語でオブジェクト指向に触れたことがあるなら、「クラスはオブジェクトの設計図」という説明を聞いたことがあるかもしれません。C++でもその考え方は同じです。クラスは、ある「モノ」が持つべき**データ(属性)**と、そのデータに対する**処理(操作)**を一つにまとめたものです。 - - **データ(属性)**: クラス内に定義された変数のことで、**メンバ変数 (member variables)** または**データメンバ**と呼びます。 + - **データ(属性)**: クラス内に定義された[[変数]]のことで、**メンバ変数 (member variables)** または**データメンバ**と呼びます。 - **処理(操作)**: クラス内に定義された関数のことで、**メンバ関数 (member functions)** または**メソッド**と呼びます。 このように、関連するデータと処理を一つのクラスにまとめることを、OOPの重要な概念の一つである**カプセル化 (encapsulation)** と呼びます。💊 diff --git a/public/docs/cpp/6-classes-basics/2-0-instance.md b/public/docs/cpp/6-classes-basics/2-0-instance.md index 46b11360..32715d4d 100644 --- a/public/docs/cpp/6-classes-basics/2-0-instance.md +++ b/public/docs/cpp/6-classes-basics/2-0-instance.md @@ -12,7 +12,7 @@ question: クラスはあくまで「設計図」です。実際にプログラムで利用するためには、この設計図をもとに実体を作る必要があります。クラスから作られた実体のことを**オブジェクト (object)** または**インスタンス (instance)** と呼び、オブジェクトを作ることを**インスタンス化 (instantiation)** と言います。 -インスタンス化の構文は、変数の宣言とよく似ています。 +インスタンス化の構文は、[[変数]]の宣言とよく似ています。 ```cpp:instantiation.cpp #include diff --git a/public/docs/cpp/6-classes-basics/3-0-access-control.md b/public/docs/cpp/6-classes-basics/3-0-access-control.md index 1b39403a..ef4a3f84 100644 --- a/public/docs/cpp/6-classes-basics/3-0-access-control.md +++ b/public/docs/cpp/6-classes-basics/3-0-access-control.md @@ -11,7 +11,7 @@ question: ## アクセス制御: public と private による情報の隠蔽 -先ほどの`Person`クラスの例では、`main`関数から`taro.age = 30;`のようにメンバ変数に直接アクセスできました。これは手軽ですが、問題を引き起こす可能性があります。例えば、年齢にマイナスの値や非現実的な値を設定できてしまうかもしれません。 +先ほどの`Person`クラスの例では、[[`main`関数]]から`taro.age = 30;`のようにメンバ変数に直接アクセスできました。これは手軽ですが、問題を引き起こす可能性があります。例えば、年齢にマイナスの値や非現実的な値を設定できてしまうかもしれません。 ```cpp Person jiro; @@ -22,7 +22,7 @@ jiro.introduce(); このような意図しない操作を防ぐために、C++には**アクセス制御**の仕組みがあります。クラスのメンバは、外部からのアクセスの可否を指定できます。 - - **`public`**: クラスの外部(`main`関数など)から自由にアクセスできます。 + - **`public`**: クラスの外部([[`main`関数]]など)から自由にアクセスできます。 - **`private`**: そのクラスのメンバ関数からしかアクセスできません。外部からはアクセス不可です。 アクセス制御の基本は、**メンバ変数は`private`にし、メンバ関数は`public`にする**ことです。これにより、データの不正な書き換えを防ぎ、クラスの内部実装を外部から隠蔽します。これを**情報の隠蔽 (information hiding)** と呼び、カプセル化の重要な目的の一つです。 diff --git a/public/docs/cpp/6-classes-basics/4-1-constructor.md b/public/docs/cpp/6-classes-basics/4-1-constructor.md index 9c5b9eaa..7abefc38 100644 --- a/public/docs/cpp/6-classes-basics/4-1-constructor.md +++ b/public/docs/cpp/6-classes-basics/4-1-constructor.md @@ -16,8 +16,8 @@ question: コンストラクタには以下の特徴があります。 - 関数名がクラス名と全く同じ。 - - 戻り値の型を指定しない(`void`も付けない)。 - - 引数を取ることができ、複数定義できる(オーバーロード)。 + - 戻り値の型を指定しない([[`void`]]も付けない)。 + - 引数を取ることができ、複数定義できる([[オーバーロード]])。 ```cpp:constructor.cpp class Person { diff --git a/public/docs/cpp/6-classes-basics/4-2-destructor.md b/public/docs/cpp/6-classes-basics/4-2-destructor.md index d110ef84..1b049eb0 100644 --- a/public/docs/cpp/6-classes-basics/4-2-destructor.md +++ b/public/docs/cpp/6-classes-basics/4-2-destructor.md @@ -73,4 +73,4 @@ Destructor called for Kenji. --- Back in main --- ``` -実行結果を見ると、`kenji`オブジェクトが生成されたときにコンストラクタが、`create_person_scope`関数のスコープを抜けるときにデストラクタが自動的に呼び出されていることがわかります。動的に確保したメモリの解放など、クリーンアップ処理はデストラクタに書くのが定石です。この考え方は、今後の章で学ぶRAII(Resource Acquisition Is Initialization)という重要な概念に繋がります。 +実行結果を見ると、`kenji`オブジェクトが生成されたときにコンストラクタが、`create_person_scope`関数のスコープを抜けるときにデストラクタが自動的に呼び出されていることがわかります。動的に確保したメモリの解放など、クリーンアップ処理はデストラクタに書くのが定石です。この考え方は、[[./12]]で学ぶRAII(Resource Acquisition Is Initialization)という重要な概念に繋がります。 diff --git a/public/docs/cpp/6-classes-basics/5-0-summary.md b/public/docs/cpp/6-classes-basics/5-0-summary.md index 9b2b4862..caeb7b8b 100644 --- a/public/docs/cpp/6-classes-basics/5-0-summary.md +++ b/public/docs/cpp/6-classes-basics/5-0-summary.md @@ -16,4 +16,4 @@ question: [] - **コンストラクタ**は、オブジェクト生成時に自動で呼ばれ、初期化を行います。 - **デストラクタ**は、オブジェクト破棄時に自動で呼ばれ、後片付けを行います。 -クラスを使いこなすことで、プログラムの部品化が進み、再利用性やメンテナンス性が格段に向上します。次の章では、クラスのさらに進んだ機能について学んでいきましょう。 +クラスを使いこなすことで、プログラムの部品化が進み、再利用性やメンテナンス性が格段に向上します。[[./next]]では、クラスのさらに進んだ機能について学んでいきましょう。 diff --git a/public/docs/cpp/6-classes-basics/5-1-practice1.md b/public/docs/cpp/6-classes-basics/5-1-practice1.md index 17b475dc..f1dda969 100644 --- a/public/docs/cpp/6-classes-basics/5-1-practice1.md +++ b/public/docs/cpp/6-classes-basics/5-1-practice1.md @@ -15,7 +15,7 @@ question: - メンバ変数は`private`で定義してください。 - コンストラクタで幅と高さを初期化できるようにしてください。 - 面積を計算して返す`getArea()`メソッドと、周の長さを計算して返す`getPerimeter()`メソッドを`public`で実装してください。 - - `main`関数で`Rectangle`クラスのインスタンスをいくつか生成し、面積と周の長さを表示するプログラムを作成してください。 + - [[`main`関数]]で`Rectangle`クラスのインスタンスをいくつか生成し、面積と周の長さを表示するプログラムを作成してください。 ```cpp:practice7_1.cpp #include diff --git a/public/docs/cpp/6-classes-basics/5-2-practice2.md b/public/docs/cpp/6-classes-basics/5-2-practice2.md index a3b149fd..e8f192bc 100644 --- a/public/docs/cpp/6-classes-basics/5-2-practice2.md +++ b/public/docs/cpp/6-classes-basics/5-2-practice2.md @@ -15,7 +15,7 @@ question: - メンバ変数は`private`で定義してください。 - コンストラクタで、タイトル、著者、ページ数を初期化できるようにしてください。 - 本の情報を整形してコンソールに出力する`printInfo()`メソッドを`public`で実装してください。(例: `Title: [タイトル], Author: [著者], Pages: [ページ数] pages`) - - `main`関数で`Book`クラスのインスタンスを生成し、その情報を表示してください。 + - [[`main`関数]]で`Book`クラスのインスタンスを生成し、その情報を表示してください。 ```cpp:practice7_2.cpp #include diff --git a/public/docs/cpp/7-classes-advanced/-intro.md b/public/docs/cpp/7-classes-advanced/-intro.md index 490d0e05..46b1d270 100644 --- a/public/docs/cpp/7-classes-advanced/-intro.md +++ b/public/docs/cpp/7-classes-advanced/-intro.md @@ -1 +1 @@ -第7章では、C++のオブジェクト指向プログラミングの核となる`class`の基本的な使い方を学びました。しかし、クラスを真に強力なツールとして使いこなすには、もう少し知識が必要です。この章では、オブジェクトのコピー、演算子のオーバーロード、クラスで共有されるメンバなど、より実践的でパワフルな機能について掘り下げていきます。これらの概念をマスターすることで、あなたの書くクラスはより安全で、直感的で、再利用性の高いものになるでしょう。 +[[./6]]では、C++のオブジェクト指向プログラミングの核となる`class`の基本的な使い方を学びました。しかし、クラスを真に強力なツールとして使いこなすには、もう少し知識が必要です。この章では、オブジェクトのコピー、演算子のオーバーロード、クラスで共有されるメンバなど、より実践的でパワフルな機能について掘り下げていきます。これらの概念をマスターすることで、あなたの書くクラスはより安全で、直感的で、再利用性の高いものになるでしょう。 diff --git a/public/docs/cpp/7-classes-advanced/1-0-copy.md b/public/docs/cpp/7-classes-advanced/1-0-copy.md index 8cbe71cb..6a22e67f 100644 --- a/public/docs/cpp/7-classes-advanced/1-0-copy.md +++ b/public/docs/cpp/7-classes-advanced/1-0-copy.md @@ -12,11 +12,11 @@ question: ## オブジェクトのコピー: コピーコンストラクタと代入演算子 -オブジェクトをコピーしたい場面は頻繁にあります。例えば、関数の引数にオブジェクトを渡すとき(値渡し)や、既存のオブジェクトで新しいオブジェクトを初期化するときなどです。 +オブジェクトをコピーしたい場面は頻繁にあります。例えば、関数の引数にオブジェクトを渡すとき([[値渡し]])や、既存のオブジェクトで新しいオブジェクトを[[初期化]]するときなどです。 ```cpp Vector2D v1(1.0, 2.0); Vector2D v2 = v1; // ここでコピーが発生! ``` -多くの場合、コンパイラが自動的に生成するコピー機能で十分です。しかし、クラスがポインタなどでリソース(メモリなど)を管理している場合、単純なコピーでは問題が発生します。 +多くの場合、コンパイラが自動的に生成するコピー機能で十分です。しかし、クラスが[[ポインタ]]などでリソース(メモリなど)を管理している場合、単純なコピーでは問題が発生します。 diff --git a/public/docs/cpp/7-classes-advanced/1-1-shallow-copy.md b/public/docs/cpp/7-classes-advanced/1-1-shallow-copy.md index 677937d0..4a2fa767 100644 --- a/public/docs/cpp/7-classes-advanced/1-1-shallow-copy.md +++ b/public/docs/cpp/7-classes-advanced/1-1-shallow-copy.md @@ -18,7 +18,7 @@ question: まず、コピーの機能を自分で作らなかった場合に何が起きるか見てみましょう。 コンパイラは、メンバ変数を単純にコピーするだけの「浅いコピー」を行います。 -ここでは、`int`へのポインタを一つだけ持つ`ResourceHolder`(リソース保持者)というクラスを考えます。 +ここでは、`int`への[[ポインタ]]を一つだけ持つ`ResourceHolder`(リソース保持者)というクラスを考えます。 ```cpp:shallow_copy.cpp // 悪い例:浅いコピーの問題点 @@ -56,4 +56,4 @@ Resource 107521 destroyed. (at 0x1a4012b0) free(): double free detected in tcache 2 ``` -この例では、`r2`が作られるときに`r1`のポインタ`m_data`の値(メモリアドレス)だけがコピーされます。その結果、2つのオブジェクトが1つのメモリ領域を指してしまいます。プログラム終了時にそれぞれのデストラクタが呼ばれ、同じメモリを2回解放しようとしてエラーになります。 +この例では、`r2`が作られるときに`r1`の[[ポインタ]]`m_data`の値(メモリアドレス)だけがコピーされます。その結果、2つのオブジェクトが1つのメモリ領域を指してしまいます。プログラム終了時にそれぞれのデストラクタが呼ばれ、同じメモリを2回解放しようとしてエラーになります。 diff --git a/public/docs/cpp/7-classes-advanced/1-2-deep-copy.md b/public/docs/cpp/7-classes-advanced/1-2-deep-copy.md index 3b36f3b0..2300d02b 100644 --- a/public/docs/cpp/7-classes-advanced/1-2-deep-copy.md +++ b/public/docs/cpp/7-classes-advanced/1-2-deep-copy.md @@ -14,7 +14,7 @@ question: ### 解決策:コピー機能を自作する (深いコピー) -この問題を解決するために、**コピーコンストラクタ**と**コピー代入演算子**を自分で定義して、「深いコピー」を実装します。深いコピーとは、ポインタの指す先の実体(データそのもの)を新しく作ってコピーすることです。 +この問題を解決するために、**コピーコンストラクタ**と**コピー代入演算子**を自分で定義して、「深いコピー」を実装します。深いコピーとは、[[ポインタ]]の指す先の実体(データそのもの)を新しく作ってコピーすることです。 ```cpp:resource_holder.cpp #include @@ -122,11 +122,11 @@ Resource 10 destroyed. (at 0x139f065e0) *(メモリアドレスは実行するたびに変わります)* -実行結果を見ると、`rh1`, `rh2`, `rh3` はそれぞれ異なるメモリアドレス (`Address`) を持っていることがわかります。これにより、各オブジェクトは独立したリソースを管理でき、プログラム終了時にそれぞれのデストラクタが安全にメモリを解放できます。 +実行結果を見ると、`rh1`, `rh2`, `rh3` はそれぞれ異なるメモリ[[アドレス]] (`Address`) を持っていることがわかります。これにより、各オブジェクトは独立したリソースを管理でき、プログラム終了時にそれぞれのデストラクタが安全にメモリを解放できます。 | 機能 | いつ呼ばれるか | 何をするか | | :--- | :--- | :--- | -| **コピーコンストラクタ** | オブジェクトが**作られる時**に、他のオブジェクトで初期化される場合
`ResourceHolder r2 = r1;` | 新しいリソースを確保し、元のオブジェクトの**値**をコピーする。 | +| **コピーコンストラクタ** | オブジェクトが**作られる時**に、他のオブジェクトで[[初期化]]される場合
`ResourceHolder r2 = r1;` | 新しいリソースを確保し、元のオブジェクトの**値**をコピーする。 | | **コピー代入演算子** | **既にあるオブジェクト**に、他のオブジェクトを代入する場合
`r3 = r1;` | 1. 自分が持っている古いリソースを解放する。
2. 新しいリソースを確保し、元のオブジェクトの**値**をコピーする。 | -このように、ポインタでリソースを管理するクラスでは、安全なコピーを実現するためにこの2つの関数を自分で定義することが不可欠です。 +このように、[[ポインタ]]でリソースを管理するクラスでは、安全なコピーを実現するためにこの2つの関数を自分で定義することが不可欠です。 diff --git a/public/docs/cpp/7-classes-advanced/2-0-operator-overload.md b/public/docs/cpp/7-classes-advanced/2-0-operator-overload.md index 4e34be9d..8541c3ae 100644 --- a/public/docs/cpp/7-classes-advanced/2-0-operator-overload.md +++ b/public/docs/cpp/7-classes-advanced/2-0-operator-overload.md @@ -13,7 +13,7 @@ question: ## 演算子のオーバーロード -C++では、`+`, `-`, `==`, `<<` などの組み込み演算子を、自作のクラスで使えるように**再定義(オーバーロード)**できます。これにより、クラスのインスタンスをあたかも組み込み型(`int`や`double`など)のように直感的に扱えるようになります。 +C++では、`+`, `-`, `==`, `<<` などの組み込み演算子を、自作のクラスで使えるように**再定義([[オーバーロード]])**できます。これにより、クラスのインスタンスをあたかも組み込み型(`int`や`double`など)のように直感的に扱えるようになります。 例えば、2次元ベクトルを表す `Vector2D` クラスがあるとします。`v3 = v1 + v2;` のように、ベクトル同士の足し算を自然に記述できると便利ですよね。 diff --git a/public/docs/cpp/7-classes-advanced/3-0-static-member.md b/public/docs/cpp/7-classes-advanced/3-0-static-member.md index 014979b5..f06ae5d2 100644 --- a/public/docs/cpp/7-classes-advanced/3-0-static-member.md +++ b/public/docs/cpp/7-classes-advanced/3-0-static-member.md @@ -16,7 +16,7 @@ question: `static` キーワードを付けて宣言されたメンバ変数は、特定のオブジェクトに属さず、クラスそのものに属します。そのため、全オブジェクトでただ1つの実体を共有します。これを**クラス変数**と呼ぶこともあります。 * **宣言**: クラス定義の中で `static` を付けて行います。 - * **定義**: クラス定義の外(ソースファイル)で、メモリ上の実体を確保し、初期化します。 + * **定義**: クラス定義の外([[ソースファイル]])で、メモリ上の実体を確保し、初期化します。 `static` キーワードを付けて宣言されたメンバ関数は、特定のオブジェクトに依存せずに呼び出せます。そのため、`this` ポインタ(後述)を持ちません。 diff --git a/public/docs/cpp/7-classes-advanced/4-0-this.md b/public/docs/cpp/7-classes-advanced/4-0-this.md index fa707373..8cf0cd61 100644 --- a/public/docs/cpp/7-classes-advanced/4-0-this.md +++ b/public/docs/cpp/7-classes-advanced/4-0-this.md @@ -10,9 +10,9 @@ question: ## thisポインタ -非staticなメンバ関数が呼び出されるとき、その関数は「どのオブジェクトに対して呼び出されたか」を知る必要があります。コンパイラは、そのメンバ関数に対して、呼び出し元のオブジェクトのアドレスを暗黙的に渡します。このアドレスを保持するのが `this` ポインタです。 +非staticなメンバ関数が呼び出されるとき、その関数は「どのオブジェクトに対して呼び出されたか」を知る必要があります。コンパイラは、そのメンバ関数に対して、呼び出し元のオブジェクトの[[アドレス]]を暗黙的に渡します。このアドレスを保持するのが `this` ポインタです。 -`this` は、メンバ関数内で使用できるキーワードで、自分自身のオブジェクトを指すポインタです。 +`this` は、メンバ関数内で使用できるキーワードで、自分自身のオブジェクトを指す[[ポインタ]]です。 `this` ポインタが主に使われるのは、以下のような場面です。 @@ -25,7 +25,7 @@ question: } ``` -2. **自分自身の参照やポインタを返す場合** +2. **自分自身の参照や[[ポインタ]]を返す場合** コピー代入演算子で `return *this;` としたように、オブジェクト自身を返したい場合に使います。これにより、**メソッドチェーン**(`obj.setX(10).setY(20);` のような連続したメソッド呼び出し)が可能になります。 メソッドチェーンを実現する簡単な例を見てみましょう。 diff --git a/public/docs/cpp/7-classes-advanced/5-0-summary.md b/public/docs/cpp/7-classes-advanced/5-0-summary.md index 3b990f9a..4476a8dc 100644 --- a/public/docs/cpp/7-classes-advanced/5-0-summary.md +++ b/public/docs/cpp/7-classes-advanced/5-0-summary.md @@ -9,9 +9,9 @@ question: [] この章では、クラスをより効果的に利用するための応用的な機能を学びました。 - * **オブジェクトのコピー**: ポインタなどリソースを管理するクラスでは、**コピーコンストラクタ**と**コピー代入演算子**を定義し、**深いコピー**を実装することが重要です。これにより、リソースの二重解放などの問題を未然に防ぎます。 + * **オブジェクトのコピー**: [[ポインタ]]などリソースを管理するクラスでは、**コピーコンストラクタ**と**コピー代入演算子**を定義し、**深いコピー**を実装することが重要です。これにより、リソースの二重解放などの問題を未然に防ぎます。 * **演算子のオーバーロード**: `+` や `==` などの演算子を自作クラスに対して定義することで、コードの可読性を高め、直感的な操作を可能にします。 * **staticメンバ**: `static`メンバ変数やメンバ関数は、クラスの全オブジェクトで共有されるデータや機能を提供します。オブジェクトを生成しなくてもアクセスできるのが特徴です。 - * **thisポインタ**: 非staticメンバ関数内で、呼び出し元のオブジェクト自身を指すポインタです。メンバ変数と引数の区別や、メソッドチェーンの実装に役立ちます。 + * **thisポインタ**: 非staticメンバ関数内で、呼び出し元のオブジェクト自身を指す[[ポインタ]]です。メンバ変数と引数の区別や、メソッドチェーンの実装に役立ちます。 これらの機能を組み合わせることで、C++のクラスは単なるデータの入れ物から、振る舞いを伴った洗練された部品へと進化します。 diff --git a/public/docs/cpp/7-classes-advanced/5-1-practice1.md b/public/docs/cpp/7-classes-advanced/5-1-practice1.md index f518ab38..22e445ce 100644 --- a/public/docs/cpp/7-classes-advanced/5-1-practice1.md +++ b/public/docs/cpp/7-classes-advanced/5-1-practice1.md @@ -9,7 +9,7 @@ question: ### 練習問題1: 複素数クラス -実部 (real) と虚部 (imaginary) を`double`型で持つ複素数クラス `Complex` を作成してください。以下の要件を満たすものとします。 +実部 (real) と虚部 (imaginary) を[[`double`]]型で持つ複素数クラス `Complex` を作成してください。以下の要件を満たすものとします。 1. コンストラクタで実部と虚部を初期化できるようにする。 2. 複素数同士の足し算 (`+`) と掛け算 (`*`) を演算子オーバーロードで実装する。 diff --git a/public/docs/cpp/7-classes-advanced/5-2-practice2.md b/public/docs/cpp/7-classes-advanced/5-2-practice2.md index 0b30919f..76ce389e 100644 --- a/public/docs/cpp/7-classes-advanced/5-2-practice2.md +++ b/public/docs/cpp/7-classes-advanced/5-2-practice2.md @@ -10,7 +10,7 @@ question: ### 練習問題2: 動的配列クラスのコピー制御 -整数 (`int`) の動的配列を管理するクラス `IntArray` を作成してください。このクラスは、コンストラクタで指定されたサイズの配列を `new` で確保し、デストラクタで `delete[]` を使って解放します。 +整数 (`int`) の動的配列を管理するクラス `IntArray` を作成してください。このクラスは、コンストラクタで指定されたサイズの配列を [[`new`]] で確保し、デストラクタで `delete[]` を使って解放します。 この `IntArray` クラスに対して、**深いコピー**を正しく行うための**コピーコンストラクタ**と**コピー代入演算子**を実装してください。 diff --git a/public/docs/cpp/8-inheritance/2-0-polymorphism.md b/public/docs/cpp/8-inheritance/2-0-polymorphism.md index 852bda06..9290b4a8 100644 --- a/public/docs/cpp/8-inheritance/2-0-polymorphism.md +++ b/public/docs/cpp/8-inheritance/2-0-polymorphism.md @@ -15,7 +15,7 @@ question: これを実現するのが **仮想関数 (virtual function)** です。親クラスの関数宣言の前に `virtual` キーワードを付けると、その関数は仮想関数になります。 -親クラスのポインタや参照は、子クラスのオブジェクトを指すことができます。このとき、呼び出された仮想関数は、ポインタが指している**オブジェクトの実際の型**に基づいて決定されます。 +親クラスの[[ポインタ]]や参照は、子クラスのオブジェクトを指すことができます。このとき、呼び出された仮想関数は、[[ポインタ]]が指している**オブジェクトの実際の型**に基づいて決定されます。 言葉だけでは難しいので、コードで見てみましょう。 @@ -73,4 +73,4 @@ Woof! Meow! ``` -`make_animal_speak` 関数は `Animal*` 型の引数を取りますが、`Dog`オブジェクトや`Cat`オブジェクトのアドレスを渡すことができています。そして、`animal->speak()` を呼び出すと、`animal` ポインタが実際に指しているオブジェクトの `speak()` が実行されます。これがポリモーフィズムです。もし `Animal`クラスの `speak()` に `virtual` が付いていなければ、どのオブジェクトを渡しても `Animal` の `speak()` が呼ばれてしまいます。 +`make_animal_speak` 関数は `Animal*` 型の引数を取りますが、`Dog`オブジェクトや`Cat`オブジェクトの[[アドレス]]を渡すことができています。そして、`animal->speak()` を呼び出すと、`animal` ポインタが実際に指しているオブジェクトの `speak()` が実行されます。これがポリモーフィズムです。もし `Animal`クラスの `speak()` に `virtual` が付いていなければ、どのオブジェクトを渡しても `Animal` の `speak()` が呼ばれてしまいます。 diff --git a/public/docs/cpp/8-inheritance/5-0-summary.md b/public/docs/cpp/8-inheritance/5-0-summary.md index 32a747f1..bf66a941 100644 --- a/public/docs/cpp/8-inheritance/5-0-summary.md +++ b/public/docs/cpp/8-inheritance/5-0-summary.md @@ -9,6 +9,6 @@ question: [] * **継承**: 既存のクラスの機能を引き継ぎ、コードの再利用性を高める仕組みです。`(子クラス) : public (親クラス)` のように書きます。 * **ポリモーフィズム**: 「同じ指示でも、オブジェクトの種類によって異なる振る舞いをさせる」性質です。 - * **仮想関数 (`virtual`)**: ポリモーフィズムを実現するための鍵です。親クラスの関数に `virtual` を付けると、ポインタや参照経由で呼び出した際に、オブジェクトの実際の型に応じた関数が実行されます。 + * **仮想関数 (`virtual`)**: ポリモーフィズムを実現するための鍵です。親クラスの関数に `virtual` を付けると、[[ポインタ]]や参照経由で呼び出した際に、オブジェクトの実際の型に応じた関数が実行されます。 * **オーバーライド (`override`)**: 子クラスで親クラスの仮想関数を上書きする意図を明示します。コンパイラがチェックしてくれるため、安全性が向上します。 * **抽象クラス**: 1つ以上の**純粋仮想関数 (`virtual ... = 0;`)** を持つクラスです。インスタンス化できず、継承されるための設計図として機能します。 diff --git a/public/docs/cpp/8-inheritance/5-1-practice1.md b/public/docs/cpp/8-inheritance/5-1-practice1.md index de4b2741..4459a4d2 100644 --- a/public/docs/cpp/8-inheritance/5-1-practice1.md +++ b/public/docs/cpp/8-inheritance/5-1-practice1.md @@ -11,7 +11,7 @@ question: `Vehicle` という親クラスを作成し、`move()` というメンバ関数を持たせましょう。次に、`Vehicle` を継承して `Car` クラスと `Motorcycle` クラスを作成し、それぞれが独自の `move()` の振る舞いをするようにオーバーライドしてください。 -`main` 関数では、`Vehicle` のポインタの配列を作成し、`Car` と `Motorcycle` のオブジェクトを格納して、ループでそれぞれの `move()` を呼び出してください。 +[[`main` 関数]]では、`Vehicle` の[[ポインタ]]の配列を作成し、`Car` と `Motorcycle` のオブジェクトを格納して、ループでそれぞれの `move()` を呼び出してください。 ```cpp:practice9_1.cpp #include diff --git a/public/docs/cpp/8-inheritance/5-2-practice2.md b/public/docs/cpp/8-inheritance/5-2-practice2.md index 4728cf91..995c02f0 100644 --- a/public/docs/cpp/8-inheritance/5-2-practice2.md +++ b/public/docs/cpp/8-inheritance/5-2-practice2.md @@ -16,7 +16,7 @@ question: 次に、`Employee` を継承して、`FullTimeEmployee`(月給制)と `PartTimeEmployee`(時給制)の2つのクラスを作成します。それぞれのクラスで `calculate_salary()` を具体的に実装してください。 -`main` 関数で、それぞれのクラスのインスタンスを作成し、給与が正しく計算されることを確認してください。 +[[`main` 関数]]で、それぞれのクラスのインスタンスを作成し、給与が正しく計算されることを確認してください。 ```cpp:practice9_2.cpp #include diff --git a/public/docs/cpp/9-templates/1-1-function-template-detail.md b/public/docs/cpp/9-templates/1-1-function-template-detail.md index 9bef5a84..8042ffd0 100644 --- a/public/docs/cpp/9-templates/1-1-function-template-detail.md +++ b/public/docs/cpp/9-templates/1-1-function-template-detail.md @@ -17,7 +17,7 @@ question: * **`template <...>`**: テンプレートの宣言を開始します。 * **`typename T`**: `T`という名前の「型引数」を定義しています。`typename`の代わりに`class`と書くこともできますが、意味は同じです。`T`は、このテンプレートが実際に使われるときに具体的な型(`int`や`double`など)に置き換えられます。 -`main`関数で`max_value(10, 20)`のように呼び出すと、コンパイラは引数の型が`int`であることから、`T`を`int`だと自動的に判断します(これを**テンプレート引数推論**と呼びます)。そして、内部的に以下のような`int`版の関数を生成してくれるのです。 +[[`main`関数]]で`max_value(10, 20)`のように呼び出すと、コンパイラは引数の型が`int`であることから、`T`を`int`だと自動的に判断します(これを**テンプレート引数推論**と呼びます)。そして、内部的に以下のような`int`版の関数を生成してくれるのです。 ```cpp // コンパイラが内部的に生成するコードのイメージ diff --git a/public/docs/cpp/9-templates/2-1-class-template-detail.md b/public/docs/cpp/9-templates/2-1-class-template-detail.md index 5efc5307..2590ee35 100644 --- a/public/docs/cpp/9-templates/2-1-class-template-detail.md +++ b/public/docs/cpp/9-templates/2-1-class-template-detail.md @@ -35,6 +35,6 @@ question: }; ``` - `Pair`と`Pair`は、コンパイルされると全く別のクラスとして扱われることに注意してください。 + `Pair`と`Pair`は、[[コンパイル]]されると全く別のクラスとして扱われることに注意してください。 -クラステンプレートは、C++の強力なライブラリである**STL (Standard Template Library)**の根幹をなす技術です。次章で学ぶ`vector`や`map`といった便利なコンテナは、すべてクラステンプレートで実装されています。 +クラステンプレートは、C++の強力なライブラリである**STL (Standard Template Library)**の根幹をなす技術です。[[./next]]で学ぶ`vector`や`map`といった便利なコンテナは、すべてクラステンプレートで実装されています。 diff --git a/public/docs/cpp/9-templates/3-1-practice1.md b/public/docs/cpp/9-templates/3-1-practice1.md index a4d6e0fa..21179348 100644 --- a/public/docs/cpp/9-templates/3-1-practice1.md +++ b/public/docs/cpp/9-templates/3-1-practice1.md @@ -12,7 +12,7 @@ question: ### 練習問題1: 汎用的なprint関数 -任意の型の配列(ここでは`std::vector`を使いましょう)を受け取り、その要素をすべて画面に出力する関数テンプレート`print_elements`を作成してください。 +任意の型の配列(ここでは[[`std::vector`]]を使いましょう)を受け取り、その要素をすべて画面に出力する関数テンプレート`print_elements`を作成してください。 ```cpp:practice10_1.cpp #include diff --git a/public/docs/cpp/9-templates/3-2-practice2.md b/public/docs/cpp/9-templates/3-2-practice2.md index 5435ec91..bc524992 100644 --- a/public/docs/cpp/9-templates/3-2-practice2.md +++ b/public/docs/cpp/9-templates/3-2-practice2.md @@ -18,7 +18,7 @@ question: * `T pop()`: スタックの先頭から要素を取り出す * `bool is_empty()`: スタックが空かどうかを返す -`std::vector`を内部のデータ格納場所として利用して構いません。`int`型と`char`型で動作を確認してください。 +[[`std::vector`]]を内部のデータ格納場所として利用して構いません。`int`型と`char`型で動作を確認してください。 ```cpp:practice10_2.cpp #include diff --git a/public/docs/javascript/1-basics/3-0-object.md b/public/docs/javascript/1-basics/3-0-object.md index 9aad0f6c..085f07b6 100644 --- a/public/docs/javascript/1-basics/3-0-object.md +++ b/public/docs/javascript/1-basics/3-0-object.md @@ -14,8 +14,8 @@ question: 主なオブジェクト型には以下があります。 - * **Object**: キーと値のペアの集合(辞書、ハッシュマップに近い)。詳しくは5章で解説します。 - * **Array**: 順序付きリスト。詳しくは7章で解説します。 + * **Object**: キーと値のペアの集合(辞書、ハッシュマップに近い)。詳しくは[[./5]]で解説します。 + * **Array**: 順序付きリスト。詳しくは[[./7]]で解説します。 * **Function**: JavaScriptでは関数もオブジェクトであり、変数に代入したり引数として渡すことができます(第一級関数)。 ```js-repl diff --git a/public/docs/javascript/3-functions-closures/2-2-arrow-function-simple.md b/public/docs/javascript/3-functions-closures/2-2-arrow-function-simple.md index 1cbc6de9..e5448caa 100644 --- a/public/docs/javascript/3-functions-closures/2-2-arrow-function-simple.md +++ b/public/docs/javascript/3-functions-closures/2-2-arrow-function-simple.md @@ -24,4 +24,4 @@ question: { id: 1, name: 'Gemini' } ``` -> **注意:** アロー関数は単なる短縮記法ではありません。「`this` を持たない」という重要な特徴がありますが、これについては**第5章**で詳しく解説します。 +> **注意:** アロー関数は単なる短縮記法ではありません。「`this` を持たない」という重要な特徴がありますが、これについては[[./5]]で詳しく解説します。 diff --git a/public/docs/javascript/4-this/1-0-this-basic.md b/public/docs/javascript/4-this/1-0-this-basic.md index 3f6f41c3..4d8bdad1 100644 --- a/public/docs/javascript/4-this/1-0-this-basic.md +++ b/public/docs/javascript/4-this/1-0-this-basic.md @@ -21,7 +21,7 @@ JavaScriptにおける関数(アロー関数を除く)の `this` は、**「 * **メソッド呼び出し:** オブジェクトのプロパティとして関数を呼び出した場合(`obj.method()`)、`this` は**ドットの左側のオブジェクト**(レシーバ)になります。これは他の言語のメンバ関数に近い挙動です。 * **関数呼び出し:** 関数を単体で呼び出した場合(`func()`)、`this` は**グローバルオブジェクト**(ブラウザでは `window`、Node.jsでは `global`)になります。 ただし、**Strict Mode(`"use strict"`)**では、安全のため `undefined` になります。 -* **コンストラクタ呼び出し:** `new` キーワードをつけて呼び出した場合、`this` は**新しく生成されたインスタンス**になります(これは第6章、第7章で詳しく扱います)。 +* **コンストラクタ呼び出し:** `new` キーワードをつけて呼び出した場合、`this` は**新しく生成されたインスタンス**になります(これは[[./6]]で詳しく扱います)。 以下のコードで、同じ関数でも呼び出し方によって `this` が変わる様子を確認しましょう。 diff --git a/public/docs/javascript/4-this/4-0-summary.md b/public/docs/javascript/4-this/4-0-summary.md index 9d8cb724..080c9ef5 100644 --- a/public/docs/javascript/4-this/4-0-summary.md +++ b/public/docs/javascript/4-this/4-0-summary.md @@ -14,4 +14,4 @@ JavaScriptの `this` は、他の静的な言語とは異なり「呼び出し 3. **明示的な指定**: `call`, `apply` で一時的に、`bind` で永続的に `this` を指定可能。 4. **アロー関数**: 独自の `this` を持たず、外側のスコープの `this` をそのまま使う(レキシカルスコープ)。 -次の章では、この `this` を活用してオブジェクト指向プログラミングの核心である「オブジェクトとプロトタイプ」について学びます。 +[[./next]]では、この `this` を活用してオブジェクト指向プログラミングの核心である「オブジェクトとプロトタイプ」について学びます。 diff --git a/public/docs/javascript/5-objects-prototype/-intro.md b/public/docs/javascript/5-objects-prototype/-intro.md index 45b5818e..3381679a 100644 --- a/public/docs/javascript/5-objects-prototype/-intro.md +++ b/public/docs/javascript/5-objects-prototype/-intro.md @@ -1,3 +1,3 @@ 他の言語(Java, C\#, Pythonなど)の経験がある方にとって、JavaScriptの「オブジェクト」と「継承」のモデルは最も混乱しやすい部分の一つです。JavaScriptはクラスベースではなく、**プロトタイプベース**のオブジェクト指向言語です。 -本章では、ES6(ECMAScript 2015)以降の`class`構文(第7章で扱います)の裏側で実際に何が起きているのか、その仕組みの根幹である「プロトタイプチェーン」について解説します。 +本章では、ES6(ECMAScript 2015)以降の`class`構文([[./6]]で扱います)の裏側で実際に何が起きているのか、その仕組みの根幹である「プロトタイプチェーン」について解説します。 diff --git a/public/docs/javascript/5-objects-prototype/2-0-method-this-recall.md b/public/docs/javascript/5-objects-prototype/2-0-method-this-recall.md index a739857e..c45e780b 100644 --- a/public/docs/javascript/5-objects-prototype/2-0-method-this-recall.md +++ b/public/docs/javascript/5-objects-prototype/2-0-method-this-recall.md @@ -10,7 +10,7 @@ question: ## メソッドと this(復習) オブジェクトのプロパティには関数も設定できます。これを**メソッド**と呼びます。 -第5章で学んだ通り、メソッド呼び出しにおける `this` は、「ドットの左側にあるオブジェクト(レシーバ)」を指します。 +[[./4]]で学んだ通り、メソッド呼び出しにおける `this` は、「ドットの左側にあるオブジェクト(レシーバ)」を指します。 ```js-repl > const counter = { diff --git a/public/docs/javascript/6-classes/-intro.md b/public/docs/javascript/6-classes/-intro.md index ef0c6482..172b8273 100644 --- a/public/docs/javascript/6-classes/-intro.md +++ b/public/docs/javascript/6-classes/-intro.md @@ -1,4 +1,4 @@ -前章では、JavaScriptのオブジェクト指向の核心である「プロトタイプ」について学びました。他の言語(Java, C\#, Pythonなど)の経験者にとって、プロトタイプチェーンによる継承は柔軟ですが、少し直感的ではない部分もあったかもしれません。 +[[./5]]では、JavaScriptのオブジェクト指向の核心である「プロトタイプ」について学びました。他の言語(Java, C\#, Pythonなど)の経験者にとって、プロトタイプチェーンによる継承は柔軟ですが、少し直感的ではない部分もあったかもしれません。 ES6 (ECMAScript 2015) から導入された **`class` 構文** は、プロトタイプベースの継承メカニズムを隠蔽し、一般的なクラスベースのオブジェクト指向言語に近い記述を可能にするものです。これを「糖衣構文(Syntactic Sugar)」と呼びます。 diff --git a/public/docs/javascript/8-promise/6-0-summary.md b/public/docs/javascript/8-promise/6-0-summary.md index 11de79fe..4343f3dd 100644 --- a/public/docs/javascript/8-promise/6-0-summary.md +++ b/public/docs/javascript/8-promise/6-0-summary.md @@ -13,4 +13,4 @@ question: [] * `.then()` をチェーンさせることで、非同期処理を直列に、読みやすく記述できます。 * エラーハンドリングは `.catch()` で一括して行えます。 -次章では、このPromiseをさらに同期処理のように書ける構文糖衣 **async/await** について学びます。 +[[./next]]では、このPromiseをさらに同期処理のように書ける構文糖衣 **async/await** について学びます。 diff --git a/public/docs/javascript/9-async-await/-intro.md b/public/docs/javascript/9-async-await/-intro.md index d2086d91..c6c78c61 100644 --- a/public/docs/javascript/9-async-await/-intro.md +++ b/public/docs/javascript/9-async-await/-intro.md @@ -1,3 +1,3 @@ -前回(第9章)では、JavaScriptの非同期処理の要である `Promise` について学びました。しかし、`.then()` チェーンが長く続くと、コードの可読性が下がる(いわゆる「コールバック地獄」に近い状態になる)ことがあります。 +[[./8]]では、JavaScriptの非同期処理の要である `Promise` について学びました。しかし、`.then()` チェーンが長く続くと、コードの可読性が下がる(いわゆる「コールバック地獄」に近い状態になる)ことがあります。 -第10章では、この課題を解決するために導入された **Async/Await** 構文と、現代的なHTTP通信の標準である **Fetch API** について解説します。他の言語で同期的なコード(ブロッキング処理)に慣れ親しんだ方にとって、Async/Await は非常に直感的で扱いやすい機能です。 +この章では、この課題を解決するために導入された **Async/Await** 構文と、現代的なHTTP通信の標準である **Fetch API** について解説します。他の言語で同期的なコード(ブロッキング処理)に慣れ親しんだ方にとって、Async/Await は非常に直感的で扱いやすい機能です。 diff --git a/public/docs/ruby/0-intro/5-2-run.md b/public/docs/ruby/0-intro/5-2-run.md index e53cbf77..2362c1ff 100644 --- a/public/docs/ruby/0-intro/5-2-run.md +++ b/public/docs/ruby/0-intro/5-2-run.md @@ -26,4 +26,4 @@ Hello from script file! ``` おめでとうございます! これでRubyの世界への第一歩を踏み出しました。 -次の章では、Rubyの基本的な構文、データ型、そして他の言語にはない特徴的な「シンボル」について詳しく学んでいきます。 +[[./next]]では、Rubyの基本的な構文、データ型、そして他の言語にはない特徴的な「シンボル」について詳しく学んでいきます。 diff --git a/public/docs/ruby/1-basics/1-0-variable.md b/public/docs/ruby/1-basics/1-0-variable.md index 3512c017..7ff9715c 100644 --- a/public/docs/ruby/1-basics/1-0-variable.md +++ b/public/docs/ruby/1-basics/1-0-variable.md @@ -15,9 +15,9 @@ Rubyの変数は型宣言を必要としませんが、変数の「スコープ * **ローカル変数**: `my_var` * 小文字または `_` で始まります。定義されたスコープ(メソッド定義、ブロック、ファイルのトップレベルなど)でのみ有効です。 * **インスタンス変数**: `@my_var` - * `@` で始まります。特定のオブジェクトのインスタンスに属し、そのオブジェクトのメソッド内からアクセスできます。(クラスの章で詳述します) + * `@` で始まります。特定のオブジェクトのインスタンスに属し、そのオブジェクトのメソッド内からアクセスできます。([[./6]]で詳述します) * **クラス変数**: `@@my_var` - * `@@` で始まります。クラス全体とそのサブクラスで共有されます。(クラスの章で詳述します) + * `@@` で始まります。クラス全体とそのサブクラスで共有されます。([[./6]]で詳述します) * **グローバル変数**: `$my_var` * `$` で始まります。プログラムのどこからでもアクセス可能ですが、グローバルな状態を持つため、使用は最小限に抑えるべきです。 * **定数**: `MY_CONSTANT` diff --git a/public/docs/ruby/2-control-methods/2-0-loop.md b/public/docs/ruby/2-control-methods/2-0-loop.md index a722582e..18d4e45a 100644 --- a/public/docs/ruby/2-control-methods/2-0-loop.md +++ b/public/docs/ruby/2-control-methods/2-0-loop.md @@ -9,4 +9,4 @@ question: ## 繰り返し処理 -Rubyでは、後の章で学ぶイテレータ(`each`など)が繰り返し処理の主流ですが、C言語スタイルの `while` や `until` も利用可能です。 +Rubyでは、[[./5]]で学ぶイテレータ(`each`など)が繰り返し処理の主流ですが、C言語スタイルの `while` や `until` も利用可能です。 diff --git a/public/docs/ruby/5-blocks-iterators/3-0-enumerable.md b/public/docs/ruby/5-blocks-iterators/3-0-enumerable.md index 53592380..95ab40e0 100644 --- a/public/docs/ruby/5-blocks-iterators/3-0-enumerable.md +++ b/public/docs/ruby/5-blocks-iterators/3-0-enumerable.md @@ -33,7 +33,7 @@ irb(main):016:0> numbers.select { |n| n.odd? } # select が使える => [1, 3] ``` -これは、自分で新しいコレクションクラスを作った場合でも同様です。(`include` については後の「モジュールとMix-in」の章で詳しく学びます) +これは、自分で新しいコレクションクラスを作った場合でも同様です。(`include` については[[./7]]で詳しく学びます) ```ruby:my_collection.rb # Enumerableモジュールを include する diff --git a/public/docs/ruby/6-classes/-intro.md b/public/docs/ruby/6-classes/-intro.md index 482aab4d..622eb1b3 100644 --- a/public/docs/ruby/6-classes/-intro.md +++ b/public/docs/ruby/6-classes/-intro.md @@ -1,3 +1,3 @@ -Rubyは純粋なオブジェクト指向言語であり、第4章「すべてがオブジェクト」で学んだように、数値や文字列さえもオブジェクトです。この章では、それらのオブジェクトの「設計図」である**クラス**を定義する方法について学びます。 +Rubyは純粋なオブジェクト指向言語であり、[[./3]]で学んだように、数値や文字列さえもオブジェクトです。この章では、それらのオブジェクトの「設計図」である**クラス**を定義する方法について学びます。 他のオブジェクト指向言語(Java, Python, C\#など)の経験があれば、概念は馴染み深いはずです。Ruby特有の構文(`@`や`attr_*`など)に注目してください。 diff --git a/public/docs/ruby/7-modules/6-1-practice1.md b/public/docs/ruby/7-modules/6-1-practice1.md index a4677265..b020a831 100644 --- a/public/docs/ruby/7-modules/6-1-practice1.md +++ b/public/docs/ruby/7-modules/6-1-practice1.md @@ -11,7 +11,7 @@ question: ### 練習問題1: カウンター機能のミックスイン -`Enumerable` モジュール(第6章で少し触れました)のように、`include` したクラスに便利な機能を追加するモジュールを作成します。 +`Enumerable` モジュール([[./5]]で少し触れました)のように、`include` したクラスに便利な機能を追加するモジュールを作成します。 1. `Counter` というモジュールを定義してください。 2. `Counter` モジュールは `count_items(item_to_find)` というメソッドを持つものとします。 diff --git a/public/docs/ruby/8-proc-lambda/-intro.md b/public/docs/ruby/8-proc-lambda/-intro.md index c99e3608..87a00996 100644 --- a/public/docs/ruby/8-proc-lambda/-intro.md +++ b/public/docs/ruby/8-proc-lambda/-intro.md @@ -1,3 +1,3 @@ -これまでの章で、Rubyの強力な機能である「ブロック」を `each` や `map` などのメソッドと共に使ってきました。しかし、ブロックは常にメソッド呼び出しに付随する形でしか使えませんでした。 +[[./5]]で、Rubyの強力な機能である「ブロック」を `each` や `map` などのメソッドと共に使ってきました。しかし、ブロックは常にメソッド呼び出しに付随する形でしか使えませんでした。 この章では、そのブロックを「オブジェクト」として扱い、変数に代入したり、メソッドの引数として自由に受け渡したりする方法を学びます。これにより、Rubyの表現力はさらに向上します。 diff --git a/public/docs/rust/1-basics/-intro.md b/public/docs/rust/1-basics/-intro.md index cd2dbba3..166240d5 100644 --- a/public/docs/rust/1-basics/-intro.md +++ b/public/docs/rust/1-basics/-intro.md @@ -2,4 +2,4 @@ C++やJava、Pythonなどでは「変数はデフォルトで書き換え可能(Mutable)」であることが一般的ですが、Rustでは**「デフォルトで不変(Immutable)」**です。この設計こそが、Rustがコンパイル時に多くのバグを排除できる理由の根幹にあります。 -第2章では、Rustの構文の基礎と、その背後にある哲学を学びます。 +この章では、Rustの構文の基礎と、その背後にある哲学を学びます。 diff --git a/public/docs/rust/1-basics/3-2-compound.md b/public/docs/rust/1-basics/3-2-compound.md index b15ced81..a0668c7d 100644 --- a/public/docs/rust/1-basics/3-2-compound.md +++ b/public/docs/rust/1-basics/3-2-compound.md @@ -15,7 +15,7 @@ question: * 異なる型をまとめる固定長のリストです。 2. **配列 (Array)**: * **同じ型**の要素をまとめる**固定長**のリストです。 - * ※ 長さが可変のリストが必要な場合は、後の章で学ぶ「ベクタ (`Vec`)」を使います。配列はスタック上に確保されるため、高速ですがサイズ変更はできません。 + * ※ 長さが可変のリストが必要な場合は、[[./8]]で学ぶ「ベクタ (`Vec`)」を使います。配列はスタック上に確保されるため、高速ですがサイズ変更はできません。 diff --git a/public/docs/rust/10-generics-traits/-intro.md b/public/docs/rust/10-generics-traits/-intro.md index 4fc4aabf..877da386 100644 --- a/public/docs/rust/10-generics-traits/-intro.md +++ b/public/docs/rust/10-generics-traits/-intro.md @@ -1,4 +1,3 @@ -Rustチュートリアルの第11章へようこそ。 この章では、Rustにおける抽象化とコード再利用の核心である「ジェネリクス」と「トレイト」について解説します。 他のプログラミング言語での経験がある方にとって、ジェネリクスは馴染み深い概念かもしれませんが、トレイトはクラス継承とは異なるアプローチをとります。これらを理解することで、柔軟かつ高速なRustコードが書けるようになります。 diff --git a/public/docs/rust/11-lifetimes/-intro.md b/public/docs/rust/11-lifetimes/-intro.md index 5c494b46..819127b7 100644 --- a/public/docs/rust/11-lifetimes/-intro.md +++ b/public/docs/rust/11-lifetimes/-intro.md @@ -1,5 +1,5 @@ ようこそ、Rustの学習における「最難関」とも呼ばれる章へ。 -これまで所有権や借用(第4章、第5章)を学んできましたが、**ライフタイム(Lifetimes)** はそれらを支えるコンパイラのロジックそのものです。 +これまで所有権や借用([[./3]]、[[./4]])を学んできましたが、**ライフタイム(Lifetimes)** はそれらを支えるコンパイラのロジックそのものです。 他の言語(C/C++)では、メモリが解放された後にその場所を指し続ける「ダングリングポインタ」がバグの温床でした。JavaやPythonのようなガベージコレクション(GC)を持つ言語では、これを自動で管理しますが、パフォーマンスのコストがかかります。 diff --git a/public/docs/rust/11-lifetimes/3-0-elision.md b/public/docs/rust/11-lifetimes/3-0-elision.md index 132b66b0..18649eeb 100644 --- a/public/docs/rust/11-lifetimes/3-0-elision.md +++ b/public/docs/rust/11-lifetimes/3-0-elision.md @@ -10,7 +10,7 @@ question: ## ライフタイム省略ルール -「待ってください。第4章で書いた `fn first_word(s: &str) -> &str` は注釈なしで動きましたよ?」 +「待ってください。[[./3]]で書いた `fn first_word(s: &str) -> &str` は注釈なしで動きましたよ?」 鋭い質問です。初期のRustではすべての参照に明示的なライフタイムが必要でした。しかし、あまりにも頻出するパターン(例えば「引数が1つなら、戻り値のライフタイムもそれと同じ」など)があったため、Rustチームはそれらを自動推論する**「ライフタイム省略ルール(Lifetime Elision Rules)」**をコンパイラに組み込みました。 diff --git a/public/docs/rust/3-ownership/5-0-summary.md b/public/docs/rust/3-ownership/5-0-summary.md index 2d959222..1a81a5e4 100644 --- a/public/docs/rust/3-ownership/5-0-summary.md +++ b/public/docs/rust/3-ownership/5-0-summary.md @@ -17,4 +17,4 @@ question: [] しかし、「関数に値を渡すたびに所有権がなくなってしまい、使えなくなる」のは不便だと感じたでしょう。値を一時的に関数に使わせたいだけなのに、いちいち所有権を返してもらうのは面倒です。 -次章の**「借用(Borrowing)」**では、所有権を渡さずに値を参照する方法を学びます。 +[[./next]]の**「借用(Borrowing)」**では、所有権を渡さずに値を参照する方法を学びます。 diff --git a/public/docs/rust/4-borrowing-slices/-intro.md b/public/docs/rust/4-borrowing-slices/-intro.md index 85a2f9d3..b0ff0471 100644 --- a/public/docs/rust/4-borrowing-slices/-intro.md +++ b/public/docs/rust/4-borrowing-slices/-intro.md @@ -1,3 +1,3 @@ -前章では「所有権(Ownership)」というRust独自のメモリ管理システムについて学びました。「所有権は一度に1つの変数しか持てない」というルールは強力ですが、関数に値を渡すたびに所有権が移動(ムーブ)してしまうと、毎回値を返り値として受け取らなければならず不便です。 +[[./3]]では「所有権(Ownership)」というRust独自のメモリ管理システムについて学びました。「所有権は一度に1つの変数しか持てない」というルールは強力ですが、関数に値を渡すたびに所有権が移動(ムーブ)してしまうと、毎回値を返り値として受け取らなければならず不便です。 そこで登場するのが**「参照(Reference)」**と**「借用(Borrowing)」**です。これを使うことで、所有権を渡さずに値にアクセスすることが可能になります。 diff --git a/public/docs/rust/5-structs-methods/2-2-unit-structs.md b/public/docs/rust/5-structs-methods/2-2-unit-structs.md index 9f75114a..468da045 100644 --- a/public/docs/rust/5-structs-methods/2-2-unit-structs.md +++ b/public/docs/rust/5-structs-methods/2-2-unit-structs.md @@ -9,4 +9,4 @@ question: ### ユニット様構造体 (Unit-like Structs) -フィールドを全く持たない構造体です。`struct AlwaysEqual;` のように定義します。これらは、データを持たずに振る舞い(トレイト)だけを実装したい場合に役立ちますが、詳細は後の章で扱います。 +フィールドを全く持たない構造体です。`struct AlwaysEqual;` のように定義します。これらは、データを持たずに振る舞い(トレイト)だけを実装したい場合に役立ちますが、詳細は[[./10]]で扱います。 diff --git a/public/docs/rust/5-structs-methods/3-0-ownership-structs.md b/public/docs/rust/5-structs-methods/3-0-ownership-structs.md index fd322885..6e076daa 100644 --- a/public/docs/rust/5-structs-methods/3-0-ownership-structs.md +++ b/public/docs/rust/5-structs-methods/3-0-ownership-structs.md @@ -13,7 +13,7 @@ question: 構造体における所有権の扱いは非常に重要です。 1. **所有するデータ**: `String`や`Vec`のような所有権を持つ型をフィールドにすると、その構造体のインスタンスがデータの所有者になります。構造体がドロップされると、フィールドのデータもドロップされます。 -2. **参照**: 構造体に「参照(\&strなど)」を持たせることも可能ですが、これには**ライフタイム(第12章)の指定が必要になります。そのため、現段階では構造体には(参照ではなく)`String`などの所有権のある型**を使うことを推奨します。 +2. **参照**: 構造体に「参照(\&strなど)」を持たせることも可能ですが、これには**ライフタイム([[./11]])の指定が必要になります。そのため、現段階では構造体には(参照ではなく)`String`などの所有権のある型**を使うことを推奨します。 diff --git a/public/docs/rust/5-structs-methods/5-0-summary.md b/public/docs/rust/5-structs-methods/5-0-summary.md index fed1027f..158ece22 100644 --- a/public/docs/rust/5-structs-methods/5-0-summary.md +++ b/public/docs/rust/5-structs-methods/5-0-summary.md @@ -13,4 +13,4 @@ question: [] * **関連関数** は `self` を取らず、`型名::関数名` で呼び出します(コンストラクタ `new` など)。 * Rustには継承がないため、データ構造とメソッドの組み合わせのみでオブジェクト指向的な設計を行います。 -次章では、Rustの強力な機能の一つである「列挙型(Enum)」と、フロー制御の要である「パターンマッチ」について学びます。 +[[./next]]では、Rustの強力な機能の一つである「列挙型(Enum)」と、フロー制御の要である「パターンマッチ」について学びます。 diff --git a/public/docs/rust/6-enums-pattern/-intro.md b/public/docs/rust/6-enums-pattern/-intro.md index a972d127..27c129d6 100644 --- a/public/docs/rust/6-enums-pattern/-intro.md +++ b/public/docs/rust/6-enums-pattern/-intro.md @@ -1,4 +1,3 @@ -Rustチュートリアル第7章へようこそ。 -これまでの章では、構造体を使って関連するデータをまとめる方法を学びました。この章では、**列挙型(Enum)と、それに関連する強力な制御フロー構造であるパターンマッチ**について学びます。 +[[./5]]では、構造体を使って関連するデータをまとめる方法を学びました。この章では、**列挙型(Enum)と、それに関連する強力な制御フロー構造であるパターンマッチ**について学びます。 他の言語(C、C++、Javaなど)でのEnumは、単に「名前付き定数のリスト」であることが多いですが、RustのEnumは「代数的データ型(Algebraic Data Types)」に近い性質を持っており、はるかに強力です。 diff --git a/public/docs/rust/7-modules/6-0-summary.md b/public/docs/rust/7-modules/6-0-summary.md index a876129e..241ad797 100644 --- a/public/docs/rust/7-modules/6-0-summary.md +++ b/public/docs/rust/7-modules/6-0-summary.md @@ -1,11 +1,11 @@ --- id: rust-modules-summary -title: 第8章のまとめ +title: この章のまとめ level: 2 question: [] --- -## 第8章のまとめ +## この章のまとめ * **パッケージとクレート:** `cargo new` で作るのがパッケージ、生成されるバイナリやライブラリがクレートです。 * **モジュール:** コードを整理する箱です。`mod` で定義します。 diff --git a/public/docs/rust/9-error-handling/-intro.md b/public/docs/rust/9-error-handling/-intro.md index 2b44120c..b505604b 100644 --- a/public/docs/rust/9-error-handling/-intro.md +++ b/public/docs/rust/9-error-handling/-intro.md @@ -1,4 +1,4 @@ -ようこそ、第10章へ。ここまでRustの所有権や型システムについて学んできましたが、この章では実用的なアプリケーション開発において避けては通れない「エラーハンドリング」について解説します。 +ここまでRustの所有権や型システムについて学んできましたが、この章では実用的なアプリケーション開発において避けては通れない「エラーハンドリング」について解説します。 他の多くの言語(Java, Python, C++など)とRustが最も大きく異なる点の一つが、**「例外(Exception)」が存在しない**ことです。 diff --git a/public/docs/rust/9-error-handling/3-0-result.md b/public/docs/rust/9-error-handling/3-0-result.md index 0da1604b..2d0aab0b 100644 --- a/public/docs/rust/9-error-handling/3-0-result.md +++ b/public/docs/rust/9-error-handling/3-0-result.md @@ -10,7 +10,7 @@ question: ## 回復可能なエラー (`Result`) -Rustのエラーハンドリングの主役は `Result` 列挙型です。以前の章で学んだ `Option` に似ていますが、失敗した場合に「なぜ失敗したか(エラー内容)」を持つ点が異なります。 +Rustのエラーハンドリングの主役は `Result` 列挙型です。[[./6]]で学んだ `Option` に似ていますが、失敗した場合に「なぜ失敗したか(エラー内容)」を持つ点が異なります。 定義は以下のようになっています(標準ライブラリに含まれています)。 diff --git a/public/docs/typescript/1-types/-intro.md b/public/docs/typescript/1-types/-intro.md index b7c87041..52d5812e 100644 --- a/public/docs/typescript/1-types/-intro.md +++ b/public/docs/typescript/1-types/-intro.md @@ -1,5 +1,5 @@ JavaScriptでの開発経験がある皆様、TypeScriptの世界へようこそ。 -第1章では環境構築を行いましたが、本章からいよいよ具体的なコードを書いていきます。 +[[./0]]では環境構築を行いましたが、本章からいよいよ具体的なコードを書いていきます。 TypeScriptの最大の武器は**「型(Type)」**です。しかし、すべてのコードに手動で型を書く必要はありません。TypeScriptは非常に賢い「型推論」という機能を持っており、JavaScriptを書く感覚のまま、安全性を享受できる場面も多々あります。 diff --git a/public/docs/typescript/2-objects-interfaces/4-0-type-vs-interface.md b/public/docs/typescript/2-objects-interfaces/4-0-type-vs-interface.md index 84e59ec6..3a3153b4 100644 --- a/public/docs/typescript/2-objects-interfaces/4-0-type-vs-interface.md +++ b/public/docs/typescript/2-objects-interfaces/4-0-type-vs-interface.md @@ -16,7 +16,7 @@ question: | 特徴 | type (型エイリアス) | interface (インターフェース) | | :--- | :--- | :--- | -| **主な用途** | プリミティブ、ユニオン型(第5章で解説)、タプル、関数の型など、**あらゆる型**に名前を付ける。 | **オブジェクトの構造**やクラスの実装ルールを定義する。 | +| **主な用途** | プリミティブ、ユニオン型([[./4]]で解説)、タプル、関数の型など、**あらゆる型**に名前を付ける。 | **オブジェクトの構造**やクラスの実装ルールを定義する。 | | **拡張性** | 交差型 (`&`) を使って拡張する。 | `extends` キーワードで継承できる。また、同名のinterfaceを定義すると自動でマージされる(Declaration Merging)。 | | **推奨シーン** | アプリケーション開発全般、複雑な型の組み合わせ。 | ライブラリ開発(拡張性を残すため)、オブジェクト指向的な設計。 | diff --git a/public/docs/typescript/3-function-types/6-0-type-alias.md b/public/docs/typescript/3-function-types/6-0-type-alias.md index ec3182a6..ce10b753 100644 --- a/public/docs/typescript/3-function-types/6-0-type-alias.md +++ b/public/docs/typescript/3-function-types/6-0-type-alias.md @@ -11,7 +11,7 @@ question: ## 関数の型エイリアス コールバック関数を引数に取る場合など、関数の型定義が長くなりがちです。 -第3章で学んだ `type`(型エイリアス)を使って、関数のシグネチャそのものに名前を付けることができます。 +[[./2]]で学んだ `type`(型エイリアス)を使って、関数のシグネチャそのものに名前を付けることができます。 構文: `type 型名 = (引数: 型) => 戻り値の型;` diff --git a/public/docs/typescript/4-combining-types/5-3-instanceof.md b/public/docs/typescript/4-combining-types/5-3-instanceof.md index ffa4c37d..9ed17463 100644 --- a/public/docs/typescript/4-combining-types/5-3-instanceof.md +++ b/public/docs/typescript/4-combining-types/5-3-instanceof.md @@ -8,7 +8,7 @@ question: ### `instanceof` 演算子 -クラスのインスタンスかどうかを判定します(第7章のクラスで詳しく扱いますが、Dateなどの組み込みオブジェクトでも有効です)。 +クラスのインスタンスかどうかを判定します([[./6]]のクラスで詳しく扱いますが、Dateなどの組み込みオブジェクトでも有効です)。 ```ts:type-guard-instanceof.ts function logDate(value: string | Date) { diff --git a/public/docs/typescript/5-generics/-intro.md b/public/docs/typescript/5-generics/-intro.md index 409eb298..b450867a 100644 --- a/public/docs/typescript/5-generics/-intro.md +++ b/public/docs/typescript/5-generics/-intro.md @@ -1 +1 @@ -第6章では、TypeScriptを使いこなす上で非常に強力な機能である**ジェネリクス (Generics)** について学びます。JavaやC\#などの言語経験がある方には馴染み深い概念かもしれませんが、JavaScriptの世界から来た方にとっては少し抽象的に感じるかもしれません。しかし、これを理解することで、**「柔軟性」と「安全性」を両立したコード**が書けるようになります。 +この章では、TypeScriptを使いこなす上で非常に強力な機能である**ジェネリクス (Generics)** について学びます。JavaやC\#などの言語経験がある方には馴染み深い概念かもしれませんが、JavaScriptの世界から来た方にとっては少し抽象的に感じるかもしれません。しかし、これを理解することで、**「柔軟性」と「安全性」を両立したコード**が書けるようになります。 diff --git a/public/docs/typescript/6-classes/5-0-implements.md b/public/docs/typescript/6-classes/5-0-implements.md index 6349a6bb..a4e5c949 100644 --- a/public/docs/typescript/6-classes/5-0-implements.md +++ b/public/docs/typescript/6-classes/5-0-implements.md @@ -12,7 +12,7 @@ question: ## `implements`: インターフェースによるクラスの形状の強制 -第3章で学んだインターフェースは、オブジェクトの型定義だけでなく、**クラスが特定の実装を持っていることを保証する(契約を結ぶ)**ためにも使われます。これを `implements` と呼びます。 +[[./2]]で学んだインターフェースは、オブジェクトの型定義だけでなく、**クラスが特定の実装を持っていることを保証する(契約を結ぶ)**ためにも使われます。これを `implements` と呼びます。 ```ts:implements-interface.ts interface Printable {