- ベストアンサー
ポインタの計算
ポインタの位置計算で悩んでいます。 以下の計算で p1 を表示すると一文字目が化けてしまいます。 これは何故でしょうか? また化けないようにするにはどうすればよいでしょうか? ************************ char s1[50] = "Hello.world"; char *p1 = s1; char *p2 = s1; p1++; p1++; p1++; p1++; p1++; *p1 = p1 - p2; printf("%s\n", p1); ************************
- みんなの回答 (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 = 計算結果;」の意味が理解できてない)
その他の回答 (2)
- tatsu99
- ベストアンサー率52% (391/751)
>ポインタをインクリメントするとポインタの型の分だけ、ポインタアドレスが増大すると思っておりましたが、それとはまた別の話になるのでしょうか? はい、別の話です。 これは、 char s1[50] = "Hello.world"; s1[0] = 5; printf("%s\n",s1); と同じ現象になります。 1文字のところに入るべき文字は、印字可能な文字コードでなければなりません。
お礼
ありがとうございます。 参考になります!
- D-Matsu
- ベストアンサー率45% (1080/2394)
p1の増分、つまり5が*p1に入るため、文字ではなく制御コードが入ってしまっています。詳しくはASCIIコード表参照。
補足
ありがとうございます。 ポインタをインクリメントするとポインタの型の分だけ、ポインタアドレスが増大すると思っておりましたが、それとはまた別の話になるのでしょうか?
お礼
詳細で丁寧な説明ありがとうございます。 その差分の値を無理に格納していたのですね。 計算結果(アドレス)をそのまま格納していると勘違いしておりました。