c言語、プログラミングについてです。
左辺値の考えを用いて(x=y)=5がなぜダメなのか理由を説明せよ。という問題です。(漠然とした問題ですが、本当にこのように書かれていて…)
私なりに調べてみました。x=5であれば、「xに5の値を代入する」という意味になり成り立つが、(x=y)=5だと(x=y)は結果であって、左辺値ではないので右辺の値を代入できない、というような説明が散見されました。
このくらいまでしか分かりませんでした。もっと明確な説明にしていきたいのですが、お教え頂けますでしょうか。よろしくお願いいたします。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答5件
0
ベストアンサー
6.5.16 代入演算子
ここに、以下のようにあります。
制約 代入演算子の左オペランドは,変更可能な左辺値でなければならない。
(x=y)=5 は、まず x = y が評価され、y の値となりますy の値が x に代入されます。そして新しい x の値が (x = y) の値となります。次に (y の値)(x の値) = 5 が評価されますが、この時左オペランドは変更可能な左辺値ではありません。
6.3.2.1 左辺値,配列及び関数指示子 左辺値(lvalue)は,オブジェクト型,又はvoid以外の不完全型をもつ式とする(53)。左辺値が評価されたときにオブジェクトを指し示していなければ,動作は未定義とする。オブジェクトがもつ型に言及する場合,その型とは,オブジェクトを指し示すために用いる左辺値によって指定される型とする。変更可能な左辺値(modifiable lvalue)とは,配列型をもたず,不完全型をもたず, const修飾型をもたない左辺値とし,それが構造体又は共用体の場合,const修飾型のメンバ(再帰的に包含されているすべての集成体又は共用体の任意のメンバ又は要素を含めて)をもたないものとする。
演算順序を変えて次のようにした場合、
x = (y = 5)
まず y = 5 が評価されます。y は変更可能な左辺値なので、y に 5 が代入され、評価値は y の値である 5 になります。次に x = 5 が評価されます。この時 x は変更可能な左辺値なので、x に 5 が代入され、評価値は 5 になります。
カッコがなかった場合、代入演算子は右結合なので、x = y = 5 は x = (y = 5) と同じ演算順序になります。
投稿2020/09/28 13:29
編集2020/09/28 23:22総合スコア28669
0
正確な説明は既にあるので、イメージでの説明を。
=
演算子、つまりは、代入とは何か?と考えると、少し見えてくるかもしれません。
C言語において、変数とは、メモリ上に割り当てられてた特定のアドレスに対するラベルのようなものです。
int x,y;
等としたときに、コンパイラはメモリ上のアドレスに変数を割り当てます。
例えば、x:0x1000
y:0x1004
みたいな感じです。
代入演算子=
は、その変数に対して値を書き込む、つまりは特定のメモリアドレスに対して、データを書き込む命令です。
x=5;
は、コンパイルされると、こんな感じになります。
[メモリアドレス0x1000 へ 数値5 を 出力せよ]
これが、代入演算子の正体です。
こんな感じに、
代入演算子とは、メモリアドレスに対するデータの書き込み命令である。と思えば、
=
の左側は書き込み先の場所を示している必要がある事がわかると思います。
[書き込み先] = [データ]
というのが、代入演算子の書式なのです。
そこから翻って、(x=y)=5
を見てみます。
この式は、まず、x=y
が実行されます。
これは普通にyのアドレスの値がメモリから読みだされ、xのアドレスにその内容が書き込まれます。
そこまでは問題ありません。
代入演算子にはもう一つ、代入した値を式の値とする。という機能があります。
例えば、y=8
だった場合、x=y
という式の値は8
になります。
x=y
が解決したので、残りの部分に取り掛かります。
(x=y)=5
ですので、上で実行した結果を受けて、式はこう変化します。
8=5
『数値8へ、数値5を代入せよ』
これは明らかにおかしいと、見てわかると思います。
代入演算子の左側には、書き込み先のメモリアドレスが指定されていなければなりません。
データ(数値)にデータ(数値)は書き込めません。
よって、左辺値がおかしいよ!というエラーになります。
これがもし、x=y=5
であれば、問題ありません。
結合法則により、並んだ=
は右から解決されます。
y=5
がまず実行され、yのアドレスに5が書き込まれます。
さらに、y=5
という式の値も5
となります。
x=(y=5)
は、x=(5)
となるので、同じように、xのアドレスに5が書き込まれ、
無事、式の実行は終わります。
(この連鎖的な代入を可能にしているのが、=の式の値が代入結果の値になるという機能です)
投稿2020/09/29 04:23
総合スコア1218
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
仕様に基づく根拠としては Zuishin 氏の説明がほぼ完璧だと思います。 ただ、質問者の課題はおそらく根拠ではなく考え方を問うものだと思うのでそもそも左辺値とは何であるかという点に重点を置いた回答が妥当でしょう。
変数を評価すると変数に入っている値が得られますが、代入するとき、つまり代入演算子の左辺に現れるときは値を格納すべき場所がわかっていなければなりません。 左辺値として定義されているものは、おおざっぱに言えば値であると同時に場所としての性質をもつものと言えます。 逆に場所としての性質を持たないものが右辺値です。
x=y
の演算をした結果は場所としての性質が失われているので値を格納することができないということです。
投稿2020/09/28 13:59
総合スコア5686
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
カッコが無ければ良いんですけどね。
変数に値は代入出来ても、式には代入出来ないですよね。
投稿2020/09/28 13:28
総合スコア923
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/09/28 13:47
2020/09/28 15:33
2020/09/28 21:08
退会済みユーザー
2020/10/05 12:54