int a(2); double b(1.0); a = a + 2;というようなプログラムは
int a(2);double b(1.0);a = a + 2;と書いても同じ動きをします。また
int a(2);double b(1.0); a = a + 2;と途中に改行がはいっても同じです。 プログラム中の空白、改行は基本的には無視されます。あってもなくても プログラムの動作には影響しません。 (とはいえ全角の空白は話が別。 コンパイラからは全角空白と半角空白は別の文字に見えます。 無視してくれません。 後述のコメントを日本語で書く人もいますが、全角空白には注意が必要。)
// コメント文 int a(2);/*←ここから コメントのブロック指定。 ここもコンパイラには 無視されます。 ここまで →*/double b(1.0); double c; // 命令の後にコメント文を入れる事も出来ます。
{ int a; int b; } // スコープ // スコープ { double c = 1.0; double b = c + 4.0; }
型 | 説明 |
---|---|
int | 整数用の変数 |
float | 実数用の変数 |
char | 文字変数 |
int a = 1; // 整数型変数 a を用意して、1という値を代入 int a(1); // 初期値が 1 の整数型変数 a 用意 char c = 'a'; // 文字型変数 c を用意して、'a'という値を代入 char c( 'a' ); // 初期値が 'a' の文字型変数 c を用意初期値の指定は、代入演算子 = を利用し、 変数生成後に値を代入してもよいですし、 初期値を指定して生成演算子(コンストラクタ)を呼び出しても構いません。
種類 | 説明 |
---|---|
代入演算子 | a = 2 |
比較演算子 | a == b; a < b; a > b, ... |
四則演算子 | a + b, a - b, a * b, a / b, ... |
int a(1), b(2), c(3), a2(0), b2(0), c2(0);
a2 = a*a;// a の2乗を a2 に代入
b2 = b*b;// b の2乗を b2 に代入
c2 = c*c;// c の2乗を c2 に代入
2乗程度であれば間違いは少ないですが、それでも変数の種類が多くなると
タイプミスの確率は大きくなります。そこで2乗部分を一つの関数にまとめます。
クラス、オブジェクトというものがあります (オブジェクトを「クラスオブジェクト」と呼ぶ事もあります)。 例えば「車」なんてものはクラスで、「私の車」はオブジェクトです。 つまりある要素の性質を決めるもの「型」がクラスであって、 その型の属性をもつ「物」がオブジェクトです。 C++では色々なクラスのオブジェクトを作り、 そのオブジェクトに備わっている機能を利用する形で プログラムを作ります。 クラスはいろいろなライブラリが提供するものを使う事もできますし、 自分で定義する事もできます。// 関数 square の宣言 // 引数: const int& // 返値: intint square( const int& a ){ return a*a; } ... a2 = square( a ); //関数 square の返値を a2 に代入 b2 = square( b ); //関数 square の返値を b2 に代入 c2 = square( c ); //関数 square の返値を c2 に代入 ...
...
// CarというクラスのオブジェクトをmyCarという名前でつくる
Car myCar;
...
と書きます。作成したのちオブジェクトを利用します。
class Car { public: void horn(); };と定義されているかもしれません。これはCarクラスは horn()という機能をもっている事を示しています。 この様にクラスにそなわった機能の事を「メソッド」と呼びます (「メンバー関数」という場合もあります)。 提供されているメソッドを使う場合
... myCar.horn(); ...と書きます。 ただしオブジェクトを作成する前に使う事はできません。
... // myCar.horn(); 作成前に使用する事はできない // CarというクラスのオブジェクトをmyCarという名前でつくる Car myCar; myCar.horn(); // 作成後に使用 ...
Car publicCar; { publicCar.horn(); Car myCar; myCar.horn(); .... // ここで myCar は消滅 } // publicCar はまだ生存スコープの外側で生成されたオブジェクトを利用する 事はできますが、その逆にあるスコープ内で生成されたオブジェクトを その外側から使う事はできません。
Car publicCar; { // スコープの中から publicCar を使う事は可能 Car myCar; .... // ここで myCar は消滅 } // publicCar はまだ生存 // myCar はつかえないオブジェクトの生成にはもう一つ別の方法があります。
... Car *pMyCar = new Car; ...この様につくったpMyCarを 「ポインター変数」と呼びます (ポインターオブジェクトではないんですねぇ)。 利点としては最初の作り方とは違って、スコープに縛られずに オブジェクトが永続します。オブジェクトの消滅はユーザーが
... delete pMyCar; ...と明示的に行わなければなりません。またメソッドを使う場合も
... pMyCar->horn(); ...と.ではなくて -> で指定します。 特別な場合を除いて ポインターオブジェクトを作る利点はそれほど高くないので、 通常は初めの方法でオブジェクトを作りましょう。
#include <iostream> #include <Car.hh>一行目のiostreamもヘッダーファイルです。 あとで述べる入出力関係に利用するクラスの定義が行われています。
#include <iostream>
int main( int argc, char* argv[] ){
cout << "Hello world!!" << endl; 標準出力にデータを書き出す
return 0;
}
プログラム中で現在時刻を得る方法
extern "C" { #include <sys/time.h> } ... struct timeval a; // 時間データー変数 if( gettimeofday( &a, NULL ) == -1 ) { // 時間データーの取得 cerr << "Failed to get localtime." << endl; ... // エラー処理 } cout << "経過秒: " << a.tv_sec << endl;時間情報を格納するための変数をtimeval構造体を 利用して作成します。変数に現在の時刻情報を取得するために gettimeofday関数を利用します。 timeval構造体のtv_sec メンバー変数には 1970年1月1日00:00:00 UTCからの経過時間が書き込まれます。 プログラム中で経過時間を確認する場合は、その都度 gettimeofday関数を呼び出し、時間情報変数の内容を更新してください。
0x0 | 0 | 0 | 0 | 0 |
0x1 | 0 | 0 | 0 | 1 |
0x2 | 0 | 0 | 1 | 0 |
0x3 | 0 | 0 | 1 | 1 |
0x4 | 0 | 1 | 0 | 0 |
0x5 | 0 | 1 | 0 | 1 |
0x6 | 0 | 1 | 1 | 0 |
0x7 | 0 | 1 | 1 | 1 |
0x8 | 1 | 0 | 0 | 0 |
0x9 | 1 | 0 | 0 | 1 |
0xa | 1 | 0 | 1 | 0 |
0xb | 1 | 0 | 1 | 1 |
0xc | 1 | 1 | 0 | 0 |
0xd | 1 | 1 | 0 | 1 |
0xe | 1 | 1 | 1 | 0 |
0xf | 1 | 1 | 1 | 1 |
プログラム中で16進数表記を使うことがたまにあります。 ハードウェアのコントロールや、生データーの解析でもしないと なかなかそういう場面には出くわさないかもしれませんが、 どういうものか知っておく方がよいでしょう。
プログラム中で16進数で数字を取り扱う場合は、数字の前に 0xをつけます。16進数は基数が 16個必要なので、0から9に加え、a, b, c, d, e, fを つかって、一つの桁を表現します。
左に 0x0~0xf までの16進数と、それに対応する2進数表記を 列記しました。 0xf は10進数では15です。 これは8+4+2+1ということで、2進数表記では1111になります。 つまり「すべてが1になる」という訳です。
「すべてがFになる」 は個人的「このミステリーがすごい」には ぜひ入れたい名作ですが、読み始める前に予習が必要ですね。 かつての理系学生なら多分ハマるような気がするのだけど、 最近は16進数表示なんてあまり扱わないからそうでもないのかなぁ。