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

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

新規登録して質問してみよう
ただいま回答率
85.50%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Visual C++

Microsoft Visual C++はWindowsのCとC++の統合開発環境(IDE)であり、コンパイラやデバッガを含んでいます。

YouTube

YouTubeとはユーザーがビデオをアップロード・共有・閲覧できるビデオ共有ウェブサイトです。

C++

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

Q&A

解決済

2回答

1742閲覧

二次元配列の書き込みについて

gift-0618

総合スコア22

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Visual C++

Microsoft Visual C++はWindowsのCとC++の統合開発環境(IDE)であり、コンパイラやデバッガを含んでいます。

YouTube

YouTubeとはユーザーがビデオをアップロード・共有・閲覧できるビデオ共有ウェブサイトです。

C++

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

0グッド

0クリップ

投稿2021/09/21 12:09

編集2021/09/21 12:20

はじめに

C/C++の外部ライブラリなしでゲームを作っているものです。(YouTubeの動画を参考に(パズ◯ラ))
初心者でどこがどのように間違っているのかわからないので質問させていただきます・・・

困っているところ

変数への書き込みについて困っています。
こちらが書いているコードです↓

C

1#include <cstdio> 2#include <cstdlib> 3#include <conio.h> 4#include <iostream> 5#include <ctime> 6using namespace std; 7 8#define BOARD_WIDTH 6 9#define BOARD_HEIGHT 5 10 11enum { 12 DROP_NONE, 13 DROP_FIRE, // 火 14 DROP_WATER, // 水 15 DROP_WOOD, // 木 16 DROP_LIGHT, // 光 17 DROP_DARK, // 闇 18 DROP_MAX 19}; 20 21enum { 22 DROP_STATUS_DEFAULT, 23 DROP_STATUS_HOLD, 24 DROP_STATUS_MAX 25}; 26 27typedef struct { 28 int x, y; 29}VEC2; 30char bropAA[DROP_MAX][DROP_STATUS_MAX][2 + 1] = { 31 {" "," "}, // DROP_NONE, 32 {"▽","▼"}, // DROP_FIRE, // 火 33 {"△","▲"}, // DROP_WATER, // 水 34 {"◇","◆"}, // DROP_WOOD, // 木 35 {"◯","●"}, // DROP_LIGHT, // 光 36 {"☆","★"} // DROP_DARK, // 闇 37}; 38 39int board[BOARD_HEIGHT][BOARD_WIDTH]; 40 41VEC2 cursorPos = {}; 42 43bool holding = false; 44 45int main() { 46 srand((unsigned int)time(NULL)); 47 48 for (int y = 0; y < BOARD_HEIGHT; y++) 49 for (int x = 0; x < BOARD_WIDTH; x++) 50 board[y][x] = 1 + rand() % (DROP_MAX - 1); 51 52 while (true) { 53 system("cls"); 54 for (int y = 0; y < BOARD_HEIGHT; y++) { 55 for (int x = 0; x < BOARD_WIDTH; x++) { 56 int status = DROP_STATUS_DEFAULT; 57 if(holding && (x == cursorPos.x) && (y == cursorPos.y)) 58 status = DROP_STATUS_HOLD; 59 cout << bropAA[board[y][x]][status]; 60 } 61 62 if (y == cursorPos.y) 63 cout << "←"; 64 cout << endl; 65 } 66 67 for (int x = 0; x < BOARD_WIDTH; x++) 68 if (x == cursorPos.x) 69 cout << "↑"; 70 else 71 cout << " "; 72 73 VEC2 lastCursorPos = cursorPos; 74 switch (_getch()) { 75 case 'w':cursorPos.y--; break; 76 case 's':cursorPos.y++; break; 77 case 'a':cursorPos.x--; break; 78 case 'd':cursorPos.x++; break; 79 default: 80 holding = !holding; 81 break; 82 } 83 84 if (holding) 85 int temp = board[cursorPos.y][cursorPos.x]; 86 board[cursorPos.y][cursorPos.x] = board[lastCursorPos.y][lastCursorPos.x]; 87 board[lastCursorPos.y][lastCursorPos.x] = temp; 88 } 89}

このコードの中で困っているのは最後の方の

C

1if (holding) 2 int temp = board[cursorPos.y][cursorPos.x]; 3 board[cursorPos.y][cursorPos.x] = board[lastCursorPos.y][lastCursorPos.x]; 4 board[lastCursorPos.y][lastCursorPos.x] = temp;

の部分です。
int temp にboard[省略][省略]を書き込もうとしてもtempが定義されていませんとエラーが出ます。
参考にしている動画ではコンパイルが通っています。

環境

OS:Windows 10 Home 64bit
コンパイラ:Visual Studio 2022 Preview
使用言語:C/C++

さいごに

こんなことで質問してしまってすみません・・・まだ初心者なもので・・・
一応コードは理解してるつもりなのですが・・・

回答してくださる心優しい方を待ってます・・・

追記

エラーメッセージの詳細を忘れていました・・・
エラーメッセージは以下です。

重大度レベル コード 説明 プロジェクト ファイル 行 抑制状態

エラー (アクティブ) E0020 識別子 "temp" が定義されていません Puzzle and Dragons C:\Users\user\Documents\Programming\C - C++\Puzzle and Dragons\Puzzle and Dragons\source.cpp 87

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

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

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

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

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

guest

回答2

0

(YouTubeの動画を参考に(パズ◯ラ))

それよりも先に基礎からやりましょう
今やっていることは、料理で例えると、「レシピ通りには作らずに、オリジナリティを出そうとして、余計なものを入れまくっている状態」です。

そりゃ、まともなものは作れませんし、仮に出来たとしても、たまたまうまくいっただけです。

それと、「エラーメッセージぐらいは読みましょう」。
エラーメッセージにヒントが隠されています。

int temp にboard[省略][省略]を書き込もうとしてもtempが定義されていませんとエラーが出ます。

(最初の質問)

だと仮定します。

まず、エラーメッセージに行番号が書かれているはずなのでそこを見ましょう。

メッセージから考えると、

if (holding) int temp = board[cursorPos.y][cursorPos.x]; board[cursorPos.y][cursorPos.x] = board[lastCursorPos.y][lastCursorPos.x]; board[lastCursorPos.y][lastCursorPos.x] = temp;

のようですね。

……えーっと、とりあえず「C言語 if文」とかで検索してみてください。
(修正: なぜかfor文になってた…)

C/C++でのfor文とかは、"{}" でくくったものが一つのブロックと見なされます。

"{}"を省略すると一行が対象になるのです。

他の方の回答のコメント部にあるリンク先には、

そもそも{}は複文を書くための手段なのであって,それが無い状態が「省略形」なのではない.

と書かれていますね。(発想が逆だったらしい)

(打消し文での)「一行」が紛らわしいとご指摘があったので、ここも修正します。
一行というよりは1ステートメントってところでしょうか。

つまり、"{}"を省略せずに書くと、

if (holding){ int temp = board[cursorPos.y][cursorPos.x]; } board[cursorPos.y][cursorPos.x] = board[lastCursorPos.y][lastCursorPos.x]; board[lastCursorPos.y][lastCursorPos.x] = temp;

という感じでしょうか。

C/C++では Pythonみたいにインデントでブロックを表現する…わけじゃないので、"{}"で一つの対象範囲とします。

次に、コードを読みましょう

コードを読むコツは『一行レベルで、何をしているかを考えながら読む』です。

今回のコードは長いので問題の部分だけを読みます。

C++

1 // holding が trueなら(?) 2 if (holding){ 3 // temp に カーソルがある場所のボードの位置の値を設定 4 int temp = board[cursorPos.y][cursorPos.x]; 5 } 6 // 前回のカーソルの場所にする? 7 board[cursorPos.y][cursorPos.x] = board[lastCursorPos.y][lastCursorPos.x]; 8 // 前回のカーソルの場所をtempの値にする 9 board[lastCursorPos.y][lastCursorPos.x] = temp;

これを「疑似コード」にする。

1. holding が trueなら(?) 1.1. temp に カーソルがある場所のボードの位置の値を設定 2. 前回のカーソルの場所にする? 3. 前回のカーソルの場所をtempの値に変更

temp のスコープを考えてください。

(1.1)しか対象範囲にありません。
そうなると、(3)でtempの値を使おうとしていますが、「おいおい、そんなもん、ねーぞ」と言われますよね。

つまり基礎が出来ていない事が原因

私なら、(2), (3) も (1)の対象範囲として"{}" の中に書くか、
別途、変数を用意して、if文の外に置いて使う。


[追記1]

失礼ですが、「参考に」というのが誤解を生んでしまいました、参考というよりかは、実際の作り方を見てこの場合はこうやる、この関数を使うと何々ができる、というのを学ぶのがが目的でした。

基礎はできています。

あ、そっちですか。それなら上での発言は言い過ぎましたね。
初心者~中級者ぐらいの人はそういう勉強方法もありっちゃアリですが、やっぱり良くないと思います。

関数とかの使い方とかは公式リファレンスを参考にすべきです。
とはいえ、C言語やC++の公式リファレンスってのは無いようなので、有志が作ったものになりますが。
たとえば cppjpとかがありますね。

for文の後ろに{}をつけるのは常識だと思っていました。

常識っていうか、これがデフォです。一行だけの場合、ブロックを明示しなくてもわかるので、省略がされがちなだけです。

ですが、その動画ではfor文に{}を付けずにPythonのようにインデントでやっていました。

インデントっていうか、それっぽく見えただけでは?

その動画は見ていませんが、おそらく、コンパイルはしていないのでは? (動画内で)
その手の動画を見るのなら、ざっくりと見るか、コンパイル(ビルド)しているのも含まれている前提ですね。私なら。

if文も、命令文が一つならインデントでできますが今回の場合、命令文が1つ以上なのに{}を付けなかったのが原因ですよね。

つまり、BeatStarさんの{}を省略して書くと・・・の場合、tempの定義はできますがあとの2つは
スコープ外になってエラーになるということですね。

YES. 一応、

int a = 1; int tmp = 2; if( a == 1 ) tmp = 10; int b = a * tmp;

とかみたいな感じでブロックの外に変数宣言を出して……であれば可能です。

投稿2021/09/21 12:29

編集2021/09/23 05:46
BeatStar

総合スコア4958

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

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

gift-0618

2021/09/22 14:14

失礼ですが、「参考に」というのが誤解を生んでしまいました、参考というよりかは、実際の作り方を見てこの場合はこうやる、この関数を使うと何々ができる、というのを学ぶのがが目的でした。 基礎はできています。 for文の後ろに{}をつけるのは常識だと思っていました。 ですが、その動画ではfor文に{}を付けずにPythonのようにインデントでやっていました。 if文も、命令文が一つならインデントでできますが今回の場合、命令文が1つ以上なのに{}を付けなかったのが原因ですよね。 つまり、BeatStarさんの{}を省略して書くと・・・の場合、tempの定義はできますがあとの2つは スコープ外になってエラーになるということですね。
gift-0618

2021/09/22 14:17

あともう一つ、誤字ってましたね・・・すみません。 「int temp にboard[省略][省略]を書き込もうとしてもtempが定義されていませんとエラーが出ます。」 ではなく、boardにtempを書き込むでした(エラーが出るのは)
BeatStar

2021/09/23 04:39 編集

本文に書きますね。
fana

2021/09/23 05:25

(互いに話が通じているようなので余計かとは思いますが) 細かい文言が気になります. > "{}"を省略すると一行が対象になるのです。 (これは他の方の回答のコメント欄にリンクが示されていますが)括弧を書かない状態が「省略系」なのではありません. また,「一行」と言うと語弊があるのではないでしょうか(C/C++はマルチステートメント可なのですし). > インデントでできますが インデントには何の効力もありません.
fana

2021/09/23 05:26

あと,至極どーでもいいことなのですが, > とりあえず「C言語 for文」とかで検索してみてください これ,何で for だったのでしょう? (問題のコードは if なのに. ifだと検索結果がイマイチとかそういう理由?)
BeatStar

2021/09/23 05:37 編集

@ fanaさん 確かにそうですね。(ざっと読んだだけだったみたいです…) 修正します。
guest

0

ベストアンサー

diff

1-if (holding) 2+if (holding) { 3 int temp = board[cursorPos.y][cursorPos.x]; 4 board[cursorPos.y][cursorPos.x] = board[lastCursorPos.y][lastCursorPos.x]; 5 board[lastCursorPos.y][lastCursorPos.x] = temp; 6+ }

投稿2021/09/21 12:17

SHOMI

総合スコア4079

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

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

gift-0618

2021/09/21 12:22

ありがとうございます! if文には波括弧が必要なのでしょうか?
gift-0618

2021/09/22 13:58

thkanaさん、ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問