- ベストアンサー
ポインタの文字の代入について
素朴な疑問ですが、なぜ宣言文の時には*ptrに文字列を代入してもエラーが出ないのに、宣言文以外のところで下記の記述をするとエラーが出るのですか? #include<stdio.h> void main(void) { char *ptr = "DEF"; *ptr = "ABC";//コンパイルエラー ptr = "ABC";//正常 }
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
>宣言文の時には*ptrに文字列を代入してもエラーが出ない わけではないのです。 こう考えて下さい。 char *ptr; は char 「*ptr」; ではなく 「char *」 ptr; つまり「charへのポインタ」として「prt」を宣言したわけです。 ここで宣言されたのは「ptr」です。「*prt」ではありません。 一方、下の方に出てくる「*ptr」は「prt」に「*」をつけたものです。 ptrに*をつけると、char型の変数となります。 しかし、右側"ABC"の型は「char型」ではなくて「char型へのポインタ型」です。 型が合わなくてエラーになります。 細かいことを言います。 宣言のところで使われる「*」は、「ポインタ宣言子」といいます。 下の式のところで使われる「*」は「間接参照演算子」です。 つまり同じ「*」でも、違うものなのです。 これは、Cの宣言方法のわかりにくさにも責任があります。 ただもう直せないので、こういうものだと覚えて下さい。
その他の回答 (2)
- sha-girl
- ベストアンサー率52% (430/816)
x = "ABC"は文字列「ABC」を確保したアドレスをxに代入します。 一方t*ptr = xはアドレスptrにxを置こうとします。 つまり*ptr = 'A'とかなら 通ります。 *prtに格納できるのは1バイトの文字(char)です。 *ptr = 'A' *(ptr+1) = 'B' *(ptr+2) = 'C' *(ptr+3) = '\0' ならokです。 >*ptr = "ABC";//コンパイルエラー は*ptrにアドレス(普通4バイト)を格納しようとするからです。
宣言文における * は、あくまで 変数ptr がポインタであることを 示しているだけです。 つまり、char *ptr = "DEF"; 文は、 char型のポインタ変数 ptr を宣言し、 メモリ上に"DEF"という文字列を格納した領域が確保され、 その先頭アドレスをポインタ変数 ptr に「代入」しています。 しかし、*ptr = "ABC"; 文における * は「間接参照子」ですから、 ポインタ変数 ptr に格納されているアドレスが指し示す メモリ上にある内容を「参照」することしか出来ません。 さらにしかし、ptr = "ABC"; では、メモリ上のどこかに確保された 文字列 "ABC" の領域の先頭アドレスを、ポインタ変数に「代入」する結果に なるのでコンパイルが通る、のだと思います。
お礼
ポインタ宣言子と間接参照演算子という言葉は始めてききました。大変参考になりました。