目次
導入
このシリーズは、初心者向けに包括的でわかりやすいC++ 入門ガイドを提供することを目的としています。C++ キーワードから始めて、名前空間、入出力、関数機能、キーワード、範囲ベースの for ループ、などのC++11の新機能など、C++ のさまざまな側面を徐々に調べていきます。各トピックには、この知識をより深く理解し、適用するのに役立つ簡潔な説明とサンプル コードが含まれています。
auto
nullptr
プログラミングを始めたばかりの場合でも、別のプログラミング言語から C++ に切り替えたい場合でも、このガイドは C++ の強固な基盤を構築するのに役立ちます。このシリーズを学習することで、C++ の中核概念と共通機能を習得し、その後の学習とプロジェクト開発のための強固な基盤を築きます。
1. C++ キーワード
1.1 コンセプト
C++ には合計63 個のキーワードがあり、C 言語には32 個のキーワードがあります。
C++ キーワードは、C++ 言語で定義された特別な意味を持つ予約語のセットです。これらのキーワードは C++ プログラミングにおいて特別な目的を持っており、識別子や変数名として使用することはできません。
ここではキーワードのみを記載しており、以下の記事で詳しく紹介しています。
1.2 キーワードリスト
キーワード | キーワード | キーワード | キーワード |
---|---|---|---|
整列 | 整列 | そして | and_eq |
アズム | 自動 | ビットアンド | 到来 |
ブール | 壊す | 場合 | キャッチ |
文字 | char8_t | char16_t | char32_t |
クラス | 完了する | コンセプト | 定数 |
コンステバル | constexpr | それは止まります | const_cast |
続く | co_await | co_return | 共同収量 |
デクタイプ | デフォルト | 消去 | する |
ダブル | ダイナミックキャスト | それ以外 | 列挙型 |
明示的な | 輸出 | 外部 | 間違い |
浮く | のために | 友人 | 後藤 |
もし | 列をなして | 整数 | 長さ |
可変 | 名前空間 | 新しい | 例外はありません |
ない | not_eq | nullptr | オペレーター |
または | or_eq | プライベート | 保護された |
公共 | 登録する | 再解釈_キャスト | 必要 |
戻る | 短い | 署名済み | のサイズ |
静的 | static_assert | static_cast | 構造体 |
スイッチ | 同期した | テンプレート | これ |
スレッドローカル | 投げる | 真実 | 試す |
typedef | タイプID | タイプ名 | 連合 |
署名されていない | を使用して | バーチャル | 空所 |
揮発性の | wchar_t | その間 | クソ |
xor_eq |
注:この表には、C++11、C++14、C++17、C++20 以降のバージョンで導入されたキーワードを含む、C++ のすべてのキーワードがリストされています。バージョンが異なればサポートされるキーワードも異なる場合があり、具体的な使用法については対応する C++ 標準ドキュメントを参照する必要があります。
2. 名前空間
2.1 質問例
名前空間について学ぶ前に、C 言語の問題を見てみましょう。
ここで定義された変数 rand は、ライブラリ内の関数 randの名前と競合しますが、C 言語の機能ではこの問題を解決できません。
#include <stdio.h>
#include <stdlib.h>
int rand = 10;
// C语言没办法解决类似这样的命名冲突问题,所以C++提出了namespace来解决
int main()
{
printf("%d\n", rand);
return 0;
}
// 编译后后报错:error C2365: “rand”: 重定义;以前的定义是自带的rand“函数”
// 就与你在一个工程代码中无法定义两个同名的标识符是一个原理
2.2 原因
名前空間は、大規模なプログラムにおける名前の競合の問題を解決するために作成されました。
大規模なソフトウェア開発では、複数の開発者が同時にコードを作成し、全員が同じ変数名、関数名、またはクラス名を使用する可能性があり、変数、関数、クラス名のほとんどがグローバル ロールに存在します。ドメインでは、コードをマージすると名前の競合が発生し、コードにバグや予測不可能な動作が発生する可能性があります。
次に、上記の問題例も理由の 1 つですが、C++ に名前空間がない場合、同じ問題が発生します。!!
名前空間を使用する目的は、名前の競合や名前汚染を回避するために識別子の名前をローカライズすることであり、このようにして名前空間が誕生しました。
2.3 デモ例
// 定义命名空间MyNameSpace
namespace MyNamespace {
int add(int a, int b) {
return a + b;
}
int subtract(int a, int b) {
return a - b;
}
}
int main() {
// 调用MyNamespace命名空间中的add函数
int result1 = MyNamespace::add(5, 3);
// 调用MyNamespace命名空间中的subtract函数
int result2 = MyNamespace::subtract(10, 4);
return 0;
}
2.4 詳細な名前空間
注意:市販されている多くの書籍のプログラム例では、名前空間 std を使用する追加が行われます。このコード行は、書籍内で記述の便宜のために説明されており、多くの読者にこれが固定された例であると思われ、誤解が生じます。この概念は捨てるべきです!!!
例えば:
#include<iostream>
using namespace std;
int main()
{
cout << "Hello World!" << endl;
return 0;
}
2.4.1 名前空間に対する作成者の理解
namespace
ネームスペースはプライベート ドメインの壁と考えてください。そこでは誰もが自分のドメイン内で何でもできますが、他の人はあなたの許可なしにドメインに侵入することはできません。
プログラマーが単独で開発する場合、名前空間を使用すると、さまざまなモジュールのコードを分離して競合を回避し、コードをより適切に分離できます。
複数人で開発する場合、プロジェクト統合時に起こる名前の衝突などの問題も回避できます。
2.4.2 使用法
ライセンスを取得するにはどうすればよいですか?
上の例のコードと同様にHelloWorld
、using namespace std
そのまま使用してください。
このコード行はどのように解釈されるべきでしょうか?
名前空間 std を使用する
std
これは C++ 標準ライブラリの名前空間であり、入出力、文字列処理、コンテナ、アルゴリズムなど、一般的に使用される多くのクラス、関数、オブジェクトが含まれています。
使用しない場合using namespace std;
、標準ライブラリのメンバーにアクセスするには、名前に接頭辞を付ける必要がありstd::
ますstd::cout
。
例えば:
#include<iostream>
//using namespace std;
int main()
{
std::cout << "Hello World!" << std::endl;
return 0;
}
using
ライセンスに相当し、using
フェンス内の情報を取得したり、内部コンテンツを自由に使用したりすることができます。
著者の以前の提案と同様に、これを直接使用しないようにしてくださいusing namespace std
。利点と欠点が混在しています。慎重に使用してください。!
その理由は次のとおりです。
を使用するとusing namespace std
コードが簡素化され、標準ライブラリ メンバーを使用するときに完全な名前空間プレフィックスを記述する必要がなく、直接使用できるようになります。
たとえば、 it を使用した後、接頭辞を付けずにusing namespace std
直接使用できます。cout
string
std::
using namespace std
名前空間全体std
が現在のスコープに取り込まれることに注意してください。
これにより、コードの冗長性が減りますが、名前の競合が発生するリスクも生じる可能性があります。大規模なプロジェクトや、他の名前空間のメンバーと区別する必要がある場合は、これを回避しusing namespace std
、代わりにusing
具体的な宣言を使用して、必要な特定のメンバーを取り込むことができます。
例えば:
#include<iostream>
//using namespace std;
using std::cout;
using std::endl;
int main()
{
cout << "Hello World!" << endl;
return 0;
}
2.4.3 スコープリゾルバー
C++ では、二重コロン (::) で表されるスコープ解決演算子 (スコープ解決演算子) は、名前空間、クラス、構造体、列挙などのメンバーにアクセスするために使用されます。
これも一種のパスですが、内部コンテンツを使用するたびにこのシンボルを追加して取得する必要があり、必要なものを取得できます。
using namespace + 命名空间
この方法は、すべて展開を使用する場合と同様にusing 命名空间::需要内容
、競合のリスクを軽減します。
例えば:
#include<iostream>
usingn namespace std;
namespace kaite{
int rand = 0;
}
int main(){
cout << kaite::rand << endl;
return 0;
}
ここではusing namespace std
矛盾を示すために使用されており、読者には他の 2 つの方法で書くことをお勧めします。
上記のコードは名前空間を定義していますkaite
。すべての名前空間を展開してもその中に関数std
はありますrand
が、自分の名前空間を展開するのではなく、スコープ リゾルバーを使用してフェンスを越えて検索するため、グローバルと競合することはありません。
ここでの説明により、読者は名前空間についてすでにある程度の理解を持っているはずだと思います。いくつかの考慮事項を以下に示します。
2.4.3 注意事項
2.4.3.1 名前空間は入れ子にできる
例えば:
namespace N1
{
int a;
int b;
namespace N2
{
int c;
int d;
}
}
//想使用命名空间N2中的变量也需要嵌套寻求
N1::N2::c = 0;
N1::N2::d = 0;
2.4.3.2 同じプロジェクト内の同じ名前の名前空間はマージされます
同じ名前を持つ複数の名前空間が同じプロジェクト内で許可され、コンパイラは最終的にそれらを同じ名前空間に結合します。
ネームスペースは新しいスコープを定義し、ネームスペース内のすべてのコンテンツはそのネームスペースに制限されます。
2.4.4 概要
名前空間を使用するには3 つの方法があります
- 名前空間名とスコープ修飾子の追加
- using を使用して名前空間にメンバーを導入します
- インポートするには、使用している名前空間の名前空間名を使用します。
3. C++ の入出力
C言語では入出力にprintfやscanfを使うことが多いです。したがって、C++ プログラミングに関しては、入力と出力も最も基本的で必要な操作の 1 つです。これらにより、ユーザーと対話したり、プログラムの結果をユーザーに表示したりすることができます。
C++ の入力と出力は通常、ストリームオブジェクトを通じて実装されます。
ストリームは、プログラムと外部デバイス (キーボード、画面、ファイルなど) の間でデータを転送する方法を提供する抽象的な概念です。
3.1 ストリーム
C++ の入出力について話すときは、まずストリームという重要な概念を理解する必要があります。
プログラミング言語でストリームについて話す場合、それはプログラムと外部デバイス(キーボード、画面、ファイルなど)の間でデータを転送するために使用される抽象化です。ストリームは、入力および出力操作を処理するための便利で統一された方法を提供します。
C++ では、ストリームは標準ライブラリのストリーム クラスを通じて実装されます。標準 C++ ライブラリには、次の 3 つのメイン ストリーム クラスが提供されます。
-
入力ストリーム:入力ストリームは、外部デバイス (通常はキーボードまたはファイル) からデータを読み取るために使用されます。C++ では、
std::istream
クラスは主に入力ストリームを表すために使用されます。クラスのオブジェクトstd::cin
であり、通常は標準入力からデータを読み取るために使用されます。std::istream
-
出力ストリーム:出力ストリームは、外部デバイス (通常は画面またはファイル) にデータを書き込むために使用されます。C++ では、
std::ostream
クラスは主に出力ストリームを表すために使用されます。クラスのオブジェクトstd::cout
であり、通常はデータを標準出力に書き込むために使用されます。std::ostream
-
入力/出力ストリーム (入力/出力ストリーム):入力/出力ストリームは、データの読み取りと書き込みの両方ができます。C++ では、
std::iostream
クラスは主に入力/出力ストリームを表すために使用されます。std::cin
と のstd::cout
基礎となる型は両方とも であるstd::iostream
ため、入力操作と出力操作の両方を実行できます。
ストリームは水の流れのように機能し、ストリームにデータが継続的に流入および流出します。データが読み取られると、ストリームはデータがなくなるまでデータ要素を 1 つずつ順番に提供します。データを書き込む場合、データはストリームに順番に書き込まれます。
3.2 ストリーム演算子
ストリームを操作するために、C++ は一連の特別な演算子を提供します。
-
入力演算子
>>
:入力ストリームからデータを抽出するために使用されます。ストリームからデータを読み取り、指定された変数に格納します。 -
出力演算子
<<
:出力ストリームにデータを書き込むために使用されます。画面上に表示したりファイルに書き込んだりするために、データをストリームに出力します。
cin >> num;
これらの演算子を使用すると、整数の読み取りに使用したり、文字列の出力に使用したりするなど、ストリーム操作が非常に直感的で理解しやすくなりますcout << "Hello, world!";
。
要約すると、ストリームは C++ における入出力操作を処理するための強力なツールです。データの読み取りと書き込みのための統一された方法を提供し、ユーザーとの対話やファイル操作の処理を簡単かつ効率的にします。ストリームの基本概念と使用法を理解することは、C++ プログラムを作成する場合に非常に重要です。
3.3 C++ 入力 (入力ストリーム)
C++ では、通常、
cin
入力操作を実行するために使用します。cin
C++ 標準ライブラリの入力ストリーム オブジェクトであり、通常はキーボード入力に関連付けられます。を通じてcin
、ユーザーが入力したデータを読み取り、定義した変数に保存できます。
ユーザーが入力した整数を読み取る簡単な例から始めましょう。
#include <iostream>
int main() {
int num;
std::cout << "Please enter an integer: ";
std::cin >> num; // 从用户输入读取整数并存储在num变量中
std::cout << "You entered: " << num << std::endl;
return 0;
}
プログラムを実行すると、整数の入力を求められます。整数を入力すると、プログラムは入力した整数を表示します。
整数に加えて、、 (文字列)などcin
の他のデータ型を読み取るために使用することもできます。使用方法も同様です。double
char
std::string
3.4 C++ 出力 (出力ストリーム)
C++ では、主に出力操作に使用します
cout
。cout
C++ 標準ライブラリの出力ストリーム オブジェクトであり、通常は画面出力に関連付けられます。を通じてcout
、データをユーザーに表示できます。
簡単な出力例を見てみましょう。
#include <iostream>
int main() {
int num = 42;
std::cout << "The number is: " << num << std::endl;
return 0;
}
このプログラムを実行すると、「数字は 42 です」と出力されます。
printf
関数を使用して、C 言語での使用と同様に、より複雑な形式の出力を実現することもできます。ただし、C++ では、 を使用するとcout
より C++ スタイルになり、読みやすく使いやすくなります。
4. デフォルトパラメータ
デフォルト引数は、関数宣言内のパラメータのデフォルト値を指定する機能です。関数を呼び出すときに、呼び出し元が対応するパラメーターの値を指定しない場合、関数は事前定義されたデフォルト値を使用します。これにより、場合によっては各呼び出しですべてのパラメーターの値を指定しなくても一部のパラメーターを省略できるため、関数呼び出しがより簡潔かつ柔軟になります。
C++ では、デフォルト パラメーターは関数の定義ではなく関数の宣言で指定できます。通常、関数はヘッダー ファイルで宣言され、実装ファイルで定義されるため、これはデフォルトのパラメーター情報を複数回繰り返すことを避けるために行われます。
4.1 コード例
#include <iostream>
// 带有缺省参数的函数声明
void printMessage(std::string message = "Hello, World!");
int main() {
// 调用函数时不提供参数
printMessage(); // 输出: "Hello, World!"
// 调用函数时提供参数
printMessage("Hi there!"); // 输出: "Hi there!"
return 0;
}
// 带有缺省参数的函数定义
void printMessage(std::string message) {
std::cout << message << std::endl;
}
上の例では、デフォルト値 の
printMessage
デフォルトパラメータを取る という名前の関数を定義しました。関数では、これを2 回呼び出します。1 回目は引数なしで、もう 1 回目は文字列引数を使用します。初めて呼び出すときは、パラメーターが指定されていないため、関数はデフォルト値を使用して を出力します。2回目の呼び出しでは、パラメーターが指定され、関数はパラメーター値を出力します。message
"Hello, World!"
main
printMessage
"Hello, World!"
4.2 デフォルトパラメータの分類
4.2.1 すべてのデフォルトパラメータ
void Func(int a = 10, int b = 20, int c = 30)
{
cout << "a = "<< a <<endl;
cout << "b = "<< b <<endl;
cout << "c = "<< c <<endl;
}
4.2.2 準デフォルトパラメータ
void Func(int a, int b = 20, int c = 30)
{
cout << "a = "<< a <<endl;
cout << "b = "<< b <<endl;
cout << "c = "<< c <<endl;
}
4.3 注意事項
- デフォルトのパラメータは通常、関数のパラメータ リストの最後で宣言する必要があります。これは、関数を呼び出すときに末尾のパラメーターを曖昧さなく省略できるようにするために行われます。つまり、準デフォルトのパラメータは右から左に順番に指定する必要があり、交互に指定することはできません。
- デフォルトのパラメータは、関数の宣言と定義の両方に使用できません。
- デフォルト値は定数またはグローバル変数/定数である必要があります。
- C言語はサポートしておりません(コンパイラはサポートしていません)。