ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子1=サッカー, 子2=野球
子ページを親ページとして更に子ページを作成することも可能です。
例: 親=サッカー, 子=サッカーのルール
親ページはいつでも変更することが可能なのでとりあえず作ってみましょう!
C++で配列(1次元)の要素数を求めるには、組み込み配列なら sizeof(arr) / sizeof(arr[0]) または C++17 の std::size(arr) を使い、std::array や std::vector なら .size() を呼びます。最も注意すべき点は、組み込み配列を関数の引数として渡すと配列がポインタに変わり(ポインタ減衰)、sizeof による要素数計算が正しく動かなくなることです。
| この記事の要点 |
|---|
|
基本: sizeof を使う方法
組み込み配列の要素数は、配列全体のバイト数を 1 要素のバイト数で割ることで求められます。sizeof(arr) は配列全体のバイト数、sizeof(arr[0]) は先頭要素のバイト数を返すため、これらの商が要素数になります。この方法は古い C++(C++03 以前)でも使え、ヘッダのインクルードも不要です。
|
#include <iostream> int main() { std::size_t count = sizeof(arr) / sizeof(arr[0]); std::cout << "要素数: " << count << "\n"; // 5 |
sizeof(arr[0]) の代わりに sizeof(*arr) や sizeof(arr) / sizeof(int) と書くこともできますが、要素の型を直接書くと型を変えたときに修正漏れが起きやすいため、sizeof(arr[0]) の形が安全です。
std::size を使う方法(C++17)
C++17 からは std::size が標準ライブラリに追加され、配列の要素数をより明確に取得できるようになりました。<iterator> をインクルードして使います(多くの実装では <array> や <vector> 経由でも利用できます)。sizeof の割り算より意図が読み取りやすく、コンテナにもそのまま使えるのが利点です。
|
#include <iostream> int main() { std::cout << std::size(arr) << "\n"; // 5 |
std::array / std::vector の場合
標準ライブラリのコンテナである std::array や std::vector は、.size() メンバ関数で要素数を取得できます。これらは要素数を自身で管理しているため、関数に渡してもポインタに変わることがなく、sizeof のような落とし穴がありません。固定長なら std::array、可変長なら std::vector が選択肢になります。
|
#include <iostream> int main() { std::cout << a.size() << "\n"; // 5 |
範囲for で要素を順に処理する
要素数そのものではなく「全要素を順に処理したい」だけなら、要素数を数える必要はありません。C++11 以降の範囲for for (auto x : arr) を使えば、要素数を意識せずに配列の全要素をたどれます。組み込み配列・std::array・std::vector のいずれにも使えます(ただし範囲forも、ポインタに減衰した配列には使えない点は sizeof と同じです)。
|
#include <iostream> int main() { for (auto x : arr) { |
重要: 関数に配列を渡すと sizeof が効かない(ポインタ減衰)
組み込み配列を関数の引数として渡すと、配列は先頭要素へのポインタに変換されます。これをポインタ減衰(配列からポインタへの暗黙変換)と呼びます。減衰後はポインタのバイト数(多くの環境で 4 または 8 バイト)しか分からなくなるため、関数の中で sizeof(arr) / sizeof(arr[0]) を計算しても、元の要素数ではなく「ポインタのバイト数 ÷ 要素のバイト数」が求まってしまいます。
|
#include <iostream> // arr は実際には int* に減衰している int main() { |
この問題を避けるには、要素数を別の引数として一緒に渡すか、ポインタに減衰しない std::array / std::vector を引数に使う、あるいは配列参照を受け取るテンプレートにするといった方法があります。要素数を扱う処理を関数に分ける場合は、組み込み配列をそのまま渡さない設計が安全です。
各手法の比較
| 手法 | 主な対象 | C++バージョン | 減衰後の動作 | 安全性 |
|---|---|---|---|---|
sizeof(arr)/sizeof(arr[0]) |
組み込み配列 | C++03〜 | 誤った値になる | 条件付き |
std::size(arr) |
組み込み配列・コンテナ | C++17〜 | コンパイルエラーで気付ける | 高い |
.size() |
std::array / std::vector |
C++11〜 | 減衰しない | 高い |
| 範囲for | 配列・コンテナ(走査のみ) | C++11〜 | 減衰した配列には使えない | 条件付き |
std::size はポインタに対しては使えずコンパイルエラーになるため、減衰に気付かず誤った値を使ってしまう事故を防げる点で sizeof の割り算より安全です。要素数を確実に管理したい場面では、std::array や std::vector の利用も検討してください。
多次元配列の場合
2 次元以上の配列では、各次元の要素数の求め方や注意点が 1 次元とは異なります。詳しくは関連記事 多次元配列の要素数 を参照してください。
落とし穴
| 落とし穴 | 内容 |
|---|---|
| ポインタ減衰 | 関数に渡した組み込み配列はポインタになり、sizeof での要素数計算が機能しない。要素数を別途渡すかコンテナを使う。 |
| sizeof はバイト数 | sizeof(arr) は要素数ではなくバイト数を返す。要素数を得るには sizeof(arr[0]) で割る必要がある。 |
| 型を直接書いた割り算 | sizeof(arr)/sizeof(int) のように要素の型を直書きすると、型変更時に修正漏れが起きやすい。 |
| 空配列・可変長 | 組み込み配列は要素数 0 を作れず、実行時に決まるサイズも扱えない。可変長が必要なら std::vector を使う。 |
FAQ
Q. sizeof(arr) / sizeof(arr[0]) と std::size(arr) はどちらを使うべきですか?
A. C++17 以降が使えるなら std::size(arr) をおすすめします。意図が明確で、ポインタに対してはコンパイルエラーになるため、ポインタ減衰による誤った要素数の使用を防げます。C++14 以前など std::size が使えない環境では sizeof の割り算を使います。
Q. なぜ関数の中だと要素数が正しく取れないのですか?
A. 組み込み配列を関数の引数として渡すと、配列が先頭要素へのポインタに変換される(ポインタ減衰する)ためです。関数内ではポインタのバイト数しか分からず、元の要素数は取得できません。要素数を一緒に引数で渡すか、std::array / std::vector を使ってください。
Q. std::vector の要素数が int と比較すると警告が出ます。
A. .size() は符号なし整数型(std::size_t)を返すため、int と比較すると符号の違いで警告が出ることがあります。受け取る変数を std::size_t にするか、用途に応じて適切にキャストして比較してください。
ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子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
コメントを削除してもよろしいでしょうか?