変数とは
概要
「変数」とは、名前を持った、値の入れ物のことである。式の中で使用することができ、変数に入っている値を取り出したり、新たな値を入れることが出来る。
例えば、以下のように記述すると、変数「a」の中に、値「123」を代入する(変数に値を入れることを「代入する」と呼ぶ)。
a = 123;
数学記号の「=」は左右両辺の値が等しいことを意味する(等号)が、C/C++では右辺値を左辺の変数に代入することを意味する。
この「=」は「代入演算子」と呼ばれる。
代入文の右辺の式の中に変数名を書くと、その時点でその変数に入っている値を取り出すことが出来る。
a = 123; b = a;
上記の2行目は、代入演算子の右辺の式は a なので、a の値を取り出してそれを b に代入する。すなわち、b の値も 123 になるというわけだ。
「a の値を取り出す」と言っても、a に入っている値が無くなるわけではない。値を参照するだけなので、a に入っている値は変化しない。
「値を取り出す」よりも「値をコピーする」の方が実情に合っているかもしれない。
前の記事で、cout を使って画面に文字列を表示する方法を学んだが、変数も以下のようにして表示することが可能だ。
a = 123; cout << a << "\n";
「123」と表示するだけなら、単に「cout << "123"」と書けばいいのに、なぜそんな周りくどことをするのだ?と思う人がいるかもしれないが、 変数の値は後で変更することができるので、このように書いておくと、同じコードで違った値を表示することが出来て便利なのだ。その例は後で説明する。
変数名
変数名は英字で始まる英数字列。「_」アンダーバーも英字として扱われる。
数字や記号で始めることは出来ない。途中に英数字アンダーバ以外の文字があると、変数名はそこで終わっているものと見なされる。
正しい変数名の例:
name abc123 a123zxx _var aaa_ xyz_abc xy2_23x_
不正な変数名の例:
123abc123 // 英字ではなく数字で始まっているので× #abc // 英字ではなく記号で始まっているので× xyz-abc // マイナス記号は変数名に含めることは出来ない aaa+ZZZ // プラス記号は変数名に含めることは出来ない
コンパイラによっては日本語を許すものもあるが、日本語の使用はあまり一般的ではない。
変数名は英単語ではなくローマ字にしてもよい。ただし、ほとんど英語で一部ローマ字だと混乱することがあるので注意だ。
文字数に制限は無い。が、あまり長いと識別しづらくなるので、ほどほどにしておいた方がよい。
長い単語は母音を抜いて短くしたり(list → lst)、先頭の数文字だけを使う(prefix → pre)ことがある。
「user name」などのように複数の単語を組み合わせる場合、2つの流儀がある。
「user_name」のようにアンダーバーで単語を連結するのと、「userName」のように連結する部分の文字を大文字にする方法だ。
各単語の先頭のみを大文字にしたものを「キャピタルワード(capital words)」と呼ぶ。最初の単語の先頭文字は大文字にしないのが普通だと思うが、 「UserName」のように大文字にする流儀もある。
実は変数ではなく「定数」にも名前を付けることができる。で、識別子が変数なのか定数なのかを見てすぐに区別できるよう、 変数は先頭が小文字、定数は全て大文字、という流儀が一般的だ。
文法には規定されていないことに関して、ソースコードをどう記述するかは「コーディング規約」と呼ばれる。
これは会社やチームで決まっていることが多いので、それに従うように。
個人であれば好きにしていいが、他人に見られることもあるので、あまり突飛な書き方はしない方が無難である。
参考資料として、Google C++スタイルガイド 日本語訳 へのリンクを貼っておく。ざっと読んでおくといいだろう。
参考:Google C++スタイルガイド 日本語訳 命名規則
変数の宣言
これまでの例では、変数をいきなり使っていたが、C/C++ では変数をあらかじめ宣言してないと使うことができない。 「これから、こういう変数を使うぞ」って宣言しておくわけだ。
変数宣言は「型名 変数名;」という形式。
int k; // int 型の変数 k を宣言
「型」とは変数に入る値の種類のことである。
整数、浮動小数点数、文字、文字列などがある。
整数、浮動小数点数には表すことが出来る値の範囲があり、以下の様なものがある。
型名 | 値の範囲 | 備考 |
---|---|---|
char | -128~+127 | 8ビット文字 |
short | -32768~+32767 | 16bit整数 |
int | 約-21億~約+21億 | 32bit整数 |
long long | -9.2*10^18~9.2*10^18 | 64bit整数 |
float | 3.4*10^±38 (有効桁数:7桁) | 4バイト |
double | 1.7*10^±308 (有効桁数:15桁) | 8バイト |
最初はどの型を使ったらいいのかわからないかもしれないが、int が各環境で最も自然な型なので、整数を扱う場合、通常は int型を使うとよいだろう。 浮動小数点数は、通常 double を使うとよいだろう。
大は小を兼ねるので、範囲の大きい型を使えばいいんじゃね?と思われる人もいるかもしれないが、変数を多量(何10億個とか)に使う場合、 範囲の大きい型はその分だけ多量のメモリを使用する。メモリ使用量が多いと、パフォーマンスが低下したり、場合によっては動作しないこともある。 なので、必要も無いのにむやみやたらと大きい型は使わない方がよい。
整数型には、上記以外に「long」がある。これは処理系によって 32bit だったり 64bit だったりして危険なので使わない方がよいと思う。
また、古ーい処理系では int が 16bit のものがある。実は int は処理系によって自然なサイズという仕様で、32bit と規定されているわけではない。
VC++ には「__int32」のようにビット数を明記する型名もある。場合によってはそれらを使うといいだろう。
C++ であれば std::string という名前の文字列型を使用することが出来る。ただし、string を使うときは #include <string> を最初のあたりに書いておく必要がある。
#include <string> ..... std::string name;
以下のように、型の後に複数の変数をカンマで区切って列挙することで、複数の変数を1行で宣言することも出来る。
double height, weight; // 身長、体重
変数の初期化
変数宣言時に「= 値」と記述することで、変数を初期化することが出来る。
int a = 123; // int型の変数 a を宣言し、値 123 で初期化
上記は以下のように記述するのと同じ意味だ。
int a; a = 123;
行数が増えるとソースコードが読みづらくなるし、宣言だけを行うと、初期化忘れの危険性があるので、常に変数宣言時に初期化しておくことを薦める。
文字列変数の初期化も、整数、浮動小数点数と同じように「変数名 = 初期値」で指定できる。 文字列リテラルはダブルクォート(")で囲ってあらわすので、以下のように記述する。
std::string name = "okap";
文字型(char)も同様に初期化できる。1文字はシングルクォート(')で囲って表す。
char ch = 'X'; // ch を文字 X で初期化
演習問題:
- int 型の変数 abc を宣言し、31415 で初期化しなさい。
- double型の変数 pai を宣言し、3.1415926535 で初期化したのち、それを画面に表示しなさい。
- short 型の変数 sh を宣言し、範囲外の値、たとえば 1000000 を代入するとどうなるかを予測しなさい。 実際に試してみて、なぜそうなったのかを考えなさい。
- std::string 型の変数 str を宣言し、"aiueo" で初期化し、それを表示しなさい。
- char 型の変数 ch を宣言し、文字 C で初期化し、それを表示してみなさい。
int abc = 31415;
double pai = 3.1415926535; cout << "pai = " << pai << "\n";
short sh = 1000000; cout << "sh = " << sh << "\n";
結果は 16960 と表示される。
1000000 は16進数では 0xF4240 だが、short は16ビットなので、下位16ビットだけが有効で、0x4240 となる。
それを10進数に変換すると 16960 となる、というわけだ。
#include..... std::string str = "aiueo"; cout << "str = " << str << "\n";
char ch = 'C'; cout << "ch = " << ch << "\n";
式とは
「123+200」とか「a-12」などの様に、普通の数式のように記述出来る。
ただし、掛け算は「*」を、割り算は「/」を用いる。
単に計算式を書くだけでは、結果が消えてしまうので、通常は何らかの変数に代入するか、値を画面に表示する。
int a = 2; int b = 3; int c = a * b;
式の構成要素としては、項と演算子、それに括弧がある。
「項」は値を持つもので、具体的には、定数、変数がある。定数には整数、小数、文字列リテラル、1文字がある。
整数は数字文字の並びだ。
小数は数字列の並びで途中に小数点(ピリオド)を入れることが出来る。
また、小数の直後に「E数字列」または「E-数字列」を付加して、浮動小数点数を表現することも可能だ。
文字列リテラルは、文字の並びをダブルクォート(")で囲って表す。
1文字だけを表す場合は、1文字をシングルクォート(')で囲って表す。
文字列と文字は初心者がよく混同するものなので、違うものだということをちゃんと認識しておいて欲しい。
123 // 整数の例 1.23 // 小数の例 1.23E10 // 浮動小数点の例 1.23*10^10 "ashita" // 文字列リテラルの例 'x' // 文字の例
演算子には1項演算子、2項演算子、3項演算子がある。
1項演算子とは「演算子 項」または「項 演算子」という形式のもので、具体的には「マイナス演算子(-)」などがある。
2項演算子とは「項 演算子 項」の形式を持つもので、四則演算子など多くの演算子がある。
具体的にどのような演算子があるかは別項で解説する。
3項演算子というものもある。ご想像どおり「項 演算子 項 演算子 項」という形式だ。C/C++ 言語では ?: 演算子がそれにあたる。 これについての説明は別稿で行う。今はそんなものもあるとだけ覚えて置いて欲しい。
-a // 変数 a に入っている値を符号反転 a + 3 // 変数 a に入っている値に整数の 3 を加える
演算子には優先順位がある。乗除算演算子(* /)の優先順位は加減算演算子(+ -)よりも高いので、「1+2*3」の値は9ではなく7となる。 このへんの事情は、通常の数式といっしょだ。
演算子の優先順位を強制的に変えたいときは丸括弧を使用する。
前の例で、「1+2」を乗算よりも先に計算したい場合は「(1+2)*3」と書けばよい。この事情も通常の数式と同じだ。
演習問題:
- int 型の変数 a に123を、b に2を代入し、a+b, a-b, a*b, a/b のそれぞれの値を表示するコードを書き、実行して結果を確認しなさい。
- BMI とは、体重と身長から算出される、ヒトの肥満度を表す体格指数である。具体的には 体重/(身長*身長) で計算する。
体重 65kg, 身長 1.7m の場合のBMIを計算し、結果を表示するコードを書きなさい。
int a = 123; int b = 2; cout << "a+b = " << a+b << "\n"; // a+b の結果を表示 cout << "a-b = " << a-b << "\n"; // a-b の結果を表示 cout << "a*b = " << a*b << "\n"; // a*b の結果を表示 cout << "a/b = " << a/b << "\n"; // a/b の結果を表示
double weight = 65; double height = 1.7; double BMI = weight / (height * height); cout << "BMI = " << BMI << "\n";