<二次元配列とポインタ配列>
 
 二次元配列とポインタ配列は互換性がありますが、では違いはどこにあるのでしょうか?
 
 例として、複数の文字列を二次元配列として宣言する場合を考えます。
 
char
str[3][4]={"ABC","DEF","GHI"};
 
 この場合、3つの文字列はメモリ上のあるアドレス(例えば0x1000)から連続した領域に格納されます。
 
アドレス          配列要素          中身(文字データ)
0xabcd0000      str[0][0]       'A'
0xabcd0001      str[0][1]       'B'
0xabcd0002      str[0][2]       'C'
0xabcd0003      str[0][3]       '\0'
0xabcd0004      str[1][0]       'D'
0xabcd0005      str[1][1]       'E'
0xabcd0006      str[1][2]       'F'
0xabcd0007      str[1][3]       '\0'
0xabcd0008      str[2][0]       'G'
0xabcd0009      str[2][1]       'H'
0xabcd000a      str[2][2]       'I'
0xabcd000b      str[2][3]       '\0'
 
 同じ複数の文字列を、以下のようにポインタ配列として宣言することもできます。
 
char
*str[3]={"ABC","DEF","GHI"};
 
 この場合、strはポインタの配列であり、個々の要素(str[0], str[1], str[2])はポインタ、つまりアドレスを格納する変数です。
 
アドレス          配列要素          中身(アドレス)
0xabcd0000      str[0]          0x00001000
0xabcd0004      str[1]          0x00001008
0xabcd0008      str[2]          0x00001010
 
 実際の文字列データはどこにあるのでしょうか?それはstrの各要素が示しているアドレスにあるのです。
 
アドレス          中身(文字データ)
0x00001000      'A'     — str[0]が指しているアドレス
0x00001001      'B'
0x00001002      'C'
0x00001003      '\0'
 ...    
0x00001008      'D'     — str[1]が指しているアドレス
0x00001009      'E'
0x0000100a      'F'
0x0000100b      '\0'
 ...
0x00001010      'G'     — str[2]が指しているアドレス
0x00001011      'H'
0x00001012      'I'
0x00001013      '\0'
 
 この例のように、各文字列リテラルに連続したメモリが割り当てられるとは限りません。