私はこれを行う場合:型鋳造char配列**
#include <stdio.h>
typedef char **arr2D;
char arr1D [5 * 10];
int main (void)
{
((arr2D)arr1D)[0][0] = '_';
printf("%c", arr1D[0]);
return(0);
}
を私は未定義の動作を示唆してクラッシュを受けます。 なぜ私はこれを行うことができませんか?
私はこれを行う場合:型鋳造char配列**
#include <stdio.h>
typedef char **arr2D;
char arr1D [5 * 10];
int main (void)
{
((arr2D)arr1D)[0][0] = '_';
printf("%c", arr1D[0]);
return(0);
}
を私は未定義の動作を示唆してクラッシュを受けます。 なぜ私はこれを行うことができませんか?
char arr1D [5 * 10];
- ゼロが初期化されます。
((arr2D)arr1D)[0]
- arr1D
が指すメモリをchar *へのポインタとして再解釈します。これには不特定のアドレスがあります(ゼロバイトパターンは必ずしもNULLアドレスである必要はありません)。
((arr2D)arr1D)[0][0]
- 指定されていないアドレスを除外します。未定義の動作。
あなたの命名は、ポインタと配列に共通する誤解を示唆しています。配列はポインタではありません。ポインタは配列ではありません。
アレイ崩壊を最初の要素へのポインタに変換します。
char[2][2]
は、char(*)[2]
(配列へのポインタ)に減衰する2D文字配列です。
char**
は2Dの文字配列ではなく、ポインタへのポインタです。
ああそう..それを理解したはずです。だから私はこのトリックをすることができません。 – Malina
@マリナ - 私は、良いプログラミングはできるだけ魔法がないことを知っています。側面を理解するために多くの説明を必要とするコードは、できるだけ小さな範囲に制限する必要があります。 – StoryTeller
私にとっては悪いニュースだと思います。私は自分自身が良いトリックであると感じるときには気分がいい。これはかなり平凡なトリックです。 (そして私はそれを "トリック"と呼んでいないだろう)良いトリックを見つける同情の試み。 – Malina
@Inline - Nope。余分な星は重要です。 – StoryTeller
@Inline途中でこれは今でも複製に近いですか? – Malina