C++ <array> at 関数
array の要素にアクセスするすべての方法の中で、atは最も安全な方法です。なぜなら、境界チェックを提供するからです。。
atはコンテナクラスのメンバ関数であり、指定位置の要素を返します。同時に境界チェックを行います。インデックスが範囲外の場合は、std::out_of_range例外をスローします。
at安全な要素アクセスを実現し、実行時に範囲外エラーをキャッチして処理することができます。
単語の意味: at「...の位置」を意味し、指定された位置の要素を取得します。
基本構文とパラメータ
atはコンテナクラスのメンバ関数なので、まずコンテナオブジェクトを用意し、ドット演算子を介して.呼び出します。
構文形式
reference at(size_type pos); const_reference at(size_type pos) const;
パラメータの説明
- パラメータ:
pos- 型:
size_type(符号なし整数型、通常はsize_t) - 説明: アクセスする要素の位置(インデックス)。インデックスは0から始まり、最大有効インデックスは
size() - 1。
- 型:
関数の説明
- 戻り値: 指定位置の要素の参照。コンテナがconstコンテナの場合は、const参照を返します。
- 効果: 指定位置の要素を返します。インデックスが有効範囲を超えた場合(
pos >= size())、std::out_of_range例外をスローします。 - operator[] との違い:
atは境界チェックを行いますが、operator[]は境界チェックを行いません(範囲外の動作は未定義です)。
例
簡単なものから複雑なものまでの一連の例を通して、atの使い方を徹底的にマスターしましょう。
例 1:基本の使い方 - 要素へのアクセス
例
#include <iostream>
#include <array>
#include <stdexcept>
int main() {
// 1. array を作成して初期化する
std::array<int, 5> numbers = {10, 20, 30, 40, 50};
std::cout << "arrayのサイズは: " << numbers.size() << std::endl;
// 2. at を使用して要素にアクセスする
std::cout << "最初の要素 (at(0)): " << numbers.at(0) << std::endl;
std::cout << "2番目の要素 (at(1)): " << numbers.at(1) << std::endl;
std::cout << "3番目の要素 (at(2)): " << numbers.at(2) << std::endl;
std::cout << "最後の要素 (at(4)): " << numbers.at(4) << std::endl;
// 3. ループを使用してすべての要素にアクセスする
std::cout << "すべての要素: ";
for(size_t i = 0; i < numbers.size(); ++i) {
std::cout << numbers.at(i) << " ";
}
std::cout << std::endl;
return 0;
}
#include <array>
#include <stdexcept>
int main() {
// 1. array を作成して初期化する
std::array<int, 5> numbers = {10, 20, 30, 40, 50};
std::cout << "arrayのサイズは: " << numbers.size() << std::endl;
// 2. at を使用して要素にアクセスする
std::cout << "最初の要素 (at(0)): " << numbers.at(0) << std::endl;
std::cout << "2番目の要素 (at(1)): " << numbers.at(1) << std::endl;
std::cout << "3番目の要素 (at(2)): " << numbers.at(2) << std::endl;
std::cout << "最後の要素 (at(4)): " << numbers.at(4) << std::endl;
// 3. ループを使用してすべての要素にアクセスする
std::cout << "すべての要素: ";
for(size_t i = 0; i < numbers.size(); ++i) {
std::cout << numbers.at(i) << " ";
}
std::cout << std::endl;
return 0;
}
実行結果の予想:
array的大小是: 5 第一个元素 (at(0)): 10 第二个元素 (at(1)): 20 第三个元素 (at(2)): 30 最后一个元素 (at(4)): 50 所有元素: 10 20 30 40 50
コードの解説:
numbers.at(0)最初の要素を返します10(インデックスは0から始まります)。numbers.at(4)最後の要素を返します50(size()は5なので、有効インデックスは0-4です)。- ループと
atを使用すると、すべての要素を安全に走査できます。
例 2:範囲外例外のキャッチ
atの主な利点は、例外をスローして範囲外エラーを処理できることです。
例
#include <iostream>
#include <array>
#include <stdexcept>
int main() {
std::array<int, 3> numbers = {10, 20, 30};
// 範囲外の位置へのアクセスを試みる
try {
std::cout << "at(10) へのアクセスを試みます..." << std::endl;
int value = numbers.at(10); // これにより例外がスローされる
std::cout << "値: " << value << std::endl;
}
catch(const std::out_of_range& e) {
std::cout << "例外をキャッチしました: " << e.what() << std::endl;
}
// 正常なアクセス
try {
std::cout << "at(2) へのアクセス: " << numbers.at(2) << std::endl;
}
catch(const std::out_of_range& e) {
std::cout << "例外をキャッチしました: " << e.what() << std::endl;
}
return 0;
}
#include <array>
#include <stdexcept>
int main() {
std::array<int, 3> numbers = {10, 20, 30};
// 範囲外の位置へのアクセスを試みる
try {
std::cout << "at(10) へのアクセスを試みます..." << std::endl;
int value = numbers.at(10); // これにより例外がスローされる
std::cout << "値: " << value << std::endl;
}
catch(const std::out_of_range& e) {
std::cout << "例外をキャッチしました: " << e.what() << std::endl;
}
// 正常なアクセス
try {
std::cout << "at(2) へのアクセス: " << numbers.at(2) << std::endl;
}
catch(const std::out_of_range& e) {
std::cout << "例外をキャッチしました: " << e.what() << std::endl;
}
return 0;
}
実行結果の予想:
尝试访问 at(10)... 捕获到异常: array::at: __pos (which is 10) >= _Nm (which is 3) 访问 at(2): 30
コードの解説:
- アクセスした場合、
at(10)インデックスが範囲外のため、std::out_of_range例外がスローされました。 catch(const std::out_of_range& e)例外をキャッチし、e.what()例外の説明情報を返します。- 正常なインデックスアクセスでは例外はスローされません。
例 3:要素の値の変更
atは参照を返すため、要素の値の変更に使用できます。
例
#include <iostream>
#include <array>
int main() {
std::array<int, 3> numbers = {10, 20, 30};
std::cout << "変更前: ";
for(size_t i = 0; i < numbers.size(); ++i) {
std::cout << numbers.at(i) << " ";
}
std::cout << std::endl;
// at() を使用して参照を取得し、要素を変更する
numbers.at(0) = 100;
numbers.at(1) = 200;
numbers.at(2) = 300;
std::cout << "変更後: ";
for(size_t i = 0; i < numbers.size(); ++i) {
std::cout << numbers.at(i) << " ";
}
std::cout << std::endl;
return 0;
}
#include <array>
int main() {
std::array<int, 3> numbers = {10, 20, 30};
std::cout << "変更前: ";
for(size_t i = 0; i < numbers.size(); ++i) {
std::cout << numbers.at(i) << " ";
}
std::cout << std::endl;
// at() を使用して参照を取得し、要素を変更する
numbers.at(0) = 100;
numbers.at(1) = 200;
numbers.at(2) = 300;
std::cout << "変更後: ";
for(size_t i = 0; i < numbers.size(); ++i) {
std::cout << numbers.at(i) << " ";
}
std::cout << std::endl;
return 0;
}
実行結果の予想:
修改前: 10 20 30 修改后: 100 200 300
コードの解説:
numbers.at(0) = 100;参照を通じて最初の要素の値を変更しました。- これは、
at()が変更可能な左辺値参照を返すことを示しています。
その他の拡張
C++ コンテナクラス <array>