• ベストアンサー

ポインタの計算

ポインタの位置計算で悩んでいます。 以下の計算で p1 を表示すると一文字目が化けてしまいます。 これは何故でしょうか? また化けないようにするにはどうすればよいでしょうか? ************************ char s1[50] = "Hello.world"; char *p1 = s1; char *p2 = s1; p1++; p1++; p1++; p1++; p1++; *p1 = p1 - p2; printf("%s\n", p1); ************************

質問者が選んだベストアンサー

  • ベストアンサー
  • chie65536
  • ベストアンサー率41% (2512/6032)
回答No.3

*p1 = p1 - p2; を実行すると、p1 - p2を計算し、その結果を「p1が指すアドレスに格納」します。 「p1 - p2」は「5」ですから、これは *p1 = 5; を実行しているのと同じです。 なので「p1が指すアドレスに5を格納する」事になります。 言い換えれば s1[5] = 5; と同じ事をします。 これは s1[5] = '\x05'; と同じです。 つまり「Hello.world」の「.」の位置に、非可読文字の「'\x05'」を上書きします。 そして printf("%s\n", p1); を実行すると、これは printf("%s\n", "\x05world"); と同じですから、1文字目の非可読文字が文字化けします。 因みに「p1 - p2」を計算すると「要素数の差」が求まります。「要素数の差」であって「バイト数」ではないので注意しましょう。 つまり、p1は&s1[5]になってて、p2は&s1[0]ですから「要素数の差」は「5 - 0」で「5」です。 言い換えれば「charのサイズで5個分、差がある」のが計算されます。「バイト数が求まる訳じゃない」ので注意しましょう。 表示方法を間違ってるだけで「ポインタの差」はちゃんと計算されてます。 「自分がプログラムに何をさせているか?」が良く判ってないようなので、もう少し考えてみましょう(「*p1 = 計算結果;」の意味が理解できてない)

mikami532
質問者

お礼

詳細で丁寧な説明ありがとうございます。 その差分の値を無理に格納していたのですね。 計算結果(アドレス)をそのまま格納していると勘違いしておりました。

その他の回答 (2)

  • tatsu99
  • ベストアンサー率52% (391/751)
回答No.2

>ポインタをインクリメントするとポインタの型の分だけ、ポインタアドレスが増大すると思っておりましたが、それとはまた別の話になるのでしょうか? はい、別の話です。 これは、 char s1[50] = "Hello.world"; s1[0] = 5; printf("%s\n",s1); と同じ現象になります。 1文字のところに入るべき文字は、印字可能な文字コードでなければなりません。

mikami532
質問者

お礼

ありがとうございます。 参考になります!

  • D-Matsu
  • ベストアンサー率45% (1080/2394)
回答No.1

p1の増分、つまり5が*p1に入るため、文字ではなく制御コードが入ってしまっています。詳しくはASCIIコード表参照。

mikami532
質問者

補足

ありがとうございます。 ポインタをインクリメントするとポインタの型の分だけ、ポインタアドレスが増大すると思っておりましたが、それとはまた別の話になるのでしょうか?

関連するQ&A