第7章 C言語のポインタ2 ~charポインタとchar配列~

休憩室

 今回のトピックスは、あまり休憩にならないかもしれません。 char 配列と char ポインタの続きになります。 全員が理解していなくても構いませんが、余裕のある人には是非知っておいて欲しいことです。 かなり難しいことも出てきますので、今のところ完全には理解できなくて当たり前のことです。

 まず最初は、char 配列の初期化と、char ポインタについてです。

— リスト20 —

#include <stdio.h>
#include <string.h>

void main()
{
  char  array[7] = "abcdef";  /* char配列の初期化 */
  char  *ptr = "ghijkl";     /* charポインタの初期化 */

  printf("array = %s\n", array);
  printf("ptr = %s\n", ptr);
}

 変数の宣言時にいきなり、文字列を代入していますね。 わざわざ関数 strcpy を使うよりも、このような記述の仕方で、文字列をコピーしてくれます。 とっても便利ですね。

 しかし、これは変数の初期化の時だけしか使えません (C++やJava言語になると、いつでもこのような文字列の代入ができます)。

 また、以下のように数字を省略して記述しても、 Cコンパイラが自動的に、char 配列の大きさを7個にしてくれます。

   char  array[] = "abcdef";  /* char配列の初期化 */

 通常は、このような書き方が一般的です。 何故なら、文字列の長さが変わったとしても、[7]を[8]に変更したりする手間が省けるからです。

 次に、ポインタ演算についてです。さっそく、次のように変更してみてください。

— リスト20` —

#include <stdio.h>
#include <string.h>

void main()
{
  char  array[7] = "abcdef";  /* char配列の初期化 */
  char  *ptr = "ghijkl";     /* charポインタの初期化 */
  int   cnt;

  /**
   * char配列を、一文字ずつ表示する
   */
  printf("char配列を、一文字ずつ表示する\n");
  for (cnt = 0; array[cnt] != '\0'; cnt++) {
    printf("%08X %c\n", &array[cnt], array[cnt]);
  }

  /**
   * charポインタを、一文字ずつ表示する
   */
  printf("charポインタを、一文字ずつ表示する\n");
  for (cnt = 0; *(ptr + cnt) != '\0'; cnt++) {
    printf("%08X %c\n", ptr + cnt, *(ptr + cnt));
  }
}

 赤字部分がポインタ演算です。 ポインタに対して、普通の数値と同様に加算をしていますね。 これは、仮に prt の箱の中に 0012ff3c というアドレスが入っているとすると、 (0012ff3c + 0)、(0012ff3c + 1)、(0012ff3c + 2)…という具合に アドレスが加算されているということです。

 もちろん、ポインタに対して他の演算を行うこともできますが、 よく使われるのは++演算子くらいで、他はあまり使いません。 以下は、char ポインタに対して、++演算子を使った例です。

— リスト20`` —

#include <stdio.h>
#include <string.h>

void main()
{
  char  array[7] = "abcdef";  /* char配列の初期化 */
  char  *ptr = "ghijkl";     /* charポインタの初期化 */
  int   cnt;

  /**
   * char配列を、一文字ずつ表示する
   */
  printf("char配列を、一文字ずつ表示する\n");
  for (cnt = 0; array[cnt] != '\0'; cnt++) {
    printf("%08X %c\n", &array[cnt], array[cnt]);
  }

  /**
   * charポインタを、一文字ずつ表示する
   */
  printf("charポインタを、一文字ずつ表示する\n");
  for (; *ptr != '\0'; ptr++) {
    printf("%08X %c\n", ptr, *ptr);
  }
}

 赤字部分が、なかなかすっきりしたように見えるかもしれません。 しかしこれだと、ポインタ変数である ptr が指している場所は、少しずつ移動しています。 ですから、文字列を二回表示することはできません。

 char ポインタに対して++演算子を使うことは、文字列を検索したり置換したりする時など、 ごく限られた時のみです。

 最後に、リスト20を以下のように変更してみてください。

— リスト20``` —

#include <stdio.h>
#include <string.h>

void main()
{
  char  array[7] = "abcdef";  /* char配列の初期化 */
  char  *ptr = "ghijkl";     /* charポインタの初期化 */
  int   cnt;

  /**
   * char配列を、一文字ずつ表示する
   */
  printf("char配列を、一文字ずつ表示する\n");
  for (cnt = 0; array[cnt] != '\0'; cnt++) {
    printf("%08X %c\n", &array[cnt], array[cnt]);
  }

  /**
   * charポインタを、一文字ずつ表示する
   */
  printf("charポインタを、一文字ずつ表示する\n");
  for (cnt = 0; *(ptr + cnt) != '\0'; cnt++) {
    printf("%08X %c\n", ptr + cnt, *(ptr + cnt));
  }

  /**
   * char配列をcharポインタ同然に扱い、一文字ずつ表示する
   */
  printf("char配列をcharポインタ同然に扱い、一文字ずつ表示する\n");
  for (cnt = 0; *(array + cnt) != '\0'; cnt++) {
    printf("%08X %c\n", array + cnt, *(array + cnt));
  }

  /**
   * charポインタをchar配列同然に扱い、一文字ずつ表示する
   */
  printf("charポインタをchar配列同然に扱い、一文字ずつ表示する\n");
  for (cnt = 0; ptr[cnt] != '\0'; cnt++) {
    printf("%08X %c\n", &ptr[cnt], ptr[cnt]);
  }
}

 なんだか、char 配列であるはずの array も、 char ポインタであるはずの ptr も全く同じように扱えるようですね。

 確かに char ポインタは、初期化されていないと危険です。 しかし、初期化された char ポインタは、char 配列と何ら変わりがないのです。

 以上です。かなり、難しいトピックスでしたので、理解できなくても落ち込まないでください。

< 前のページへ
お問い合わせ
  • ようかん
  • SG Labs(エスジー ラボ)
  • ITERACY
  • RiceLog(ライスログ)
  • Salesforce導入コンサルティング
  • SES営業向け用語講座

Pagetop