- 変数が何かぜんぜんわからない
- 「変数=箱」っていわれてもよくわかりません!
- データ型とかスコープって何?
この記事では、プログラミングにおける変数をわかりやすく解説します。
1. 変数とは?
プログラミングにおける変数とは「データにつけるラベル」のことです。
詳しく説明します。
変数とは
プログラミングではデータを扱います。
データは数字や文字などです。
プログラミングとは、コンピュータがデータを受け取ったときに、それを決まったルールで計算するように命令をすることです。
そのルールを作るのがプログラミングです。
たとえば、計算機をプログラミングするには「1」→「+」→「1」→「=」とボタンが押されたときに「1 + 1」を計算して返すようにルールを作らなくてはいけません。
「2」→「+」→「3」 →「=」と押されたら「2 + 3」を計算します。
このようなルールをつくるにはどのようにすればよいでしょうか?
そのためには、計算機のボタンが押されたときに、押された数字を覚えておく必要があります。
「2」というボタンが押されたら、それを一時的に覚えておきます。それから「3」というボタンが押されたら、それも覚えておきます。最後に「=」のボタンが押されたら、覚えていた2つの数字(「2」と「3」)を合計します。
このように、押された数字を覚えておくために使うのが「変数」です。
JavaScriptで変数を使わずに「2+3」を計算するには、以下のように書きます。
console.log(2 + 3);
しかし、これでは「2+3」の計算しかできません。
計算機のボタンを押して、ユーザーの操作によって異なる数字で計算することはできません。
必要なのは「押された2つの数字を覚えておいて」合計することです。
ここで変数を使います。
let a = prompt(); // aが変数
let b = prompt(); // bが変数
console.log(Number(a) + Number(b)); // a と b を足す
これでユーザーから入力を受け付けて、入力された数字を足すことができます。
変数を使えば、最初に受け取った数字をa,次に受け取った数字をbとして、名前をつけて覚えておくことができます。
このように変数とは、あるデータを一時的に覚えておくための保管庫であり、それを思い出すためのラベルなのです。
変数はどのように使われるのか?
変数は「あるデータを一時的に覚えておくための保管庫であり、それを思い出すためのラベル」であると説明しました。
変数を使えば、数値や文字列などのデータを一時的に名前をつけて保存し、あとで使うことができます。
ここで、変数はどのように使われるのかを理解するため、3つの例を紹介しましょう。
- データの一時的な保存領域としての変数
- データに名前をつけてコードを読みやすくする手段としての変数
- for文の繰り返し回数の記録としての変数
1. データの一時的な保存領域としての変数
変数はデータを一時的に記憶するために使われます。以下は計算の前段階で数値データを記憶する例です。
let a = 100;
let b = 200;
let answer = a + b;
console.log(answer);
2. データに名前をつけてコードを読みやすくする手段として
変数にはデータにつけるラベルとしての側面があります。
以下の例はJavaScriptを使ってexample.comにアクセスする例です。
// example.comにリダイレクトするコード
window.location.href("https://example.com");
このコードに問題はありませんが、以下のように変数を使うことで、プログラムの意図を理解しやすくなります。
let url = "https://example.com"; // 変数として宣言する
window.location.href(url); // 変数名があるとurlが渡されていることがわかりやすい
URLである文字列データをurlという変数に代入しました。これによって、このコードがurlを使うものであることがはっきりします。
次の例では、コードの内容をより理解しやすくするため、関数化を行っています。
// 処理を関数化したときも変数がついていれば柔軟に使える
function redirect(url) {
window.location.href(url);
}
let urlCom = "https://example.com";
redirect(urlCom);
let urlNet = "https://example.net";
redirect(urlNet); // 引数を変えるだけで異なるURLにアクセスできる
ここでも変数urlを導入したことで関数の引数に与えるべきデータが明確になりました。また、関数名をredirectとしたことで、コードの役割がはっきりとわかるようになりました。
このように、変数を使うことでデータに名前がついて、どんなデータを使っているのかが明確になります。
このように「データの命名」のために変数を使うこともあります。
3. for文の繰り返し回数の記録として
for文の繰り返し回数の記録にも変数が使われます。以下は標準的なfor文のコードです。
変数iがfor文の繰り返し回数を記録するのに使われています。
for (let i = 0; i < 10; i++) { // iが変数(繰り返した回数)
console.log(i);
}
for文の書き方についてはプログラミングのfor文とは?30分でマスターできるわかりやすい解説を参照してください。
2. 変数の宣言
ここからは変数の使い方を説明します。
変数宣言
変数は使う前に宣言する必要があります。以下が変数を宣言するコードの一例です。
let x;
let y;
x = 100;
y = 200;
最初の2行で変数xとyを使うことを宣言しています。
変数は宣言してはじめて使えるようになります。
JavaScriptでは「let 変数名;」という形で変数を宣言できます。
後半の2行でそれぞれ100、200というデータに変数を割り当てています。
このように変数とデータを=でつないで関連付けることを「値を代入する」といいます。
変数に関連付けるデータを「値」といいます。
ここでは変数xに値「100」を、変数yに値「200」を代入しています。
変数を宣言すると同時に代入する
変数を宣言するとき、同時に値を代入することもできます。
これを宣言代入といいます。変数を宣言するとともに値を代入するからです。
let x = 100;
let y = 200;
ここでは変数xを宣言するとともに値「100」を代入し、変数yを宣言するとともに値「200」を代入しています。
宣言代入はプログラミングでは頻繁使われます。変数を宣言だけする場合よりも、宣言とともに値を代入する場合の方が多いかもしれません。
変数の値の取得
変数に代入した値は後から取り出すことができます。
変数から値を取得するには変数名を使います。
let x = 100;
// 変数xの値を取り出す
console.log(x); // 100
ここでconsole.log()はコンソールに出力するための関数です。変数xに代入された値である「100」が取り出せていることがわかります。
また、ある変数に入れた値を別に変数に代入してコピーすることもできます。
let x = 100;
let y = x; // 変数yに変数xを代入する
console.log(y); // 100
この例では、変数xに値「100」を代入した後、変数xを変数yに代入しています。
これで変数xの値が変数yにコピーされます。
変数の上書き
変数は値を上書きすることもできます。変数は文字通り「変わる数」です。
変数はデータにひもづいているラベルにすぎないので、もう一度別の値を代入すれば、その値にラベルを移動できます。
ラベルを貼り直すイメージですね。
このように変数に値を代入して上書きすることを「再代入」といいます。
let x = 100;
let y = 200;
console.log(x + y); // 300
x = 200; // 上書き。letは不要
console.log(x + y); // 400
ここでは変数xを宣言代入したあと、値「200」を再代入しています。
これによって値が書き換わり、計算結果も変わっていることがわかります。
定数
変数は宣言代入をした後、値を書き換えることができます。値を書き換えられないようにするには、定数を使います。
const x = 100; // 定数として宣言代入
const y = 200; // 定数として宣言代入
console.log(x + y); // 300
// 上書きできない
x = 200; // TypeError: Assignment to constant variable.
JavaScriptでは「const 定数名 = 値;」と書くことで定数を宣言できます。
定数には値を再代入できません。
書き換える必要のない値を定数として宣言することは、コードの安全性を高めるうえで重要です。
変更する予定のない値は定数として宣言するとよいでしょう。
3. 変数の型
変数には「データ型」という概念があります。
データ型
データ型とは「コンピュータが変数のデータをどのように扱うべきか」を定義するものです。
「データ型」は単に「型」ということもあります。
データ型の詳細についてはプログラミングでデータ型を書く3つの理由で詳しく書いているので参照してください。
データ型の種類
ここでは一般的な変数の型を紹介します。
1. 数値型
数値型は、数値データを保持するためのデータ型です。
intやfloat, decimalなどがあります。
JavaScriptではNumber型が数値型にあたります。
let variable = 10;
console.log(typeof variable); // number
2. 文字列型
文字列型は、テキスト形式のデータを保持するためのデータ型です。
プログラミング言語によって様々ですが、str, string, Stringなどの表記があります。
JavaScriptではString型が文字列型にあたります。
let variable = "文字列";
console.log(typeof variable); // string
3. 論理型
論理型は、真(true)か偽(false)の2値を保持するためのデータ型です。
プログラミング言語によって様々ですが、bool, boolean, Booleanなどの表記があります。
JavaScriptではBoolean型が論理型にあたります。
let variable = true;
console.log(typeof variable); // boolean
4. void型
vodi型は、値が「ない」ことを意味するデータ型です。
プログラミング言語によって様々ですが、null、Null、None、nilなどの表記があります。
JavaScriptではnull値がvoid型に相当します。
let variable = null;
console.log(typeof variable); // object (注)
注)JavaScriptでnullはプリミティブデータ型とされていますが、実際にはプリミティブではなくobject型です。実務上はvoid型のように使われるためここではvoid型として紹介しています。
5. 配列型
配列型は、複数のデータをまとめて扱うためのデータ型です。
プログラミング言語によりますが、arrayやArrayなどと表記されます。
JavaScriptにもArray(配列)型が存在します。
let variable = new Array(10); // 空の要素を10個持つ配列を作成
console.log(variable); // (10) [empty × 10]
console.log(typeof variable); // object (注)
注)JavaScriptのArray型はオブジェクトとして実装されています。
6. 日付型
日付型は文字通り日付データを保持するためのデータ型です。日付だけでなく時間まで含む場合もあります。
プログラミング言語によりますが、Dateやdatetimeなどと表記されます。
JavaScriptではDateオブジェクトが日付型に相当します。
let variable = new Date();
console.log(variable); // Thu Mar 09 2023 20:00:00 GMT+0900 (日本標準時)
console.log(typeof variable); // object
変数の型についてのまとめ
データ型について詳しくはプログラミングでデータ型を書く3つの理由を参照してください。
4. 変数のスコープ
変数には、参照できる「範囲」の制限があります。
たとえば、if文の中で定義した変数はif文の外では使えません。
let x = 100;
if (x >= 1) {
let y = 200;
}
console.log(y); // ReferenceError: y is not defined
このように変数が参照できる範囲のことを「スコープ」といいます。
スコープには、広さが異なる3つの種類があります。
- グローバルスコープ
- ローカルスコープ
- ブロックスコープ
1. グローバルスコープ
グローバルスコープは、そのファイル内のどこからでも参照できる変数のスコープです。
グローバルスコープで定義されている変数を「グローバル変数」といいます。
以下はグローバルスコープの例です。
ファイル内のどこでも変数の値を参照できます。
let globalVariable = "これはグローバル変数です";
function exampleFunction() {
console.log(globalVariable); // これはグローバル変数です
}
exampleFunction();
関数の中でも、関数の外の変数の値を取得できていることがわかります。
2. ローカルスコープ
ローカルスコープは、関数の中で定義された変数が持つスコープです。
関数の中で定義された変数は、その関数の中でしか参照できません。
このような変数を「ローカル変数」といいます。
以下は、ローカル変数がその関数の外からアクセスできないことを示す例です。
function exampleFunction() {
let localVariable = "これはローカル変数です";
}
console.log(localVariable); // ReferenceError: localVariable is not defined
関数内で定義された変数を、関数の外で参照しようとするとエラーが出ることがわかります。
3. ブロックスコープ
ブロックスコープは、if文やfor文などで使用するブロック({})
の中で定義した変数のスコープです。
ブロック文({})
の中で定義した変数は、そのブロックの中でしか参照できません。
let x = 10;
{
let y = 10;
}
console.log(x); // 10
console.log(y); // ReferenceError: y is not defined
上記の例では、ブロック内で定義した変数yをブロック外から参照しようとしてエラーが出ています。
このようにブロック内で定義された変数のスコープを「ブロックスコープ」といいます。
※ただし、JavaScriptの変数のスコープは変数定義を「var」で定義したか「let」で定義したかによって異なります。また、strictモードによっても異なります。混乱を招くかもしれないため、ここでは説明しません。詳しくは公式ドキュメントを参照してください。
変数にスコープがある理由
変数に参照範囲の制限(スコープ)がある理由は、変数の命名を楽にするとともに、変数名の重複によるバグの発生を防ぐためです。
たとえば、ひとつのファイルにとても長いコードを書いたとき、変数名が重複してしまうことはよくあります。
let count = 0;
// ... (長いコード)
for (let count = 0; count < 100; count++) {
if (count % 2 == 0) {
// ...
}
}
// ... (長いコード)
function exampleCount(count) {
count += 1;
return count;
}
exampleCount();
上記では、ファイルの先頭でcountという変数名を多用しています。
もし、スコープがなかったら、どのcountがどこで宣言した変数かわからず、予期しないバグが発生します。
変数名が被らないようにすればいいのですが、その場合は変数名を考えるのが大変になります。
globalCount, countInFor, countInExampleFunctionなど、変数名が見づらくもなります。
スコープがあれば、関数内では関数内の変数だけを、ブロック内ではブロック内の変数だけを考えればよくなります。
このようにスコープには、変数名の設定を楽にするとともに、予期しないバグの発生を防ぐ役割があります。
5. 変数の命名規則
変数はデータに名前をつける役割があります。
変数名の重要性
データにどんな名前をつけるかは重要な問題であり、プログラマーとしての技量が問われるところです。
たとえば、以下のコードがそれぞれ何のための処理をしているコードなのかを考えてみてください。
let a = 1000;
let b = 7;
let c = a * b;
console.log(c);
わかりましたか?
では、次のコードはどうでしょう?
let price = 1000;
let amount = 7;
let sumOfTicketFee = price * amount;
console.log(sumOfTicketFee);
これならわかりますね。
チケットの料金の合計を計算しているコードです。
実は、どちらのコードもやっていることは同じです。
コンピュータ的には何も変わりません。
しかし、人間にとっては2番目のコードのほうが読みやすいですね。
このように変数の命名はとても重要なことなのです。
※エンジニアのコーディング面接で2人の候補者がそれぞれ上記のコードを書いたとしたら、間違いなく2つ目の「変数名がわかりやすい方」のコードを書いた人が採用されるでしょう。
命名規則
変数名には「命名規則」があります。
命名規則とは「変数名をつけるときのルール」です。
ここでは、変数の命名規則の例を紹介します。
キャメルケース
キャメルケース(camel case)は変数の命名法として代表的です。
キャメル(camel)とはラクダのことです。
ラクダのコブのように2単語目以降の先頭を大文字にします。
thisIsCameCase
キャメルケースの使用例
let exampleVariable = "この変数名はキャメルケースです";
パスカルケース
パスカルケースは変数名を構成するすべての単語の先頭を大文字にする命名法です。
アッパーキャメルケース(先頭の単語も先頭を大文字にしたキャメルケース)とも呼ばれます。
ThisIsPascalCase
パスカルケースは変数名よりも「クラス名」などに使われる場合が多いです。
パスカルケースの使用例
let ExampleVariable = "この変数名はパスカルケースです";
スネークケース
スネークケースは、変数名を構成する単語同士をすべて小文字で表記しつつ、アンダーバーで接続する命名法です。
プログラミング言語のPythonでは変数名の命名にスネークケースがよく使われます。
this_is_snake_case
スネークケースの使用例
let example_variable = "この変数名はスネークケースです";
アッパースネークケース(コンスタントケース)
アッパースネークケースは、スネークケースのように単語間をアンダーバーでつなぎ、単語を構成する文字をすべて大文字で表記する命名法です。
THIS_IS_UPPER_SNAKE_CASE
アッパースネークケースは、言語を問わず、定数の命名によく使われます。
アッパースネークケースの使用例
let EXAMPLE_VARIABLE = "この変数名はアッパースネークケースです";
ケバブケース(チェインケース)
ケバブケースは、変数名を構成する単語間をハイフンでつなぐ命名法です。
HTMLやCSSのプロパティの命名でよく使われます。
this-is-kebab-case
形が食べ物のケバブに似ていることからケバブケースと呼ばれます。
ケバブケースの使用例
let example-variable = "この変数名はケバブケースです";
命名規則のまとめ
変数名の命名にはさまざまな方法がありますが、たいていはプログラミング言語によって公式に推奨されている命名法があります。
あるいは、慣習として「この言語ではこういう命名規則に従いましょう」という提案がなされているのでそれに従うのがベターです。
チーム開発やプロジェクト単位で命名規則が決められていることもあるので、そのときは、その場のルールに従いましょう。
6. 【言語別】変数の使い方
ここではプログラミング言語別に変数の使い方を紹介します。
C言語の変数の使い方
C言語ではデータ型とともに変数を宣言します。
// 変数の宣言
int a; // 整数型の変数aを宣言
float b; // 浮動小数点型の変数bを宣言
char c; // 文字型の変数cを宣言
// 変数への値の代入
a = 100;
b = 1.23;
c = 'X';
// 変数の値の取得(出力)
printf("aの値は%dです\n", a); // aの値は100です
printf("bの値は%fです\n", b); // bの値は1.230000です
printf("cの値は%cです\n", c); // cの値はXです
変数は宣言代入することもできます。
int a = 100;
float b = 1.23;
char c = 'X';
Pythonの変数の使い方
Pythonでは変数宣言でデータ型を書く必要はありません。
データ型は代入された値から推論されます。
また、Pythonでは宣言と代入を別々に行うことができません。
宣言代入のみできます。
# 変数の宣言代入
a = 100
b = 1.23
c = "Python"
print(a) # 100
print(b) # 1.23
print(c) # Python
JavaScriptの変数の使い方
JavaScriptでは「let 変数名 = 値;」という形式で変数の宣言代入ができます。
データ型を書く必要はありません。
データ型は代入された値から推論されます。
// 変数の宣言代入
let a = 100
let b = 1.23
let c = "JavaScript"
console.log(a) // 100
console.log(b) // 1.23
console.log(c) // JavaScript
また、JavaScriptでは、変数の宣言と代入を別々に行うこともできます。
// 変数の宣言
let a;
let b;
let c;
// 変数の代入
a = 100;
b = 1.23;
c = "JavaScript";
console.log(a) // 100
console.log(b) // 1.23
console.log(c) // JavaScript
Rubyの変数の使い方
Rubyでは変数の宣言と代入を分ける必要はなく、データ型を書く必要もありません。
変数に対して値を代入すると、値からデータ型が推論されます。
a = 100
b = 1.23
c = "Ruby"
puts(a) # 100
puts(b) # 1.23
puts(c) # Ruby
PHPの変数の使い方
PHPでは変数名の先頭に「$(ドルマーク)」をつけて変数を宣言代入します。
データ型は値から推論されるため、型を書く必要はありません。
$a = 100;
$b = 1.23;
$c = "PHP";
print($a);// 100
print($b); // 1.23
print($c); // PHP
変数の値を取得する際にも、変数名の先頭に「$」をつけて取得します。
Javaの変数の使い方
Javaではデータ型とともに変数を宣言します。
int a = 100;
double b = 1.23;
String c = "Java";
System.out.println(a); // 100
System.out.println(b); // 1.23
System.out.println(c); // Java
変数の宣言と代入を別々に行うこともできます。
int a;
double b;
String c;
a = 100;
b = 1.23;
c = "Java";
System.out.println(a); // 100
System.out.println(b); // 1.23
System.out.println(c); // Java
C#の変数の使い方
C#ではデータ型とともに変数を宣言します。
int a = 100;
double b = 1.23;
string c = "C#";
System.Console.WriteLine(a); // 100
System.Console.WriteLine(b); // 1.23
System.Console.WriteLine(c); // C#
変数の宣言と代入を別々に行うこともできます。
int a;
double b;
string c;
a = 100;
b = 1.23;
c = "C#";
System.Console.WriteLine(a); // 100
System.Console.WriteLine(b); // 1.23
System.Console.WriteLine(c); // C#
7. (おまけ)変数を定義したときコンピュータの内部では何が起きているのか
変数を宣言したときコンピュータの内部では何が起きているのでしょうか?
私たちが変数を宣言したとき、コンピュータはデータを入れる場所として「メモリ」という保存場所を確保します。
そして、代入されたデータは、この「メモリ」に記憶されます。
この仕組みを理解すると、変数をもっとよく理解できるようになります。
詳しくは「プログラミングでデータ型を書く3つの理由」の「データと変数」の説明を参照してください。
まとめ
この記事では、プログラミングで使う変数について説明しました。
- 変数は「データにつけるラベル」のこと
- 変数はデータを一時的に保存するために使う
- 変数には「データ型」があり、型に合うデータしか保存できない
- 変数には「スコープ」があり、決まった範囲でしか参照できない
- 変数の名称は命名規則にならって命名するのがベター
変数はプログラミングでは必須の概念です。「データ型」や「スコープ」を理解するのは、はじめのうちは難しいかもしれません。
そんなときは、これらの概念の理解はいったん後回しにしても大丈夫です。
「変数はデータに名前をつけて一時的に保存できるものなんだなあー」とだけ理解して、とりあえず使ってみましょう。
何度も変数を使っているうちに「データ型」や「スコープ」の概念もなんとなく理解できるようになります。
変数を使い慣れた頃に、改めて知識として学習できれば完璧です。