C/C++のポインタの機能--配列との関係

沖林正紀
2008/03/28 17:00

ポインタは配列と深い関係があることを前回言及したが、今回はそれが具体的にどのようなことなのかを説明していきたい。

ポインタ変数と配列との関係

 ポインタ変数と配列との深い関係を表す例を示そう。それは、配列の変数名をポインタ変数のように扱えるということだ。

    int n[] = { 7, 3, 5, 9, 2 };
    printf( "%d\n", *n );  /*  7 と出力される  */

 上記は、nを5つのint型の要素を持つ配列として宣言した後、すぐに*nの値を表示させている。この結果は7と出力される。つまり、*nは配列の最初の要素(n[ 0 ])の値を表していることになる。

 では、n[ 1 ]以降の値を*nを使って表すにはどうしたらよいだろうか。そのためには以下のように記述する。

    int n[] = { 7, 3, 5, 9, 2 };
    printf( "%d\n", *(n + 1) );   /* 3 と出力される */
    printf( "%d\n", *(n + 2) );   /* 5 と出力される */

 こうすると、*(n + 1)がn[ 1 ]の値を表し、*(n + 2)がn[ 2 ]の値を表すことがお分かりいただけるだろう。

ポインタ変数と文字列との関係

 C/C++においては、文字列は文字の配列として扱われるので、ポインタ変数との関係はほとんど上記のint型配列の場合と同じなのだが、異なっている点もある。以下に例を示そう。

    char s[] = "Hello";
    printf( "%c\n", *s );         /* H と出力される */
    printf( "%c\n", *(s + 1) );   /* e と出力される */
    printf( "%c\n", *(s + 2) );   /* l と出力される */
    printf( "%s\n", s );          /* Hello と出力される */

 配列sをHelloという文字列で初期化した後、*sを書式%cで出力すると、最初の文字Hが表示される。これはs[ 0 ]の値だ。同じ書式で*(s + 1)の値を出力すると、eが表示される。これはs[ 1 ]の値だ。ここまでのところは、書式を%cにしている以外はint型の場合と同じだ。

 int型と異なるのは書式%sのときだ。ここでは*sではなくsと記述している。以前にもこのような処理については説明しているが、%sは桁数の指定がない時は文字列の終端('\0')までを*sから順に*(s + 1)の値、*(s + 2)の値、と出力することを表す。その結果、文字列が出力されることになるわけだ。

 ここで、文字へのポインタを使って違う書き方をしてみよう。以下に例を示す。前述の配列の場合と処理の仕方に変わりがないことがおわかりいただけるだろう。

  char *p = "Hello";
  printf( "%c\n", *p );       /* H と出力される */
  printf( "%c\n", *(p + 1) ); /* e と出力される */
  printf( "%s\n", p );        /* Hello と出力される */

 しかし、前述の配列では、配列変数sを指定された文字列で「初期化」していたのに対し、今回のポインタ変数pには、"Hello"という文字列を指すポインタ(アドレス)が代入されているという違いがある。配列は、まるごと“代入”することができないので、sとvという同じ型の配列があるとき s = v;とは書けないが、p と q という同じ型のポインタであればp = q; と書くことはできる。

 たとえば、ポインタ変数pに別の文字列へのポインタを代入したいのであれば、変数を初期化した後でも p = "Welcome"; とすることができる。なお、文字列(文字の配列)以外に、任意の型の配列定数を表現することはできないので、初期化時に int n[] = { 1, 2, 3 }; と書くことはできても、int *p; に対して p = { 1, 2, 3 }; と書くことはできない。

  • コメント(12件)

#1 επιστημη  - 2008/03/29 10:05

> ポインタ変数と配列との深い関係を表す例を示そう。 > それは、配列の変数名をそのままポインタ変数名として扱えるということだ。 ... 続きを見る
» 不適切なコメントを報告する

#2 επιστημη  - 2008/03/29 10:14

[2page冒頭] > さきほど*sで1つの文字列を表していたが、 違います。*sは"文字列"ではなく(先頭の)"文字"です。 文字列を表すのは*... 続きを見る
» 不適切なコメントを報告する

#3 がる  - 2008/03/31 00:20

んと…とりあえず筆者の方に伺ってみたいのですが。 char s[] = "Hello"; と char *s = "Hello"; との違いが「どのあたりにある」と... 続きを見る
» 不適切なコメントを報告する

#4 bright  - 2008/04/06 11:12

配列の変数名をそのままポインタ変数名として扱えるのではなく、配列のデータアクセスと、ポインタ経由でのデータアクセスに同じ表現が... 続きを見る
» 不適切なコメントを報告する

#5 リュート  - 2008/04/17 21:27

気になったことがあるのですが,コメントの書き方で char s[] = "Hello"; と char s[] = {'H', 'e', 'l', 'l', 'o', '\0'}; が同じ... 続きを見る
» 不適切なコメントを報告する

#6 がる  - 2008/04/19 01:33

ところで。「C/C++のポインタの機能--配列との関係」が未修正のまま大分時間が経過しているように見えるのですが。 いつ頃修正されるご... 続きを見る
» 不適切なコメントを報告する

#7 tomita  - 2008/04/21 13:59

builder編集部の冨田です。 連載の修正が遅れており、ご迷惑をおかけしております。申し訳ございません。 いついつまでに修正を完了... 続きを見る
» 不適切なコメントを報告する

#8 オワタ  - 2008/05/13 10:42

この筆者の方はIなのですか。。。 Iのレベルも落ちたもんだ。。。
» 不適切なコメントを報告する

#9 tomita  - 2008/06/03 18:29

builder編集部の冨田です。 本記事を6月3日の18時に修正しました。 修正が多岐に渡っているため、修正個所を逐次記載するのではなく... 続きを見る
» 不適切なコメントを報告する

#10 tomita  - 2008/06/03 18:29

1ページ目 ポインタ変数と配列との関係  ポインタ変数と配列との深い関係を表す例を示そう。それは、配列の変数名をそのままポイ... 続きを見る
» 不適切なコメントを報告する

#11 tomita  - 2008/06/03 18:30

2ページ目 ポインタ変数の配列  ポインタ変数も配列を宣言できる。これは文字列の配列を表す場合によく用いられる。以下にその例... 続きを見る
» 不適切なコメントを報告する

#12 tomita  - 2008/06/03 18:30

以上です。 読者の皆様には大変ご迷惑をおかけしましたこと、深くお詫び申し上げます。
» 不適切なコメントを報告する
記事に関係する情報をコメントでお寄せください

ニックネーム : CNET_IDにログインしてコメントする

コメント本文(必須) :
  • 新着記事
  • 人気記事
  • 特集
  • ブログ