2017-01-15 4 views
3

私はこれを行う場合:型鋳造char配列**

#include <stdio.h> 

typedef char **arr2D; 

char arr1D [5 * 10]; 

int main (void) 
{ 
    ((arr2D)arr1D)[0][0] = '_'; 

    printf("%c", arr1D[0]); 

    return(0); 
} 

を私は未定義の動作を示唆してクラッシュを受けます。 なぜ私はこれを行うことができませんか?

+0

@Inline - Nope。余分な星は重要です。 – StoryTeller

+0

@Inline途中でこれは今でも複製に近いですか? – Malina

答えて

4
  1. char arr1D [5 * 10]; - ゼロが初期化されます。

  2. ((arr2D)arr1D)[0] - arr1Dが指すメモリをchar *へのポインタとして再解釈します。これには不特定のアドレスがあります(ゼロバイトパターンは必ずしもNULLアドレスである必要はありません)。

  3. ((arr2D)arr1D)[0][0] - 指定されていないアドレスを除外します。未定義の動作。

あなたの命名は、ポインタと配列に共通する誤解を示唆しています。配列はポインタではありません。ポインタは配列ではありません。

アレイ崩壊を最初の要素へのポインタに変換します。

char[2][2]は、char(*)[2](配列へのポインタ)に減衰する2D文字配列です。
char**は2Dの文字配列ではなく、ポインタへのポインタです。

+0

ああそう..それを理解したはずです。だから私はこのトリックをすることができません。 – Malina

+0

@マリナ - 私は、良いプログラミングはできるだけ魔法がないことを知っています。側面を理解するために多くの説明を必要とするコードは、できるだけ小さな範囲に制限する必要があります。 – StoryTeller

+0

私にとっては悪いニュースだと思います。私は自分自身が良いトリックであると感じるときには気分がいい。これはかなり平凡なトリックです。 (そして私はそれを "トリック"と呼んでいないだろう)良いトリックを見つける同情の試み。 – Malina