質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

プログラミング言語

プログラミング言語はパソコン上で実行することができるソースコードを記述する為に扱う言語の総称です。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

解決済

3回答

1618閲覧

配列を左辺に用いてはならないならば、if文の条件式に配列を左辺値として用いたいときは、どのようにそれを回避しつつ意味が変わらない条件式を書くのが常套手段なのか。

hanyansakura

総合スコア6

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

プログラミング言語

プログラミング言語はパソコン上で実行することができるソースコードを記述する為に扱う言語の総称です。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

0グッド

1クリップ

投稿2020/03/30 02:31

前提・実現したいこと

以下をご教授お願い致します。

・配列は左辺値ではないため左辺に持ってきてはならないのは理解した。しかし、それならば、下記の正しいソースコードでも同様に、if文の条件式の左辺に配列であるdt,distを持ってくるとエラーするはずではないのか。違いを生む理由は何か。
・”21行目、canは定義されていない識別子であること。”というエラーメッセージを得たが、canは13行目で定義しているはずである。理解に苦しむ。
・これらを踏まえた上で、ソースコードを訂正するならばどのようになるか。入門者であるため、普遍的な教訓まで教えていただけると非常にありがたい。

問題文

シカの AtCoDeer くんは二次元平面上で旅行をしようとしています。AtCoDeer くんの旅行プランでは、時刻 0 に 点 (0,0) を出発し、1 以上 N 以下の各 i に対し、時刻 tiに 点 (xi,yi) を訪れる予定です。

AtCoDeer くんが時刻 ti,ti+1 に 点 (xi,yi)(xi+1,yi+1) にいる時、 時刻 ti+1には 点(x+1,y),(x−1,y),(x,y+1),(x,y−1) のうちいずれかに存在することができます。その場にとどまることは出来ないことに注意してください。AtCoDeer くんの旅行プランが実行可能かどうか判定してください。

発生している問題・エラーメッセージ

・16行目、if文の条件式において、配列であるdt,dsが左辺にあること。
・21行目、canは定義されていない識別子であること。

該当のソースコード

C++

1自分が書いた誤ったソースコード 2 3include <iostream> 4using namespace std; 5 6int main() { 7 int N, i; 8 int t[100000], x[100000], y[100000]; 9 cin >> N; 10 t[0] = x[0] = y[0] = 0; 11 for (i = 0; i < N; i++) { 12 cin >> t[i + 1] >> x[i + 1] >> y[i + 1]; 13 } 14 for (i = 0; i < N; i++) { 15 int can = 1; 16 int dt = t[i + 1] - t[i]; 17 int ds = abs(x[i + 1] - x[i]) + abs(y[i + 1] - y[i]); 18 if ((dt - ds) % 2 = 0 && dt >= ds) { 19 can = 0; 20 } 21 else { break; } 22 } 23 if (can) { cout << "Yes"; } 24 else { cout << "No"; } 25 return 0; 26} 27 28### 正しい(正解の一例)ソースコード 29include <iostream> 30using namespace std; 31 32int main() { 33 int N; 34 int t[110000], x[110000], y[110000]; 35 cin >> N; 36 t[0] = x[0] = y[0] = 0; // 初期状態 37 for (int i = 0; i < N; ++i) cin >> t[i+1] >> x[i+1] >> y[i+1]; // 1-index にしておく 38 39 bool can = true; 40 for (int i = 0; i < N; ++i) { 41 int dt = t[i+1] - t[i]; 42 int dist = abs(x[i+1] - x[i]) + abs(y[i+1] - y[i]); 43 if (dt < dist) can = false; 44 if (dist % 2 != dt % 2) can = false; // dist と dt の偶奇は一致する必要あり! 45 } 46 47 if (can) cout << "Yes" << endl; 48 else cout << "No" << endl; 49}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

y_waiwai

2020/03/30 02:44

質問が意味不明です。 dt、dsは配列じゃないです。 エラーが出るならエラーメッセージを提示しよう
guest

回答3

0

ベストアンサー

配列は左辺値ではないため左辺に持ってきてはならないのは理解した。

左辺値は代入ができる値、という意味です。比較の左辺に置く(a[1] == 3のようにする)のは全く問題ありません。

投稿2020/03/30 02:39

編集2020/03/30 02:40
maisumakun

総合スコア145184

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hanyansakura

2020/03/30 02:45

数時間に及ぶ、疑問との不毛な格闘が一瞬で解決しました。 簡潔な回答をありがとうございました。
SaitoAtsushi

2020/03/30 03:28

左辺値・右辺値というのは公式な訳語 (JIS ではそう訳されている) なのですが、誤解を避けるために原文通りの lvalue / rvalue という語を使うことを好む人もいます。 左辺値・右辺値という語が割り当てられているのは歴史的な理由であり、現在では必ずしも左辺・右辺とは関係ありません。 C++ の仕様において定義が与えられている専門用語です。 https://ja.cppreference.com/w/cpp/language/value_category そして配列が左辺値ではないというのは誤解で、仕様の定義に従って解釈すれば配列として宣言された変数は左辺値 (lvalue) です。 左辺値の内で「変更可能な左辺値 (modifiable lvalue)」が代入可能なものです。
guest

0

手元ではこんなエラーメッセージが出ました。

c250265.cpp:21:21: エラー: 代入の左側の被演算子として左辺値が必要です if ((dt - ds) % 2 = 0 && dt >= ds) { ^

「左辺値が必要」とあるので「if文の条件式に配列を左辺値として用いたいときは・・・」という問いになったのでしょうが

if ((dt - ds) % 2 = 0
if ((dt - ds) % 2 == 0 と直すだけの、よくあるバグではないでしょうか。

投稿2020/03/30 12:34

rubato6809

総合スコア1380

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

配列を左辺値にできないというのは、正しいです。
※配列を戻り値とする関数を定義することはできない
ですが、「配列を構成する要素の中の一つ」は、通常は配列ではありません。ですからそれらの要素から導き出した値もまた(導いて配列にしなかったのでない限り)左辺値とすることができます。

C

1if ((dt - ds) % 2 = 0 && dt >= ds) { 2 can = 0; 3}

ここで dt は t[] の要素から導き出している値であって配列ではありませんし(int って定義してますよね?)、ds も x[] 及び y[] の要素から導き出している値ですから配列ではありません。
ですからこれがエラーの原因ではありません。

本当に書かれたコードの通りで、エラーも吐かれたとおりですか?

投稿2020/03/30 02:41

tacsheaven

総合スコア13703

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問