Thinkers'Studio
JavaとC言語の自習ツール
配列とポインタのプログラムクイズ(2)

ポインタ参照の書き方

 ポインタを使うとき、ポインタ自身が指す場所を変えたり、いま指しているところの前や後ろを見る書き方ができます。
  (ポインタ自身を動かす) p++ や p-- でポインタ自身をひとつ進めたり戻したりする。 p += 2 と書くと2つ進める。
  (前や後ろを見る) p+1 で隣の要素、p-1 ならひとつ手前の要素、p+2 と書くと2つ先にある要素を指す。

ポインタは文字列操作でよく使われる

 下のプログラムは、文字列 str の内容を表示しますが、途中に大文字があればその前に空白を入れます。
 上で挙げた2種類のポインタ参照の書き方が含まれます。
#include <stdio.h>
#include <ctype.h>
main()
{
    char    *p;
    char    str[] = "WeCanWorkItOut";

    for( p = str; *p != '\0'; p++ ) {
        putchar( *p );
        if( isupper( *(p+1) ) ) putchar( ' ' );
    }
    putchar( '\n' );
}
 ポインタ p が str 配列の先頭を指すようにした後、p が指す文字 *p が文字列の終端でない間 p を進め、表示処理を繰り返します。 空白を putchar するのは、isupper に p の隣の要素の値を渡してそれが大文字だった場合です。
 このプログラムを実行すると、次のように表示されます。
We Can Work It Out
 ポインタに関するコードを下に整理します。
char *p p は char型データの記憶場所(アドレス)を指すポインタです
p = str 配列名だけ書くとその先頭要素のアドレスを表わします。それを代入しています
str を配列とせずに、char *str のように文字列へのポインタとした場合も p = str で指し示します
*pポインタ p が指す値です
p++ ポインタ p の値をひとつ進めて次の要素を指すようにします
*(p+1) p+1 は、ポインタ p に char型ひとつ分を足したアドレス
その前に * をつけると (p+1) が指す値、つまり次の文字の値を参照しています

(今回のクイズです)
 上のプログラムで *(p+1) の ( ) は必要ですが、わざと ( ) を取り除き、下のように書き換えて実行しました。
    if( isupper( *p+1 ) ) putchar( ' ' );
 実行結果は次の通りです。なぜこのようになるのか説明してください。
W eC anW orkI tO ut
   (答えは、次回のC言語の Tips で ・・・)

[ 関連記事 ] 用語集:ポインタ, Tips:ポインタの間違い探し, 配列とポインタのクイズ(1), 同(3), NULLポインタ
[ ご案内 ] ポインタの要点を学習できるコース:要点講座 [配列とポインタ編]

前回のクイズの答え: (前回の問題を見る
(1) の実行結果:argc が 1 なので、Usage が表示されてプログラムが終わる
(2) の実行結果:指定通り、2099年から 3年分のうるう年判定の結果が表示される
(3) の実行結果:2014 がMAXCNTの50にリミット調整され、2013年から 50年分のうるう年判定が行われる