C# フィールド変数とブロックスコープの学習資料
C# のプログラムをしっかり理解するには、フィールド変数のスコープだけでなく、ブロックスコープについても学ぶ必要があります。
この資料では、フィールド変数のスコープとブロックスコープの違いを解説し、具体例と練習問題を用意しました。
1. スコープとは?
スコープとは、変数が有効な範囲(アクセスできる範囲)のことです。
C# では、変数のスコープには大きく以下の4種類があります。
種類 | スコープ(有効範囲) |
---|---|
フィールドスコープ | クラスのすべてのメソッド内で有効 |
メソッドスコープ | メソッド内でのみ有効 |
ブロックスコープ | {} で囲まれたブロック内でのみ有効 |
静的(static )スコープ | クラス全体で1つの値を保持し、インスタンス間で共通 |
2. フィールド変数のスコープ
フィールド変数(メンバ変数)は、クラス内のすべてのメソッドでアクセス可能ですが、アクセス修飾子によって制限できます。
サンプルコード
using System;
class Person
{
// フィールド変数(クラス内のどこでもアクセス可能)
private string name;
public int age;
public void SetName(string newName)
{
name = newName; // フィールド変数を変更
}
public void ShowInfo()
{
Console.WriteLine($"名前: {name}, 年齢: {age}");
}
}
class Program
{
static void Main()
{
Person p = new Person();
p.age = 30;
p.SetName("太郎");
p.ShowInfo(); // 名前: 太郎, 年齢: 30
}
}
ポイント
✅ name
は private
なので Program
から直接アクセス不可。
✅ SetName()
を使って name
を変更できる。
✅ age
は public
なので、Program
から直接アクセス可能。
3. ブロックスコープとは?
ブロックスコープとは、{}
で囲まれた範囲内でのみ有効な変数のスコープです。
ループや条件分岐、メソッド内部の {}
で定義された変数は、そのブロック内でのみ使えます。
サンプルコード
using System;
class Program
{
static void Main()
{
int x = 10;
{
int y = 20;
Console.WriteLine(x); // OK(外のスコープの変数は使える)
Console.WriteLine(y); // OK
}
// Console.WriteLine(y); // エラー(y はブロック外なので使えない)
}
}
ポイント
✅ y
は {}
内で定義されたので、その外では使えない。
✅ x
は Main()
の中で定義されたので、ブロックの内外で使える。
4. for
ループのスコープ
for
ループ内で定義された変数は、そのループの中でのみ有効です。
サンプルコード
using System;
class Program
{
static void Main()
{
for (int i = 0; i < 3; i++)
{
Console.WriteLine(i);
}
// Console.WriteLine(i); // エラー(i は for ループのブロック内だけで有効)
}
}
ポイント
✅ i
は for
ループの {}
内でしか使えない。
✅ i
をループの外でも使いたい場合は、外で宣言する必要がある。
外で使いたい場合の修正
using System;
class Program
{
static void Main()
{
int i; // ループの外で宣言
for (i = 0; i < 3; i++)
{
Console.WriteLine(i);
}
Console.WriteLine($"ループの後の i: {i}"); // OK
}
}
✅ i
をループの外で宣言すると、ループ後も使用可能になる。
5. if
や while
でのブロックスコープ
if
文や while
文の {}
で定義された変数は、その中でのみ使えます。
サンプルコード
using System;
class Program
{
static void Main()
{
if (true)
{
int num = 100;
Console.WriteLine(num); // OK
}
// Console.WriteLine(num); // エラー(num は if のブロック内のみ有効)
}
}
✅ num
は if
文の {}
内でのみ使える。
6. フィールド変数とブロックスコープの違い
スコープ | 有効範囲 | 特徴 |
---|---|---|
フィールド変数 | クラス全体 | クラスのすべてのメソッドからアクセス可能 |
ローカル変数(メソッドスコープ) | メソッド内 | メソッドが終了すると消える |
ブロックスコープ | {} 内のみ | {} の外では使えない |
static 変数 | クラス全体 | インスタンス間で共通の値を持つ |
7. 練習問題
Q1. 次のコードの出力を予想してください
using System;
class Sample
{
int num = 10;
void Show()
{
int num = 20;
Console.WriteLine(num);
}
static void Main()
{
Sample s = new Sample();
s.Show();
}
}
10
20
エラーになる
コンパイルできない
Q2. for
ループの後に i
を使うとエラーになるのはなぜ?
i
はstatic
変数ではないからi
はfor
ループのブロックスコープ内にあるからi
はreadonly
だからfor
の外にi
が宣言されていないから
Q3. 次のコードはエラーになりますか?
using System;
class Program
{
static void Main()
{
{
int x = 10;
}
Console.WriteLine(x);
}
}
10
が表示されるエラーになる
何も表示されない
プログラムが停止する
8. まとめ
✅ フィールド変数 → クラス全体でアクセス可能
✅ ローカル変数 → メソッド内でのみ有効
✅ ブロックスコープ → {}
内でのみ有効
✅ static
変数 → クラス全体で1つの値を共有
これで、フィールド変数とブロックスコープをしっかり理解できます!
7. 練習問題(模範解答&解説付き)
Q1. 次のコードの出力を予想してください
using System;
class Sample
{
int num = 10;
void Show()
{
int num = 20;
Console.WriteLine(num);
}
static void Main()
{
Sample s = new Sample();
s.Show();
}
}
✅ 正解:
2. 20
解説
num
はSample
クラスのフィールド変数(インスタンス変数)として10
で初期化されている。Show()
メソッド内のnum
は、ローカル変数として宣言されており、20
に設定されている。- ローカル変数のスコープは、メソッド内に限定されるため、メソッド内の
num
が優先される。
したがって、Show()
を実行すると 20
が表示される。
Q2. for
ループの後に i
を使うとエラーになるのはなぜ?
using System;
class Program
{
static void Main()
{
for (int i = 0; i < 3; i++)
{
Console.WriteLine(i);
}
Console.WriteLine(i); // ここでエラー
}
}
✅ 正解:
2. i
は for
ループのブロックスコープ内にあるから
解説
i
のスコープはfor
ループの{}
内 に限定される。- したがって、ループが終了した後には
i
は無効になり、エラーが発生する。 - 修正方法:
i
をfor
の外で宣言する。
using System;
class Program
{
static void Main()
{
int i; // ループの外で宣言
for (i = 0; i < 3; i++)
{
Console.WriteLine(i);
}
Console.WriteLine($"ループの後の i: {i}"); // OK
}
}
✅ この修正により、i
は for
ループの外でも有効になり、エラーが解消される。
Q3. 次のコードはエラーになりますか?
using System;
class Program
{
static void Main()
{
{
int x = 10;
}
Console.WriteLine(x);
}
}
✅ 正解: 2. エラーになる
解説
- 変数
x
は{}
内で宣言されており、ブロックスコープが適用される。 - ブロック
{}
を抜けるとx
は無効になり、Console.WriteLine(x);
でエラーが発生する。 - 修正方法:
x
をブロックの外で宣言する。
using System;
class Program
{
static void Main()
{
int x; // ブロックの外で宣言
{
x = 10; // ブロック内で代入
}
Console.WriteLine(x); // OK
}
}
✅ この修正により、x
は Main()
内のどこでも使えるようになり、エラーが解消される。
ディスカッション
コメント一覧
まだ、コメントがありません