[解決済み】int型配列へのポインタのスカラ・イニシャライザの過剰要素
質問
K&Rの演習問題(例5-9)をやっているのですが、元のプログラムの2次元配列である「...」を「...」に変換しようとしていました。
static char daytab[2][13] = {
{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
{0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
};
のような 13 個の int の配列へのポインタを使用するように変更しました。
static char (*daytab)[13] = {
{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
{0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
};
しかし、コンパイラは次のように表示します。 警告:スカラ・イニシャライザに過剰な要素があります .
ググっても解決せず、K&Rでも関数に配列を渡すと書き込みます。
myFunction(int daytab[2][13]) {...}
と同じです。
myFunction(int (*daytab)[13]) {...}
解決方法は?
この2つは一部しか等価ではありません。 という違いがあります。
static char daytab[2][13] = {
{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
{0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
};
は 2 次元配列を宣言しています.この宣言には,配列のための領域を確保することと
daytab
はそのメモリを参照する。 しかし
static char (*daytab)[13] = {
{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
{0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
};
...はポインタを宣言しているだけです。 つまり、ポインターを配列イニシャライザーで初期化しようとしているわけですが、これは期待通りにはいきません。 配列は存在しませんし、配列用に確保されたメモリもありません。 代わりに起こるのは、イニシャライザーの最初の数字がポインターに割り当てられることです。
daytab
そのため、コンパイラは警告を発して、たくさんの値を追加で指定したことを知らせますが、それは単に捨てられるだけです。 イニシャライザーの最初の数値は
0
を設定するだけです。
daytab
から
NULL
を、かなり冗長な方法で実行します。
つまり、このような初期化を行いたい場合は、最初のバージョンを使用します。これは、2番目のバージョンで明示的に宣言したのと同じポインタ型に減衰するので、同じように使用することができます。 2番目のバージョンでは、配列ポインタを使用します。これは、配列を動的に確保したり、すでに存在する別の配列への参照を取得したりする場合に必要です。
だから、こんなことができるんです。
static char arr[2][3] = { { 1, 2, 3 }, { 4, 5, 6 } };
static char (*ptr)[3] = NULL;
ptr = arr;
...そして
ptr
と
arr
を交換することができます。 あるいはこうも。
static char (*ptr)[3] = NULL;
ptr = malloc(2 * sizeof(*ptr));
...動的に割り当てられた2次元配列(1次元配列へのポインタの配列ではなく、本当の2次元配列)を取得します。 もちろん、その場合は初期化されません。
2つのバリエーションの"equivalence"は、2D配列がその最初の要素へのポインタに減衰するとき、2番目のバリエーションで宣言されたポインタのタイプに減衰することを意味するだけです。 ポインタ版が実際に配列を指すようになれば、この2つは等価です。 しかし、2次元配列では配列のメモリが設定され、ポインタの宣言では設定されません。また、2次元配列の変数ではできない新しい値(別の配列を指す)をポインタに代入することができます。
C99ではこれができるんですけどね(そうでない場合は
static
少なくとも)。
char (*daytab)[13] = (char [][13]){
{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
{0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
};
関連
-
[解決済み】エラー:cの入力の最後に期待される宣言またはステートメント
-
[解決済み】組み込み関数「malloc」の暗黙の宣言の非互換性
-
[解決済み】空の配列要素を削除する
-
[解決済み】ヒープ割り当てで初期化されていない値が作成された
-
[解決済み] JavaScriptで配列の先頭に新しい配列要素を追加するにはどうすればよいですか?
-
[解決済み] 配列の反復処理に "for...in "を使用するのは、なぜ良くないのでしょうか?
-
[解決済み] Javascriptで配列から空の要素を削除する
-
[解決済み] C 言語の配列へのポインタ/ポインタの配列の曖昧さ解消
-
[解決済み] 配列からポインタへの減衰とは何ですか?
-
[解決済み】JavaScriptで配列の要素を削除する - delete vs splice
最新
-
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 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】Cコンパイルエラー。"変数サイズのオブジェクトが初期化されていない可能性がある"
-
[解決済み] strtokのセグメンテーションフォールト
-
[解決済み] struct で "warning: useless storage class specifier in empty declaration" (警告: 空の宣言での無駄なストレージクラス指定子)
-
[解決済み】スレッド1:EXC_BAD_ACCESS(コード=1、アドレス=0x0)標準Cメモリ問題
-
[解決済み】ヒープ割り当てで初期化されていない値が作成された
-
[解決済み】C言語で多重定義を防ぐには?
-
[解決済み】MPI通信でMPI_Bcastを使用する場合
-
[解決済み】Makefile:1: ***セパレータがありません。停止します。
-
[解決済み】Linuxソケットのwrite()でBad File Descriptorが発生するC
-
[解決済み】C言語でpow( )への未定義参照、math.hを含むにもかかわらず【重複】。