このエントリーをはてなブックマークに追加

手を動かして さくさく理解する
C++ やさしい入門 変数と式
Copyright (C) 2015 by Nobuhide Tsuda

変数とは

概要

「変数」とは、名前を持った、値の入れ物のことである。式の中で使用することができ、変数に入っている値を取り出したり、新たな値を入れることが出来る。

例えば、以下のように記述すると、変数「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 で初期化

演習問題:

  1. int 型の変数 abc を宣言し、31415 で初期化しなさい。
  2.     int abc = 31415;
    
  3. double型の変数 pai を宣言し、3.1415926535 で初期化したのち、それを画面に表示しなさい。
  4.     double pai = 3.1415926535;
        cout << "pai = " << pai << "\n";
    
  5. short 型の変数 sh を宣言し、範囲外の値、たとえば 1000000 を代入するとどうなるかを予測しなさい。 実際に試してみて、なぜそうなったのかを考えなさい。
  6.     short sh = 1000000;
        cout << "sh = " << sh << "\n";
    

    結果は 16960 と表示される。
    1000000 は16進数では 0xF4240 だが、short は16ビットなので、下位16ビットだけが有効で、0x4240 となる。 それを10進数に変換すると 16960 となる、というわけだ。

  7. std::string 型の変数 str を宣言し、"aiueo" で初期化し、それを表示しなさい。
  8. #include 
        .....
        std::string str = "aiueo";
        cout << "str = " << str << "\n";
    
  9. char 型の変数 ch を宣言し、文字 C で初期化し、それを表示してみなさい。
  10.     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」と書けばよい。この事情も通常の数式と同じだ。

演習問題:

  1. int 型の変数 a に123を、b に2を代入し、a+b, a-b, a*b, a/b のそれぞれの値を表示するコードを書き、実行して結果を確認しなさい。
  2.     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 の結果を表示
    
  3. BMI とは、体重と身長から算出される、ヒトの肥満度を表す体格指数である。具体的には 体重/(身長*身長) で計算する。
    体重 65kg, 身長 1.7m の場合のBMIを計算し、結果を表示するコードを書きなさい。
  4.     double weight = 65;
        double height = 1.7;
        double BMI = weight / (height * height);
        cout << "BMI = " << BMI << "\n";
    

まとめ・参考