ポインタの話

C言語でのポインタの話。C言語は3年前に3ヶ月ほど講義を受けただけで当時はポインタの説明を聞いてもイマイチだった記憶があります。なので、まずはポインタって何だったかを思い出すとこから。というのも、C言語って文字列は配列にしか入らないから不便だなぁという大きな誤解をしていた*1ことに気づいたからなんです。

そんな恥ずかしい話はさておき、ポインタの話。ポインタを使って文字列を定義してみる。

char *str="abc123";

こうするとメモリ上のどこかに連続した領域を確保してそこの先頭からabc123を順に格納する。つまりstrにはメモリ上の連続した領域の先頭のアドレス、つまりaが格納されているメモリのアドレスが格納されている。

整理すると・・・

  • *はポインタ参照の演算子
  • 続く変数にアドレスが代入される
  • そこから文字が順に代入される

ちょっと試してみる

#include <stdio.h>

int main(void) {
    char *str="abc123";

    printf("%p\n",str);         // ポインタの先頭アドレス表示
    printf("%c\n",*str);        // aが表示されるはず
    printf("%c\n",*(str+1));    // bが表示されるはず
    printf("%c\n",*(str+2));    // cが表示されるはず
    printf("%c\n",*(str+3));    // 1が表示されるはず
    printf("%c\n",*(str+4));    // 2が表示されるはず
    printf("%c\n",*(str+5));    // 3が表示されるはず
    printf("%s\n",*str);        // abc123が表示されるはず
    printf("%c\n",*(str+5)+1);  // 4が表示されるはず    
}

ちゃんと出力されるか確認

0x804854c
a
b
c
1
2
3
Segmentation fault (core dumped)

あれ?正しく動かない・・・。printfの下から2行目の*strはstrの間違いですね。これで動くはず。

#include <stdio.h>

int main(void) {
    char *str="abc123";

    printf("%p\n",str);         // ポインタの先頭アドレス表示
    printf("%c\n",*str);        // aが表示されるはず
    printf("%c\n",*(str+1));    // bが表示されるはず
    printf("%c\n",*(str+2));    // cが表示されるはず
    printf("%c\n",*(str+3));    // 1が表示されるはず
    printf("%c\n",*(str+4));    // 2が表示されるはず
    printf("%c\n",*(str+5));    // 3が表示されるはず
    printf("%s\n",str);         // abc123が表示されるはず
    printf("%c\n",*(str+5)+1);  // 4が表示されるはず    
}

出力確認。

0x804856c
a
b
c
1
2
3
abc123
4

ちゃんと意図した通りに動きました。これでなんとなくポインタの大まかな理解完了*2。次は構造体とかをやってみようかな。

*1:なんでだろう?

*2:ここ違うぞ、とかあれば是非教えて下さい