文字列ポインタを配列にする


次の様な配列を考えてみましょう。

char *str[6];

例によって演算子 * と[ ] の優先順位を考えると、[ ] の方が順位が上です。したがって

char *(str[6]);

となります。これは str[6] という char * 型の配列ですね。即ち、char 型へのポインタの配列、ということになります。これを初期化するには、次のようにかけばいいです。

char *str[6] = {
  "abc",
  "de",
  "fghi",
  "jklmnop",
  "qrs",
  "tuvwxyz",
};  

特に、最後の"tuvwxyz"の後のコンマがついてますが、もりろんかくてもかまいません。

ソースコード

源文件
  1|/* strings01.c */                                                                     
  2|
  3|#include <stdio.h>
  4|
  5|int main(void)
  6|{
  7|  char *str[6] = {
  8|    "abc",
  9|    "de",
 10|    "fghi",
 11|    "jklmnop",
 12|    "qrs",
 13|    "tuvwxyz",
 14|  };
 15|  int i;
 16|
 17|  for(i = 0; i < 6; i++){
 18|    printf("%s",str[i]);
 19|  }
 20|    printf("\n");
 21|    return 0;
 22|}

実行結果

abcdefghijklmnopqrstuvwxyz


さて、str[0], str[1], ... str[5]は配列なので、メモリ上に並んでいるはずです。確かめてみましょう。

ソースコード

源文件
  1|/* strings02.c */
  2|
  3|#include <stdio.h>
  4|
  5|int main(void)
  6|{
  7|  char *str[6] = {
  8|    "abc",
  9|    "de",
 10|    "fghi",
 11|    "jklmnop",
 12|    "qrs",
 13|    "tuvwxyz",
 14|  };
 15|  int i;
 16|
 17|  for(i = 0; i < 6; i++){
 18|    printf("str[%d]のアドレスは%p\n", i, &str[i]);                                    
 19|  }
 20|  return 0;
 21|}

実行結果

str[0]のアドレスは0x7fff5fbff650
str[1]のアドレスは0x7fff5fbff658
str[2]のアドレスは0x7fff5fbff660
str[3]のアドレスは0x7fff5fbff668
str[4]のアドレスは0x7fff5fbff670
str[5]のアドレスは0x7fff5fbff678

ちゃんと8バイトずつ並んでいますね。

  • str[0]には、文字列 "abc" の先頭文字のアドレスが格納されています。
  • str[1]には、文字列 "de" の先頭文字のアドレスが格納されています。
  • str[2]には、文字列 "ghi" の先頭文字のアドレスが格納されています。
  • str[3]には、文字列 "jklmnop" の先頭文字のアドレスが格納されています。
  • str[4]には、文字列 "qrs" の先頭文字のアドレスが格納されています。
  • str[5]には、文字列 "tuvwxyz" の先頭文字のアドレスが格納されています。

    したがって

  • str[0][0]には'a'
  • str[0][1]には'b'
  • str[0][2]には'c'
  • str[0][3]には'\0'
が格納されています。

str[0][4]とか、str[0][5]とかにはアクセスしてはいけません。ところが、str[5][4], str[5][5], str[5][6], str[5][7]にアクセス可能です。


Chapte7 @ C言語目録 @ HomeWork List @ 昭亮's Homepage