C#の配列の定数の問題について

このQ&Aのポイント
  • C#の配列の定数に関して、VS2013でのコーディングでエラーが発生してしまいます。解決方法を教えてください。
  • フォームに設置したボタンのテキストを、あらかじめ定義したテーブルから表示したいですが、思ったような結果になりません。C#ならどのようにコーディングすればよいでしょうか。
  • 現在テスト段階であり、2列定義しているにもかかわらず、1列しか表示されません。問題の原因と解決方法を教えてください。
回答を見る
  • ベストアンサー

C#の配列の定数

BCCを使用していたのですが、最近VS2013でC#を勉強し始めました フォームの指定した位置にいくつかのボタンを設置し、あらかじめ定義しておいた テーブルからボタンのtextを表示したいと思い、以下のようにコーディングしたのですが エラーが出てしまい思ったような結果に持って行くことができません C#ならこうした方がいいという指摘も含めて どうやるのがいいのか ご教授ください 足りない情報があれば追加します ちなみにまだテスト段階だから2列定義して1列しか表示するようにしかなってません ----------------------------------------------------------------------- using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace haneda { public partial class Form1 : Form { private Button[] buttons; public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { int i; //ボタンコントロール配列の作成 this.buttons = new Button[table.MAX_R]; for (i = 0; i < buttons.Length; i++) { //ボタンコントロールのインスタンス作成 this.buttons[i] = new Button(); //プロパティ設定 this.buttons[i].Name = "btn" + i.ToString(); this.buttons[i].Text = table.roomNo[1, i]; <=ここがエラー this.buttons[i].Top = table.roomX01[i]; <=ここがエラー this.buttons[i].Left = table.roomY01[i]; <=ここがエラー this.buttons[i].Click += new System.EventHandler(button_Click); //コントロールをフォームに追加 this.Controls.Add(this.buttons[i]); } } private void button_Click(object sender, System.EventArgs e) { Button btn = (Button)sender; MessageBox.Show(btn.Name); } } public class define { public const bool IGNORE = false; //非表示 public const bool EFFECT = true; //表示 /* 最大値 */ public const int MAX_F = 2; //フロア数 public const int MAX_R = 3; //ルーム数 } public class table { /* ナンバー */ public readonly string[,] roomNo = new string[define.MAX_F, define.MAX_R] { { "101", "102", "103"}, { "201", "202", "203"} } /* 表示・非表示 */ public readonly bool[,] effectRoom = new bool[define.MAX_F, define.MAX_R] { {EFFECT, IGNORE, EFFECT}, {EFFECT, EFFECT, EFFECT} } public readonly int[] roomX01 = new int[define.MAX_R] { 5, 70, 135 } public readonly int[] roomY01 = new int[define.MAX_R] { 100, 100, 100 } } }

質問者が選んだベストアンサー

  • ベストアンサー
  • wormhole
  • ベストアンサー率28% (1622/5659)
回答No.3

>として初めて中身を入れることができるようになるので >そこから中身をセットしないとできないよ >ということですかね? そうです。 ただ#2で書いてる事の半分だけですね。 インスタンスメンバーとクラスメンバーが、それぞれどういったものなのか理解された方がよろしいかと思います。 これはC#に限らずC++,Javaなども同じですし。

condor2
質問者

お礼

インスタンスメンバー、クラスメンバーについて 勉強してみます そうしないと先に進めなそうな感じがするので (^^; ありがとうございました

その他の回答 (2)

  • wormhole
  • ベストアンサー率28% (1622/5659)
回答No.2

>エラー内容は「静的でないフィールド、メソッド、またはプロパティ。。。。オブジェクト参照が必要です」というエラーです このメッセージの意味は理解してますか? エラーの原因は、このメッセージに書かれてる通りなんですけど。 roomNo roomX01 roomY01 は、tableクラスのインスタンス(オブジェクト)のメンバ変数(readonlyは読み取り専用変数で定数ではないです)ですから、tableクラスのインスタンスなしにはアクセスできません。 ですのでstaticを付けて静的変数にするかtableクラスのインスタンスを作るかなりしてください。

condor2
質問者

お礼

返事が遅くなりすみません。 ご回答ありがとうございます Form1_Loadで table tbl; tbl = new table(); として初めて中身を入れることができるようになるので そこから中身をセットしないとできないよ ということですかね?

  • wormhole
  • ベストアンサー率28% (1622/5659)
回答No.1

>this.buttons[i].Text = table.roomNo[1, i]; <=ここがエラー >this.buttons[i].Top = table.roomX01[i]; <=ここがエラー >this.buttons[i].Left = table.roomY01[i]; <=ここがエラー 単純にエラーと書かれていますけど、エラーメッセージは「エラー」としか書かれていなかったんですか? とりあえず https://msdn.microsoft.com/ja-jp/library/aa645629%28v=vs.71%29.aspx を参照してください。

condor2
質問者

補足

ご指摘ありがとうございます エラー内容は「静的でないフィールド、メソッド、またはプロパティ。。。。オブジェクト参照が必要です」というエラーです

関連するQ&A

  • テーブル配列の中身、出力値

    お世話になっております。 C言語勉強中のものです。 一定のひもをランダムに切断し、その長さを測ろうと思っています。 前回アドバイスを頂き、ソートを使って書いてみたのですが、詰まる部分があったのでご指導いただきたいと思いました。 #include <stdlib.h> #include <string.h> #include <stdio.h> #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))   int GetRandom(int min, int max);   int compare_int(const void* a, const void* b);   int compare_str(const void* a, const void* b); int main(void) {   int int_table[] = {GetRandom(0,10000)};   int i;   qsort( int_table, ARRAY_SIZE(int_table), sizeof(int), compare_int );   for( i = 0; i < ARRAY_SIZE(int_table); ++i ) {     printf("%d\n",int_table[i] ); }   return 0; } int compare_int(const void* a, const void* b) {   return ( *(int*)a - *(int*)b ); } int GetRandom(int min, int max) {     return min + (int)(rand()*(max-min+1.0)/(1.0+RAND_MAX)); } 【困っている箇所】 ・int int_table[]={} の中身に次のようなものを入れることで、ランダムに切ったひもを、ソートできると考えているのですが、その方法を色々ためしましたが上手くいきませんでした。このようなやり方で良いのか、その場合どのようにしたら良いか、また違うのかを教えていただきたいです。 for(i=0;i<10;i++) { printf("%d\n",GetRandom(0,10000)); } ・また最終的にソートしたものを比較させようと思っています。 「出力値を保存する方法」が分からないので教えて頂きたいです。 ----前回ご覧になってくださった方へ---- アドバイスありがとうございました。 まだ初心者ですが、色々ご教授下さるとうれしい限りです。

  • C++のクラス内での2次元配列

    C++学習者です。Windows 10上で、Visual Studio Community 2015 を使って勉強しています。 2次元配列を持つクラスを作ろうとしていますが、クラス定義ファイルの中のプライベート変数部分に2次元配列を定義しようとするとエラーメッセージが出てきます。 自分のソースコードは次のようなもので、最後の int aray[rowSize][colSize]; の部分に赤い波線が出ていて、そこにカーソルを合わせると「静的でないメンバー参照は特定のオブジェクトを基準とする相対参照である必要があります。」というメッセージが出ます。 #pragma once #ifndef DSUBARRAY_H // Double Subscripted Array #define DSUBARRAY_H #include <iostream> using namespace std; class DsubArray { public: friend ostream &operator<<(ostream &, const DsubArray &); // output array friend istream &operator>>(istream &, DsubArray &); // input array DsubArray(const int=1, const int=1); // default constructor DsubArray(DsubArray &); // copy constructor ~DsubArray(); // destructor int &operator()(int, int);// subscript -- lvalue const int &operator()(int, int) const; // subscript -- rvalue DsubArray &operator=(DsubArray &);// assignment bool operator==(DsubArray &) const; // equality check of the two arrays bool operator!=(DsubArray &) const; // inequality check int getRowSize() const; int getColSize() const; private: int rowSize; int colSize; int aray[rowSize][colSize]; }; #endif これをたとえば次のように書き換えると、赤い波線は消えるのですが、今度はコラムのサイズが10に固定されてしまい、コンストラクターでこれと異なる数値を与えるとエラーになってしまうのではないかと心配します。 int aray[ ][10]; どなたか2次元配列の正しい作り方を教えてください。お願いいたします。

  • define で 配列

    #defineで配列を定義したいのですがこのようなことは可能でしょうか? ヘッダファイル(test.h)で #define MAX (2) int A[MAX]={20,30}; ソースファイルで #include <stdio.h> #include "test.h" int main(){ int i; for(i=0;i<MAX;i++){ printf("A[%d]=%d\n",i,A[i]); } return 0; } とやれば出来るのですが、このヘッダファイルを複数のソースで参照すると 多重定義であるとおこられてしまいます。 #defineで #define A[MAX] {20,30} のように配列を定義する方法は存在するのでしょうか? どなたか良い方法を御存じの方、ご教授お願いします。

  • C# タスクバーを隠したフォーム固定の方法

    前略 ・C#の初心者です。 ・先日このMSN相談箱でtsukasa-12rさんからタスクバーを非表示する下記のプログラムをおしえていだきました。 このプログラムでウィンドウフォームを固定しようとして this.FormBorderStyle = FormBorderStyle.FixedSingle; のコードを1行だけ追加しましたがウィンドウフォームを固定できませんでした。  タスクバーを隠して かつウィンドウフォームを固定したいのですが tsukasa-12rさん以外の方でもかまいませんのでどなたか教えてください。  以上、よろしくお願いします //----------------------------------- using System; using System.Drawing; using System.Runtime.InteropServices; using System.Windows.Forms; namespace WindowsFormsApplication1 { public partial class Form1 : Form { [DllImport("user32.dll", SetLastError = true)] static extern IntPtr FindWindow(string lpClassName, IntPtr lpWindowName); [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); private const int SW_HIDE = 0; private const int SW_NORMAL = 1; [StructLayout(LayoutKind.Sequential)] struct APPBARDATA { public int cbSize; public IntPtr hwnd; public uint uCallbackMessage; public uint uEdge; public Rectangle rc; public int lParam; }; private const int ABM_SETSTATE = 10; private const int ABS_AUTOHIDE = 1; private const int ABS_ALWAYSONTOP = 2; [DllImport("shell32.dll")] static extern int SHAppBarMessage(int msg, ref APPBARDATA pbd ); public Form1() { InitializeComponent(); // 「タスクバーを自動的に隠す」 APPBARDATA abd = new APPBARDATA(); abd.cbSize = Marshal.SizeOf(abd); abd.lParam = ABS_AUTOHIDE; SHAppBarMessage(ABM_SETSTATE, ref abd); // タスクバーを非表示 ShowWindow(FindWindow("Shell_TrayWnd", IntPtr.Zero), SW_HIDE); // コントロールボックスを非表示 this.ControlBox = false; // 最大表示 this.WindowState = FormWindowState.Maximized; this.FormBorderStyle = FormBorderStyle.FixedSingle;// ← ウィンドウサイズを固定しようとして追加 → 固定できず } private void button1_Click(object sender, EventArgs e) { // タスクバーを常に表示 APPBARDATA abd = new APPBARDATA(); abd.cbSize = Marshal.SizeOf(abd); abd.lParam = ABS_ALWAYSONTOP; SHAppBarMessage(ABM_SETSTATE, ref abd); // タスクバーを表示 ShowWindow(FindWindow("Shell_TrayWnd", IntPtr.Zero), SW_NORMAL); // フォームを閉じる this.Close(); } } }

  • BackgroundWorkerについて(C#)

    C#でBackgroundWorkerを使ったプログラムを試しています。 Windows Form上にButtonとProgressBarを設置して以下のプログラムを 動作させると、プログレスバーが終了するまえに”終了”が出てしまいますが これはどうしてでしょうか? よろしくお願いいたします。 using System; using System.ComponentModel; using System.Threading; using System.Windows.Forms; namespace WindowsFormsApplication1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { button1.Enabled = false; Random rand = new Random(); BackgroundWorker bgWorker = new BackgroundWorker(); bgWorker.DoWork += ((sender2, e2) => { for (int i = 0; i < 10; i++) { Thread.Sleep((int)(rand.NextDouble() * 500)); bgWorker.ReportProgress((i + 1) * 10); } }); bgWorker.RunWorkerCompleted += ((sender2, e2) => { button1.Enabled = true; bgWorker.Dispose(); MessageBox.Show("終了"); }); bgWorker.ProgressChanged += ((sender2, e2) => { progressBar1.Value = e2.ProgressPercentage; }); bgWorker.WorkerReportsProgress = true; bgWorker.RunWorkerAsync(); } } }

  • C#でオブジェクトの配列を使う

    開発環境はMicrofoft visual stdio 2005 で開発言語はC#を使い、Windousアプリケーションでプログラミングしているのですが オブジェクトを配列でせんげんし、オブジェクトのメンバを使うとエラーが出てしまいます。ソースコードで説明すると using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; namespace WindowsApplication1 {   public partial class Form1 : Form   {     public class car     {       int a;       public void set(int i)       {         a = i;       }     }     public Form1()     {       InitializeComponent();     }     private void label1_Click(object sender, EventArgs e)     {       car[] bike = new car[1];       bike[0].set(1);//ここでひっかかる     }   } } これをじっこうするとデバックは通るのですが、label1_Clickイベントが発生すると、「NULLの場所を参照しています」という意味のエラーが出てしまいます。 C#はほとんど初心者なので、初歩的なミスだとおもうんですが、 よろしければ御回答をお願いします。

  • ○×ゲーム

    ○×ゲーム ○×ゲームをつくろうとしてるのですがどうプログラムを組んでいいのか分りません。ポインタとクラスを使って作りたいのですがどなたか教えていただけないでしょうか。 途中までのプログラムを載せておきます。ここからどうすればいいのか教えてください。 #include<iostream> #include<cstdlib> #include<ctime> #define NON 0 #define MARU 1 #define BATU 2 #define MAX_HEIGHT 3 #define MAX_WIDTH 3 using namespace std; int g_mas[MAX_WIDTH][MAX_HEIGHT]; class Game{ public: void Clear(); void Player(int *width, int *height); bool Draw(); } void Game::Clear() { for(int width=0; width<MAX_WIDTH; width++) { for(int height=0; height<MAX_HEIGHT; height++) { g_mas[MAX_WIDTH][MAX_HEIGHT] = NON; } } } void Game::Player(int width, int height) { } bool Game::Draw() { for(int width=0; i<MAX_WIDTH; width++) { for(int height=0; i<MAX_HEIGHT; height++) { if(g_mas[MAX_WIDTH][MAX_HEIGHT] == NON) { return 0; //引分けじゃない時、0を返す } } } return 1; //引分けだった時、1を返す } int main() { int width, height; Game g; g.Clear(); srand((unsigned int)time(NULL)); }

  • クイックソート

    #include<stdio.h> #include<stdlib.h> #define MAX 10 int comp(const void *i,const void *j); int main(void) { int sort[MAX], i ; for(i=0 ; i<MAX ; i++){ sort[i] = rand(); } qsort(sort, MAX, sizeof(int), comp); for( i=0; i<MAX ; i++) printf("%d\n", sort[i]); return 0; } int comp (const void *i, const void *j) { return *(int*)i - *(int*)j; } これはクイックソートのプログラムなのですが、 int comp (const void *i, const void *j) { return *(int*)i - *(int*)j; } この部分がわかりません。ここでソートしているのですか?

  • Visual C++ 2008 EEでボタンの判定、結果を配列に格納

    OSはXPでViaual C++ 2008 Express EditionのWindowsフォームアプリケーションにて一つのフォームで全132問に答えるというものを作成しています。フォームには[戻る]、[次へ進む]、[チェック除外]ボタンと「はい」、「いいえ」、「どちらでもない」のラジオボタン、問題文とタイマーのラベル、テキストボックス(問題番号を入力すると[戻る]ボタンが[移動]ボタンに変わり、入力した問題に進む)があります。最初に変数qに1を入れ、[次へ進む]を押すとqに1がプラスされswitch文で2問以降に進む(ラベルのみ切り替わる)というもので、最後の問題に行くと[次へ進む]ボタンが[終了]ボタンに変わります。ただし、全ての問題に解答していなければ終了できないようにしています。この解答結果をCSVに(はいなら1、いいえなら2、どちらでもないなら3)出力したいと考えているのですが、ラジオボタンにチェックを入れ、[次へ進む]ボタンを押したときのみ「インデックスが配列の境界外です」というエラーが表示されてしまいます。コードは以下の通りですが、どこを直せばよいのか分からないのでご教授願います。 private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) { endflag = 0; this->button2->Text = "次へ進む"; if(flag == 1){ q = jump; flag = 0; this->button1->Text = "戻る"; this->textBox1->Text = ""; }else{ q--; } if(q == 1){ this->button1->Enabled = false; } switch(q){ case 1:                          ・                          ・                          ・                          case 132                           endflag = 1; break; }                            }: private: System::Void button2_Click(System::Object^ sender, System::EventArgs^ e) { String^ s = rtrstrg(); if(endflag == 1){ if(s == "") { MessageBox::Show("全ての質問に答えて下さい。","エラー"); } else if(MessageBox::Show("終了しますか?", "確認", MessageBoxButtons::OKCancel, MessageBoxIcon::Question) == System::Windows::Forms::DialogResult::OK) { this->Close(); } } q++; this->button1->Enabled = true; switch(q){ case 2:                      ・                      ・                      ・                      case 132                       endflag = 1;    break; }                      }: private: System::Void button3_Click(System::Object^ sender, System::EventArgs^ e) { this->radioButton1->Checked = false; this->radioButton2->Checked = false; this->radioButton3->Checked = false; } private: System::Void chg(System::Object^ sender, System::EventArgs^ e) { bool result = int::TryParse(textBox1->Text, jump); if(jump > 0 && jump <= 132){ if(jump != q){ this->button1->Text = "移動"; this->button1->Enabled = true; flag = 1; } } else{ textBox1->Text = ""; this->button1->Text = "戻る"; flag = 0; } } private: System::String^ rtrstrg() { String^ s; for(int i=1; i<=QSTNB; i++) { s += this->rtrdt(i); if(s->EndsWith("×")) { return ""; } } return s->Remove(s->Length - 1); } private: System::String^ rtrdt(int qstn) { //配列の宣言 array<RadioButton^>^ arb = gcnew array<RadioButton^>(SZBH); for(int i=0; i<SZBH; i++) { arb[i] = dynamic_cast<RadioButton^>(this->Controls->Find("radioButton"+(qstn*SZBH-SZBH+1+i), true)[0]); } return this->chck(arb); } private: System::String^ chck(array<RadioButton^>^ arb) { for(int i=0; i<arb->Length; i++) { if(arb[i]->Checked == true) { return i + 1 + ","; } } return "×"; }

  • 配列で最大・最小値を求める

    import java.io.*; class Prog10_2 { public static void main(String args[])throws IOException { System.out.println("10個の整数を入力してください。"); BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); int num[] = new int[10]; for(int i=0; i<num.length; i++){ String str = br.readLine(); int tmp = Integer.parseInt(str); num[i] = tmp; } int max = 0; int min = 0; for(int i=0; i<num.length; i++){ if(max < num[i]){ max = num[i]; } if(min > num[i]){ min = num[i]; } } System.out.println("最大値は"+max+"で、最小値は"+min+"です。"); } }   というコマンドを実行すると、最大値はちゃんと表示されるのですが、 最小値はいつも"0"しか表示されません。どこを修正すればいいのでしょうか? どなたか分かる方いらっしゃいましたら、よろしくお願いします。

    • ベストアンサー
    • Java