アプリ版:「スタンプのみでお礼する」機能のリリースについて

C言語入門者です。今ポインタの勉強をしています。char *p=“123”と初期化し、後にp=“456”という処理を行うプログラムで、なぜ、2回目の代入と時には間接演算子をつけないのですか?

質問者からの補足コメント

  • char *p=“123”
    *p=“456”
    だとなぜダメなのでしょうか?
    p=“456”じゃないといけない理由を詳しくお願いします!

      補足日時:2018/06/29 19:44

A 回答 (6件)

char *p;


は pをchar* という型で宣言しています。
便宜上、*をpの側に付ける構文が許されているので、誤解する人もいます。
また仕様上、"123" は char*型になっています。
ですから、
char* p="123";
は同じ型の実態での初期化なので、問題ありませんし、
p="123";
も問題ないことが分かるかと思います。
さて、
*p
と書いたときの*は意味が異なります。この*は、char*型であるpをchar型に変換する単項演算子です。
ですから
*p = '4';
であれば問題ありません。なぜなら'4'がchar型だからです。
これを実行するとpの内容が
"423"
にかわります。
ちなみに、さらに
*(p+1) = '5';
を追加で実行すると、pの内容は
"453"
になります。
さらに
*(p+100) = '5';
とると、メモリリークが起こります。(アプリケーションに与えられたメモリの範囲内であれば、OSによるチェックはすり抜けるので、暴走することもあります。)
この理由から、私は
*(p+i) = ‥‥
のような書きかたはしないようにしています。
昔は、この書きかたが速度的に有利と聞きましたが、いまはコンパイラが頭いいので、p[]の方を多用しています。
配列型の宣言のほうが、デバッガでとらえやすいという面もあります。
    • good
    • 1

char *p="123";


の*はpの宣言におけるpの型のー部で
ポインタ型であることを表してます(charを指すポインタ)。

char* p="123";

と、それを意識した書き方をする人もいますね。

式の中で *p とかくと、ボインタpの指す、char型を表わす
ことになります。ポインタの逆参照と呼ぶことも有りますね。

char型なので、(char*)型である"456"を代入することは出来ません。
    • good
    • 1

これ、C言語のよくない点だと思ってます。




C言語では、宣言するときに「使うときと同じような見た目」になるようになっています。

char *p ;
とは
「*p と使ったら char型になる変数pを定義する」
というように見ます。
これを意訳すると
「charへのポインタpを定義する」
となります。


さらにややこしいことに、
宣言と同時に「代入」できるのですが、その代入先はあくまで「変数」です。
/* 正確には、初期化といって、代入とは違う点があります */

char *p=“123”
と書いてあって *p へ代入しているように見えても、あくまで代入先は 変数p です。
違って見えても p=“123” なのです。


「宣言のときの代入先は、あくまで素の変数」ということを理解して、慣れていくしかないと思います。
    • good
    • 1

>p=“456”じゃないといけない理由を詳しくお願いします!


char *p なので代入できるのはchar型のデータです。
*p=“456”
では、“456”、すなわち「文字列のアドレス」を代入しようとしてしまうのでエラーになります。

誤解の根源は
char *p=“123”;
の理解です。これを横着せずに記述すると
 char *p;

 p=“123”;
という意味ですよ。

 *p=“123”;
ではありません。

つまり
 *P は char型
ですが、
 p はポインタ型
なので、pにはアドレスを代入する必要があります。
    • good
    • 0

やってみれば?


暴走するけど、、
    • good
    • 0

char *p;


p = "123";
p = "456";
って事ですね。ま、合わせ技です。
    • good
    • 1

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!