[解決済み] 2次元配列へのポインタを作成する
質問
静的な2次元配列へのポインタが必要です。これはどのように行われるのですか?
static uint8_t l_matrix[10][20];
void test(){
uint8_t **matrix_ptr = l_matrix; //wrong idea
}
などと、いろいろなエラーが出ます。
- 警告: 互換性のないポインタ型からの代入
- 添え字の値は配列でもポインタでもありません。
- error: flexible array member の無効な使用
どのように解決するのですか?
ここでは、配列の最初の要素へのポインタを作成します。
uint8_t (*matrix_ptr)[20] = l_matrix;
typedefを用いると、よりすっきりした印象になります
typedef uint8_t array_of_20_uint8_t[20];
array_of_20_uint8_t *matrix_ptr = l_matrix;
そうすれば、また人生を楽しむことができます :)
matrix_ptr[0][1] = ...;
注意すべきは ポインタ/配列の世界 には注意してください。
編集
コメント欄が短すぎてそこではできないので、ここで他の回答のいくつかをレビューする。複数の選択肢が提案されましたが、それらがどのように動作するかは示されていませんでした。以下は、それらがどのように動作するかです。
uint8_t (*matrix_ptr)[][20] = l_matrix;
エラーを修正し、address-of 演算子を追加すると
&
を追加すると、次のスニペットのようになります。
uint8_t (*matrix_ptr)[][20] = &l_matrix;
次にその1つは、20 uint8_tのarray型の要素の不完全な配列型へのポインタを作成します。このポインタは配列の配列へのものなので、それにアクセスするには
(*matrix_ptr)[0][1] = ...;
また、不完全な配列へのポインタであるため はできません。 ショートカットとして
matrix_ptr[0][0][1] = ...;
なぜなら、インデックス付けは要素型のサイズが分かっている必要があるからです(インデックス付けはポインタへの整数の追加を意味するので、不完全な型では動作しません)。なお、これは
C
でしか動作しないことに注意してください。
T[]
であり
T[N]
は互換性のある型です。C++には
互換性のある型
という概念がないため、そのコードは拒否されます。
T[]
と
T[10]
は異なるタイプです。
以下の代替案は全く機能しません。なぜなら、一次元配列として見たときの配列の要素型は
ではなく
uint8_t
しかし
uint8_t[20]
uint8_t *matrix_ptr = l_matrix; // fail
以下は良い代替案です。
uint8_t (*matrix_ptr)[10][20] = &l_matrix;
でアクセスすると
(*matrix_ptr)[0][1] = ...;
matrix_ptr[0][0][1] = ...; // also possible now
これは外側の次元のサイズを保持するという利点があります。そのため、その上にsizeofを適用することができます
sizeof (*matrix_ptr) == sizeof(uint8_t) * 10 * 20
配列のアイテムが連続的に格納されることを利用した、もう一つの回答があります。
uint8_t *matrix_ptr = l_matrix[0];
さて、この形式では2次元配列の最初の要素の要素にしかアクセスできません。つまり、以下の条件が成立します。
matrix_ptr[0] = ...; // valid
matrix_ptr[19] = ...; // valid
matrix_ptr[20] = ...; // undefined behavior
matrix_ptr[10*20-1] = ...; // undefined behavior
までしか動作しないことにお気づきでしょう。
10*20-1
までしか動作しませんが、エイリアス解析や他の積極的な最適化を行うと、コンパイラによってはそのコードが壊れるかもしれないという仮定をする可能性があります。とはいえ、この手法で失敗したコンパイラーに出会ったことはありませんし (ただし、実際のコードでこの手法を使ったことはありません)、C FAQ にもこの手法が (UB'ness についての警告とともに) 含まれており、配列タイプを変更できない場合、これはあなたを救う最後の選択肢になります :)
関連
-
解決済み] g++ コンパイルエラー: ')'トークンの前に一次式があることが予想される
-
未定義の `__isoc99_sscanf' への参照
-
[解決済み] C言語の書式指定子 %ul と %lu の違いは何ですか?
-
[解決済み] 配列から特定の項目を削除するにはどうすればよいですか?
-
[解決済み] JavaScript で配列に値が含まれているかどうかを確認するにはどうすればよいですか?
-
[解決済み] 配列からArrayListを作成する
-
[解決済み] 配列に特定のインデックスで項目を挿入する方法 (JavaScript)
-
[解決済み] JavaScriptで2次元の配列を作成するにはどうすればよいですか?
-
[解決済み] C言語でファイルが存在するかどうかを確認する最も良い方法は何ですか?
-
[解決済み】オブジェクトの配列を文字列のプロパティ値でソートする
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
赤線の位置は必ずしも間違っていない:式は変更可能なlvalueでなければならないエラーは、この文とは別の場所に存在する可能性があります。
-
C/C++の再定義
-
[解決済み] C言語でchar配列をコピーする方法は?
-
[解決済み] Windows用Cコンパイラ?[クローズド]
-
[解決済み] C言語の**はどういう意味ですか?
-
[解決済み] C言語における「static」の意味とは?
-
[解決済み] 難読化Cコードコンテスト2006。sykes2.cの解説をお願いします。
-
[解決済み] C言語標準に準拠した構造体の初期化方法
-
[解決済み] C言語でファイルが存在するかどうかを確認する最も良い方法は何ですか?
-
[解決済み] 講師が書いたC言語のファイルは、なぜ最初の行に#が一つ付いているのですか?