ホーム | ブログ | C++辞典 | サイトマップ | FAQ | 掲示板 | リンク集
メイン・メニュー
プログラミング
その他

初期化と代入

前回は、キーボードからの入力によって、オブジェクトの値を設定しました。しかし、このように外からの入力で値を設定することより、プログラムの中で値を設定することの方がずっと多いはずです。今回解説するのは、プログラムの中でオブジェクトの値、より正確にはオブジェクトの状態を設定する「初期化」と「代入」についてです。

「初期化」と「代入」というのはよく似ています。ごく簡単にいうと、宣言(オブジェクトを使うための準備でしたね)のときに同時に行うのが「初期化」で、宣言した後に行うのが「代入」です。また、場合によっては「初期化」のときでなければ行えないようなものもあります。

まずは、整数を表す int 型のオブジェクトを初期化してみましょう。 今回は、「初期化」と「代入」の部分に的を絞るので、main 関数の枠組みなどは省略しますが、実際にコンパイルするときは、これまでのサンプルを参考に、適宜補ってください。

int x = 0;

初期化は、上のように等号 = を使って行います。数学での等号は、両辺が等しいことを意味しますが、C++での等号は、右辺の値で左辺のオブジェクトを設定する意味だと考えてください。数学に強い方ほど、慣れないうちはとまどうことがあるかもしれませんが、= は単なる記号ですので、ある程度割り切って理解するようにしてください。

初期化を行うには、上のように等号を使う以外に、次のような書き方もできます。どちらでも同じ意味です。

int x(0);

等号の代わりに、設定する値を括弧でくくって、オブジェクト名の直後に書いています。等号を使う方法はC言語から引き継いだ書き方であり、括弧を使う方法は、C++特有の書き方です。int 型のような数値の場合は、どちらかというと、等号を使う方が一般的なようです。

次に、int 型のオブジェクトへの「代入」について解説します。まずは、ソースコードを見てみましょう。

int x;
x = 123;

今回の例では、x をとりあえず宣言した後で、123 という値を x に「代入」しています。「代入」を行った後は、x には 123 という値が格納されることになります。「代入」の場合にも等号 = を使います。「代入」のときの等号のことを、特に「代入演算子」と呼びます。その名の通り、+ や - などと同じ「演算子」の仲間です。「代入演算子」も、等号を使ってはいますが、両辺が等しいことを表すのではなく、右辺の値で左辺を設定することを表します。

ところで、上の例で、123 を代入する前の x ですが、ここでの宣言では「初期化」を行っていませんので、x の値は「未規定」になります。「未規定」というのは、どんな値が設定されているか、蓋を開けてみるまで分からないということです。ですから、初期化も代入も行わず、キーボードのような外部からの入力を読み込んだりもしないままで x を使うと、とんでもない結果になったりします。つまらないバグを防ぐには、オブジェクトは宣言と同時に初期化しておいた方が無難です。

なお、上の説明では、「初期化」も「代入」も、具体的な数字を使って書きましたが、他のオブジェクトを使って「初期化」や「代入」を行うこともできます。また、難からの「式」を使って「初期化」や「代入」を行うこともできます。次のような具合にです。

int x = 0;
int y = x;
int z = y + 1;
x = z;
y = y * 2;

上の例の最後の文では、y に代入する値を表す式として、y 自身を使っていますね。実はこのような書き方もできるのです。それ以外の文では、結果として、代入後の左辺と右辺は等しくなっていましたが、自分自身を使った代入を行った場合には、左辺と右辺の値は等しくなりません。等号を使ってはいますが、数学的な意味とは異なることを、しっかり覚えておいてください。

これまでは整数の「初期化」と「代入」について解説してきましたが、ついでに文字列の「初期化」と「代入」についても解説しておきましょう。文字列には、もちろん std::string を使います。まずは、「初期化」からです。

std::string str1 = "This is a string.";
std::string str2("This is a string.");

文字列の「初期化」も、整数と同じように、等号を使う書き方と、括弧を使う書き方の両方があります。文字列の場合は、どちらが一般的かは微妙ですが、できれば後者の括弧を使う方法で書いておいた方がよいでしょう。理由は続きの解説を読んでいただければ想像がつくと思います。

文字列の初期化の場合も、他のオブジェクトや式を使うことができるのですが、それ以外にもこんなことができます。

std::string str1("This is a string.", 4);
std::string str2(10, 'A');

上の例では、str1 は "This is a string." の最初の 4 文字だけを使って「初期化」します。str2 は、'A' という文字(文字列ではありません)を 10 個並べた文字列として「初期化」します。こんな風に、2 つ以上の値を使ってオブジェクトを初期化することもできるわけです。2 つ以上の値を使って初期化する場合は、等号を使った書き方はできません。括弧を使った方法でのみ書くことができます。

文字列への代入についても解説しておきましょう。これは比較的簡単です。とりあえず、ソースコードを見てください。

std::string str1("This is a string.");
std::string str2;
str2 = str1;
str1 = "It is a string.";
str2 = 'A';

上のように、文字列の代入も整数の場合と同じように、他のオブジェクト(や式)で表される値を代入することも、二重引用符で囲んだ文字列を直接代入することもできます。ところで、最後の行が少し変わっていますね。文字列ではなく、単なる文字を代入することもできるのです。この場合は、str2 には "A" が設定されることになります。

int 型と違って、std::string 型の場合は、「初期化」せずに宣言した場合でも値が「未規定」になりません。「初期化」しなかった場合には、長さ 0 の "" という文字列に設定されるのです。このように、型によって、「初期化」しない場合は「未規定」になったり、ならなかったりします。どんな場合に「未規定」にならないかのルールははっきりしているのですが、ここで一度に理解するのは大変ですので、とりあえず全部何らかの値で「初期化」すべきだと考えておいた方が無難かと思います。


さて、以下はほとんど余談に近い内容になりますので、参考程度に読んでみてください。もしかすると今は理解できないかもしれませんが、何も心配することはありません。この入門講座も、「Boostを使う!」と銘打っているにも関わらず、なかなか Boost C++ Libraries が登場しないので、この辺りで少しだけ顔を出してもらいましょう。

先ほど、型によって、「初期化」しない場合に「未規定」になったり、ならなかったりするという話をしましたが、強制的に初期化させる方法が Boost C++ Libraries によって提供されています。まずは、ソースコードを見てもらいましょう。

#include <iostream>
#include <boost/optional.hpp>

int main()
{
  boost::optional<int> x;
  std::cout << x.data() << std::endl;
  return 0;
}

boost::optional<int> というのがその部分です。<boost/optional.hpp> というのは、boost::optional<int> を使うために必要なヘッダです。boost::optional<int> という型を使うと、特に「初期化」しなくても、x は 0 に設定されます。int 型以外に対しても同じ方法が使えて、boost::optional<std::string> とすれば、文字列に対して同じように使うことができます。

この、boost::optional<...> を使うときに注意しないといけないのは、std::cout の行を見ていただければわかるように、x の内容を触るには、x.data() といった具合に、.data() を付けなければいけないことです。この .data() が何なのかはここではまだ解説しません。ここでは、Boost C++ Libraries には、こんな機能が満載されているということを、紹介するにとどめておきます。

プリンタ出力用画面
前のページ
四則演算
コンテンツのトップ 次のページ
if文による場合分け


 ホーム | プロフィール | メール | ログイン | 管理
Copyright © 2005-2009 by TAKAGI Nobuhisa