ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子1=サッカー, 子2=野球
子ページを親ページとして更に子ページを作成することも可能です。
例: 親=サッカー, 子=サッカーのルール
親ページはいつでも変更することが可能なのでとりあえず作ってみましょう!
C++で多次元配列の要素数を求めるには、配列全体のバイト数を1要素のバイト数で割るのが基本です。総要素数は sizeof(arr) / sizeof(arr[0][0])、行数は sizeof(arr) / sizeof(arr[0])、列数は sizeof(arr[0]) / sizeof(arr[0][0]) で求められます。sizeof はコンパイル時に確定する演算子なので、要素数も実行前に決まります。
| この記事の要点 |
|---|
|
前提:配列のサイズは sizeof でわかる
C++の組み込み配列には「自分が何要素あるか」を返す機能はありません。そこで使うのが sizeof 演算子です。sizeof は対象が占めるメモリのバイト数を返します。配列に対して使うと、その配列が占める全バイト数が得られます。
たとえば int が4バイトの環境で int a[2][3]; を宣言すると、要素は全部で 2×3=6 個、合計で 6×4=24 バイトを占めます。このとき sizeof(a) は 24 を返します。要素1個分のバイト数 sizeof(a[0][0])(=4)で割れば、要素数が逆算できるという仕組みです。
sizeof はコンパイル時に評価される演算子なので、求まる要素数も実行前に確定する定数になります。ただし、この方法が成り立つのは配列の実体(要素数が型に含まれている状態)に対して sizeof を適用したときだけである点に注意してください(詳細は後述の「落とし穴」を参照)。
2次元配列の総要素数を求める
2次元配列の全要素数は、配列全体のバイト数を1要素のバイト数で割って求めます。
|
#include <iostream> int main() { int arr[2][3] = { {1, 2, 3}, {4, 5, 6} }; // 総要素数 = 配列全体のバイト数 / 1要素のバイト数 std::size_t total = sizeof(arr) / sizeof(arr[0][0]); std::cout << total << "\n"; // 6 } |
sizeof(arr) は配列全体の24バイト、sizeof(arr[0][0]) は int 1個分の4バイトなので、24÷4=6 が得られます。割り算の結果の型は std::size_t(符号なし整数)になるため、受け取る変数も std::size_t にしておくと警告を避けられます。
各次元の要素数(行数・列数)を求める
各次元の要素数は、「1つ外側の要素のバイト数」を「1つ内側の要素のバイト数」で割ると求められます。int arr[2][3] の場合、arr[0] は「int 3個分の配列(=1行)」を表すことがポイントです。
|
#include <iostream> int main() { int arr[2][3] = { {1, 2, 3}, {4, 5, 6} }; // 行数 = 配列全体 / 1行分 std::size_t rows = sizeof(arr) / sizeof(arr[0]); // 列数 = 1行分 / 1要素分 std::size_t cols = sizeof(arr[0]) / sizeof(arr[0][0]); std::cout << rows << "\n"; // 2(行数) std::cout << cols << "\n"; // 3(列数) } |
関係を整理すると次のとおりです。総要素数は「行数×列数」と一致します。
| 求めたいもの | 式 | int arr[2][3] での値 |
|---|---|---|
| 総要素数 | sizeof(arr) / sizeof(arr[0][0]) |
6 |
| 行数(第1次元) | sizeof(arr) / sizeof(arr[0]) |
2 |
| 列数(第2次元) | sizeof(arr[0]) / sizeof(arr[0][0]) |
3 |
std::size(C++17)で書く
C++17以降では <iterator>(または多くの標準ヘッダ)で使える std::size を利用できます。組み込み配列に対しては各次元の要素数を返すため、sizeof の割り算よりも意図が読み取りやすくなります。
|
#include <iostream> #include <iterator> // std::size int main() { int arr[2][3] = { {1, 2, 3}, {4, 5, 6} }; std::cout << std::size(arr) << "\n"; // 2(行数) std::cout << std::size(arr[0]) << "\n"; // 3(列数) } |
std::size(arr) が第1次元(行数)、std::size(arr[0]) が第2次元(列数)を返します。総要素数が必要なら、両者を掛け合わせるか、前述の sizeof 方式を使います。なお std::size はポインタに対しては利用できないため、配列がポインタへ減衰してしまう関数内などでは使えません(後述)。
std::array / std::vector での扱い
標準ライブラリのコンテナを使うと、要素数の取得はメンバ関数 .size() で完結します。組み込み配列の sizeof 計算と違い、ポインタへ減衰しないので関数に渡しても要素数を取り出せるのが大きな利点です。
|
#include <iostream> #include <array> #include <vector> int main() { // std::array による2次元配列 std::array<std::array<int, 3>, 2> a = { { {1, 2, 3}, {4, 5, 6} } }; std::cout << a.size() << "\n"; // 2(行数) std::cout << a[0].size() << "\n"; // 3(列数) // std::vector による2次元配列 std::vector<std::vector<int>> v = { {1, 2, 3}, {4, 5, 6} }; std::cout << v.size() << "\n"; // 2(行数) std::cout << v[0].size() << "\n"; // 3(先頭行の列数) } |
std::array は要素数が型に含まれる固定長配列で、.size() はコンパイル時に決まる定数を返します。std::vector は実行時に伸縮できる可変長配列で、.size() はその時点の要素数を返します。std::vector による2次元配列は行ごとに長さが異なる場合があるため、列数は「行ごとに v[i].size() を見る」点に注意してください。
関数に渡すと sizeof が効かない
もっとも間違えやすいのが、配列を関数の引数に渡したときの挙動です。C++では配列を関数に渡すと、先頭要素へのポインタに変換(減衰)されます。その結果、関数側の sizeof は配列全体ではなくポインタ自身のサイズを返してしまい、要素数を正しく計算できません。
|
#include <iostream> // 仮引数 arr は int(*)[3] というポインタに減衰している void print_count(int arr[2][3]) { // sizeof(arr) はポインタのサイズ(例: 8)になる std::cout << sizeof(arr) / sizeof(arr[0][0]) << "\n"; // → 6 にはならない(誤った値) } int main() { int arr[2][3] = { {1, 2, 3}, {4, 5, 6} }; print_count(arr); } |
関数の引数で int arr[2][3] と書いても、先頭の次元のサイズは無視され、実際には int (*arr)[3](「int 3個の配列」へのポインタ)として扱われます。そのため sizeof(arr) は配列全体ではなくポインタのバイト数になります。
関数内で要素数を使いたい場合は、次のいずれかで対処します。
- 要素数(行数・列数)を別の引数として一緒に渡す。
std::arrayやstd::vectorを渡し、.size()で取得する。- テンプレートで配列を参照(
const T (&arr)[N][M])として受け取り、N・Mを型から取り出す。
1次元配列の要素数について
1次元配列の要素数の求め方(sizeof(arr) / sizeof(arr[0]))や、ポインタ減衰の扱いについては、関連記事の 配列の要素数 でも詳しく解説しています。多次元配列は「1次元配列の各次元への応用」と捉えると理解しやすくなります。
落とし穴・注意点
| 注意点 | 内容 |
|---|---|
| ポインタには sizeof が使えない | 関数引数や new[] で確保した配列はポインタなので、sizeof ではポインタ自身のサイズしか得られず、要素数を計算できません。 |
| 可変長配列(VLA)は非標準 | int n = 5; int arr[n][n]; のように実行時の変数でサイズを決める書き方は、C++標準には含まれません(一部コンパイラの拡張機能)。可変長が必要なら std::vector を使います。 |
| size_t は符号なし | sizeof や std::size の結果は std::size_t(符号なし整数)です。int と比較・演算すると暗黙変換による警告や予期しない結果を招くことがあります。 |
| vector の列数は行ごとに異なりうる | std::vector による2次元配列は各行の長さがそろっているとは限らないため、列数は v[0].size() だけで判断せず、必要な行ごとに確認します。 |
よくある質問(FAQ)
Q. なぜ sizeof(arr) / sizeof(arr[0][0]) で総要素数が求まるのですか?
A. sizeof(arr) は配列全体が占めるバイト数、sizeof(arr[0][0]) は1要素が占めるバイト数です。全体のバイト数を1要素のバイト数で割れば、要素が何個並んでいるか(=総要素数)が求まります。要素の型が int でも double でも、この比は要素数になります。
Q. sizeof 方式と std::size はどちらを使うべきですか?
A. C++17以降が使える環境なら、意図が明確で間違えにくい std::size が読みやすくおすすめです。総要素数を一発で求めたい場合や古い規格に合わせる必要がある場合は sizeof 方式が便利です。どちらも配列がポインタへ減衰していないことが前提です。
Q. 関数の中で多次元配列の要素数を正しく取得するには?
A. 配列は関数に渡すとポインタへ減衰するため、sizeof では取得できません。要素数を別の引数として渡すか、std::array / std::vector を渡して .size() を使うか、テンプレートで配列参照として受け取り型からサイズを取り出す方法を使います。
ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子1=サッカー, 子2=野球
子ページを親ページとして更に子ページを作成することも可能です。
例: 親=サッカー, 子=サッカーのルール
親ページはいつでも変更することが可能なのでとりあえず作ってみましょう!
子ページはありません
人気ページ
- 1 Eclipseで「サーバーに追加または除去できるリソースがありません。」の原因と対処法
- 2 tomcat の起動 / 停止ログと catalina.log・catalina.out の違い
- 3 JavaScript base URL 取得方法|window.location.origin と SSR/Node.js 対応
- 4 YouTube Data API v3 エラー一覧|403/400/404 の主要原因と切り分け
- 5 Spring Frameworkのアノテーション一覧
- 6 Laravel エラー一覧|500/Blade/DB 接続/ルーティングの代表エラー
- 7 3Dグラフィックスとは|モデリング/レンダリング/主要ソフトウェア (Blender / Maya)
- 8 【Spring】@Valueアノテーションとは
- 9 CATALINA_HOME の確認方法 (Linux / Mac)
- 10 【Spring】@Autowiredアノテーションとは
最近更新/作成されたページ
- IPv6とは|128bitアドレス・コロン16進表記/::省略・リンクローカル・SLAAC・デュアルスタック NEW 2026-06-22 12:34:44
- MAC アドレスフィルタリングの仕組みと限界 | ネットワーク入門 NEW 2026-06-22 12:19:10
- VPNとは|暗号トンネル・サイト間/リモートアクセス・IPsec/SSL-VPN/WireGuardを解説 NEW 2026-06-22 12:19:10
- WebRTC とは ブラウザ間 P2P の音声・映像・データ通信 | ネットワーク入門 NEW 2026-06-22 12:17:25
- HTTP/2 とは 多重化・HPACK・バイナリフレーム | ネットワーク入門 NEW 2026-06-22 12:17:25
- Web通信プロトコル入門 HTTP/2・HTTP/3・WebSocket・gRPC・WebRTC | ネットワーク入門 NEW 2026-06-22 12:17:25
- gRPC とは HTTP/2 + Protocol Buffers の高速 RPC | ネットワーク入門 NEW 2026-06-22 12:17:25
- HTTP/3 (QUIC) とは UDP ベースの低遅延 Web 通信 | ネットワーク入門 NEW 2026-06-22 12:17:25
- WebSocket とは 全二重リアルタイム通信 ws/wss | ネットワーク入門 NEW 2026-06-22 12:17:25
- 証明書と認証局(CA)とは|X.509・信頼チェーン・DV/OV/EV・失効(CRL/OCSP)を解説 NEW 2026-06-22 12:17:24
- ファイアウォールとは|パケットフィルタ・ステートフル・DMZ・次世代FW(L4/L7)を解説 NEW 2026-06-22 12:17:24
- iptables/nftablesとは|テーブル・チェーン・ルール例・永続化をLinux視点で解説 NEW 2026-06-22 12:17:24
- HAProxy とは frontend/backend と設定例 | ネットワーク入門 NEW 2026-06-22 12:17:24
- CDN とは エッジキャッシュ・TTL・Cloudflare/CloudFront | ネットワーク入門 NEW 2026-06-22 12:17:24
- TLS/SSLの仕組み|ハンドシェイク・暗号スイート・前方秘匿性・証明書検証をわかりやすく解説 NEW 2026-06-22 12:17:24
コメントを削除してもよろしいでしょうか?