C++の超基本 †数値計算の授業のための、簡単なC++の入門ページです。 もくじ †参考 †ここでは授業で使わない知識や用語などをなるべくを省きましたが、高度なプログラムには大切なものです。下の入門書などを読んで学んでおくことをお勧めします。
はじめに。 †コンピュータはアホの子で基本的に数字しか分からないので、数字でできた言葉(機械語)しか理解で来ません。だから、私たちが普段使っている日本語や英語など(自然言語)で命令しても、実行してくれません。 とはいっても、完全な機械語ではないのでコンピュータが実行できる機械語に翻訳して実行可能にしなければいけません(コンパイル)。と言うわけで、とりあえずコンパイルするソフトウェア(コンパイラ)が必要となります。ページの最後に代表的なものを紹介しておきました。まだコンパイラをインストールしてない人やコンパイルのやり方が分からない人は読んでおいてください。 おまじない †最初に次の文を入れておきます。 #include<iostream> using namespace std; この文の説明は初心者には難しいのでよく「おまじない」とか言われます。今は理解できなくても構いません。 基本 †C言語やC++のプログラムは int main(){ 処理1; 処理2; ........ return 0; } とするのが超基本です。文字は全て半角英数字のみです。上から順に実行されていきます。文の終わりには「;」をつけます(よく忘れるので注意)。 変数宣言 †変数を使うときは必ず「宣言」をしなければいけません。 型 変数; 上の「型」の所に変数の種類を指定します。例えば整数はintで宣言します。変数の名前には英数字とアンダーバー_が使えます。ただし、もちろん同じ変数名を何度も宣言はできません。 int a; 実数はdoubleで宣言します。 double x; また、 int a=2; とすれば、初期値を代入できます。 演算と代入 †例えば足し算をしたいときは 1+2 とします。四則演算の記号は通常の記号と同じです。
余りは%を使います。たとえば10÷3の余り (=1)を計算したいときは、 10%3 変数xに数値を代入したい時は x=1; と書きます。またx=1のとき、 x=x+1; とすると、もともと、x=1でしたのでこれは、x=1+1となり、xに2が代入されます。つまり右辺の計算の結果が左辺の変数に代入されます。通常の数学の式とは違いますので注意してください。 x+=1; と同じです。この様な省略文は足し算+以外でもできます。つまりx=x/2の時は、 x/=2 と同じ事です。 さらに増やす値が1の時は、 x++; とさらに簡単に書くことができます。減らす値が-1の時も同様に、 x--; と書けます。ちなみに C++ の名前の由来はC言語の「一歩進んだプログラミング言語」という意味からきています。 入力と出力 †変数xにキーボードから値を入力させるには、 cin >> x; プログラムを実行すると入力待ちになりますので、値をキーボードで打ってリターンを押せば入力されます。 cout << x; 文章は"ではさみます。いくつかの数字や文章を並べてたいときは<<をさらに書いていきます。なお"\n"やendlは改行、"\t"
はタブを示します。(\tや\nは他のエディタとかでもよく使われている「特殊文字」です。したがって文章扱いなので"ではさみます。) cout << "整数 a=" << a << endl; cout << "実数 x=" << x << endl; とかすると、もしa=2、x=1.2だったら画面に 整数 a=2 実数 x=1.2 と出てきます。改行などは自分で明示しなければならないことを注意してください。 くり返し †for文 †for(くり返し変数の宣言と初期値; くり返しの条件; くり返し変数の増分) くり返す文; for文はくり返しの条件を;で3つに区切られた()で書きます。for(...)の後の文がくり返されます。 例えば10回くり返して、0から9までを画面に出力させるときは、 for(int i=0; i<10; i++) cout << i << endl; つまり、くり返しの変数を用意して(int i=0)、くり返す毎にその変数が代わり(
i++なので一つずつ増えます)、その変数が条件(i<10)を満たす限りくり返しが続きます(つまりi=10になったら、10<10は成立
しないのでくり返しが終了します)。この書き方はお約束なので覚えてください。 while文 †while(くり返しの条件) くり返す文; くり返しの条件が成り立つ限り、while(...)の後の文をずっとくり返し続けます。2行以上の時は{}で明示します。例えば、 int i=0; while( i<10 ){ cout << i << endl; i++; } とすると、先ほどの例と同じ結果が得られます。 くり返しの制御 †くり返しをスキップさせたいときは continue; とすると、その番のくり返しははスキップされます。くり返しをを強制的に終わらせたいときは、 break; で終わります。 分岐 †if(分岐条件) 文; かっこ()の中が成り立っていたら、続く文を実行します。
2つ以上文がある時は{}でくくってループを明示します。 for(int i=0; i<10; i++) if(i==5) cout << i << endl; となります。等号は==とすることに注意してください。 「Aの時はX、そうではなくBの時はY、...、それ以外の時はZ」と複数の分岐をする時は if(A) X; else if(B) Y; ... else Z; と書きます。「else if」の分岐は複数あっても、省略してもかまいません。 条件文 †すでに分岐などで条件文は出てきましたが、一応、下に表を作っておきます。
配列 †変数をたくさん使いたいときは「配列」を使います。 型 配列[配列の数]; のように宣言します。たとえば実数の配列を3つ作りたかったら、 double v[3]; とします。このとき、 v[0] v[1] v[2] という変数ができます。
ここで添字に注意してください。必ず0からはじまる添字になっています。 v[1]=2; なお、{}で初期値が一度に入れれます。 double v[3]={1, 2, 3}; この例だと v[0]=1; v[1]=2; v[2]=3; と初期値が代入されます。 配列を画面に出力 †cout << "配列 v="; for(int i=0; i<3; i++) cout << v[i] << "\t"; cout << endl; "\t"はタブ。 行列(二重配列) †行列を作りたいときは、単にもう一つかっこ[]を加えるだけです。 型 配列[行][列]; 初期値を入れたかったら、 型 配列[行][列]={{1行目の初期値}, {2行目の初期値}, ....}; とかします。 例えば2×2行列なら、 double A[2][2]={{1,2},{3,4}}; かっこを2重に使って初期値を入れます。つまり上の例だと 1 2 3 4 の行列ができます。 行列を画面に出力 †cout << "行列 A=" << endl; for(int i=0; i<2; i++){ for(int j=0; j<2; j++) cout << A[i][j] << "\t"; cout << endl; } 初等関数と定数 †数学のsinとかexpとかの初等関数とかを使いたいときは、おまじないの呪文に #include <math.h> を追加しておきます。すると、例えば sin(x) とかが使えるようになります。表記はほとんど教科書と同じです。 fabs(x) でxの絶対値を返します。
あと、数学の定数も用意されています。
乱数はrand()を使います。例えば、 N=rand(); とかするとNに0からRAND_MAX (=2147483647)までの整数が代入されます。RAND_MAXは用意されている乱数の最大値です。 ベクトル †ベクトル †int n=3; double v[n]; //コンパイルエラー! 配列の数をこのように"動的"に扱うとコンパイルエラーとなります。こんなふうに"配列"を扱う時は vector<型> ベクトル名(成分数) のように宣言します。例えば先ほどの例では int n=3; vector<double> v(n); ただし、おまじないに #include<vector> を入れる必要があります。 v[0]=5; v[1]=10; for(int i=0; i<n; i++) cout << v[i] << "\t"; cout << endl; 行列 †行列は少しだけ宣言が複雑です。 vector< vector<型> > 行列名(行数, vector<型>(列数)) "> >"はスペースを入れることに注意して下さい(coutなどの>>と混合されてしまいます)。 int n=2; int m=3; vector< vector<double> > A(n,vector<double>(m)); 複素数 †複素数を使いたい時はおまじないに #include<complex> を入れておきます。複素数を宣言したい時は、 complex<型> 複素数(実部,虚部) 例えば実数の複素数「z=1+2i」を宣言したい時は complex<double> z(1,2); これを cout << z << endl; とかすると (1,2) とか表示されて、 (実部,虚部) のように表示されます。 zの実部と虚部をだけを求めたい時は、「z.real()」「z.imag()」とします。 cout << z.real() << endl; cout << z.imag() << endl; これは、「real(z)」「imag(z)」としても同じです。 abs(z) 偏角を求めたい時は arg(z) とかします。このように数学の関数も使えます。 ファイルに出力 †ファイルにデータを書き込みたいときは #include <fstream> int main(){ ..... ofstream fout("file.txt"); ..... fout << "Hello, World!" << endl; ..... fout.close(); ..... return0; } とするのがお約束です。上の例だと実行ファイル(exeファイル)と同じフォルダに「file.txt」と言うファイルができて、「Hello, World!」という文章が書き込まれています。 #include <fstream> を追加しておきます。つぎに ofstream fout("書き込むファイル名"); として書き込むファイルの名前を決めます。あとは、 fout << 出力 << endl; などでファイルに書き込みます。書き方は基本的に画面への出力と変わりません(違いはcout→foutだけ)。 fout.close(); としてファイルを保存して閉じます。ちなみにfoutの文字は自由に変えることができます。 (ofstreamや先ほどのvector、complexはクラスと呼ばれているものです。これらの書き方に違和感を持たれた人もいるでしょうが、クラスを勉強すればすっきりするでしょう。ここでは簡単に紹介しましたが、他にもさまざまな機能があります。) ここからのこと。 †ここからはポインタや関数、クラスなどを簡単に解説します。授業では使わない知識ですが高度なプログラムには必要なものです。余力のある人は読んでみてください。 ポインタ †メモリとアドレス †ポインタを理解するには少しコンピュータのしくみの知識が必要なのでそれを解説します。 int a; と変数宣言をすると、コンピュータは整数をメモリに保存するだけのデータ量の場所をメモリに作って、他のソフトウェアなどが使わないようにします。そして、 a=2; とすると、その作った場所に値の2を保存します。 さて人が住む場所には住所がありますが、データをメモリに置く場所にもデータの「住所」があります。このデータの住所を「メモリアドレス」または単に「アドレス」と呼ばれています(この名前もそのまんまですね)。 cout << &a << endl; とかすると、画面に 0012FF50 とかでてきます。このアドレスの「番地」はコンピュータ側が勝手に与えますので時と場合によって異なります。見ての通り、アドレスの実体は16進法で示された番号です。 人が住んでいるところの住所に手紙などを送ればその人と連絡をとること(アクセス)ができますが、メモリ上のデータもこのアドレスに「連絡(アクセス)」すれば、そのアドレスにあるデータを読み込んだり、書きかえたりすることが来ます。アクセスしたい時はアドレスの前に「*」を付けます。例えば先ほどのa(=2)のアドレスにアクセスしたい時は、 cout << *&a << endl; とかすれば、aのアドレスにアクセスされてaに入っていた値の2が表示されます。 たまにアドレスの&とアクセスの*を混乱してしまいますが、「&(アンド)はアドレス」と覚えておくと忘れないです。 ポインタ †住所を記録するのに便利なアドレス帳が世の中にはありますが、データのアドレスを保存する「アドレス帳」があったら便利そうです。実はC言語にはアドレスを保存できるアドレス用の「変数」を作ることができます。このようなアドレス用の変数を「ポインタ」と呼ばれています。ポインタの変数宣言は データの型* 変数; とかします。例えば整数のデータのアドレス用のポインタを作りたいなら、 int* p; として保存したいデータの型の後ろに「*」を付けて宣言します。このポインタに先ほどの整数a(=2)のアドレスを代入したかったら、 p=&a; とかします。 cout << p << endl; とすると確かに先ほどのアドレスが表示されます。 このa(=2)ののアドレスにアクセスしたかったら、先ほども解説しましたが「*」を前につけて、 cout << *p << endl; とすると、このアドレスにアクセスされて2が表示されます。当たり前ですがアクセスは普通の計算や代入とかにも使えます。例えば、 b=*p; とすると、pにはa(=2)のアドレスが入っているので、aのアドレスにアクセスされてbに2が代入されます。またこれも当然ですが、 *p=1; とかすると、pにはaのアドレスが入っているので、aのアドレスにアクセスされてaに1が代入されます。こうみると、*pはaの代わりのように扱えます。 配列とポインタ †double v[3]={1,2,3}; と配列を宣言すると、メモリ上に並んで配列が作られます。したがって、アドレスの番地も並んで与えられている事になります。 v となります。他のアドレスの番地は並んでいるので、+をつかって、 v+1 v+2 とすると2番目と3番目の配列の成分のアドレスを求めれます。 アドレスで配列にアクセスしたいなら、先ほどの変数と同様に*をつけて、 *v *(v+1) *(v+2) とかします。するとこれらは v[0] v[1] v[2] と同じように思えます。 つまり「v[i]と*(v+i)は同じもの」として扱えます。(実際にコンパイラはこの二つの書き方を同じものとみなします。) もちろん、ポインタを使っても配列にアクセスできます。 double* p=v; とかして配列の先頭アドレスをpに代入して、 *p *(p+1) *(p+2) とすればポインタから配列の成分にアクセスできます。したがって、 cout << *(p+2) << endl; とかするとv[2]の値の3が表示されます。 *(p+1)=5; とすると、v[1]に5が代入されます。こうしてみると *p *(p+1) *(p+2) も v[0] v[1] v[2] の代わりのように扱えます。 p[0] p[1] p[2] と配列みたいに書くことができます。つまりポインタも「p[i]と*(p+i)は同じもの」として扱えます。 関数 †長いプログラムを書いていると同じ記述が何度も出てくることがあります。これをいちいち書いていたら面倒だし、プログラムの記述自体も煩雑になって しまいます。こういうときは自分で「関数」を作って、簡単に書くことができます。C言語では最初から様々な関数が用意されていましたが、自作の関数を作る ことができます。 関数の作り方 †型 関数名(引数1, 引数2, ...){ .... return 戻り値; } 関数の型のところに戻り値の型を指定します。基本に数学の関数と同じ形をしています。例えば、「f(a,b)=a+b」
(a,bは実数)のような関数を例にとれば、関数名はfで引数はaとb、戻り値はa+bです。a,bは実数なので関数の型はdoubleになります。もし
戻り値のない関数の時は「void」を指定します。関数名は変数と同じように英数字とアンダーバー_が使えます。基本的に一度使った関数名を重複して使え
ませんが、引数の数や型が違うものは同じ関数名が重複して使えます。 こうしてみると、main(){...}も関数であることに気がつきます。これはプログラムが最初に実行する関数で「main関数」と呼ばれています。 実際に自作の関数を使った例で考えてみましょう。sumは2つの引数の和を返す関数、outputは引数の値を表示させる関数です。 #include <iostream> using namespace std; int sum(int a, int b); //関数sumの宣言 void output(int a); //関数outputの宣言 int main(){ int a; a=sum(2,5); //関数sumの呼び出し output(a); //関数outputの呼び出し return 0; } //関数sumの定義 int sum(int a, int b){ int c=a+b; return c; } //関数outputの定義 void output(int a){ cout << "答えは" << a << "です。" << endl; } はじめに変数の時と同様に関数も「宣言」をします。これはmain関数より先に、またmain関数の外に宣言します。 int sum(int a, int b); void output(int a); 関数の定義はmain関数の後ろに書きます。 int sum(int a, int b){...} void output(int a){...} outputは戻り値のない関数なのでvoidを型に指定します。実際に使うときは使いたいところで、 a=sum(2,5); output(a); とすればOKです。 さて、ここで変数aの使い方に「あれ?」と思う人がいるかもしれません。変数aは同じ名前なのに何度も宣言して使っています。実は変数には有効範囲 があって、かっこの{.....}の中でしか使えません。{.....}の外に出てしまうと、たとえ同じ変数名を使っていようがそれはまったく「別物」だ とみなされてしまいます。このルールはfor文やif文などでも同様です。少し注意が必要ですが、慣れると逆に便利な事が多いです。 ヘッダファイル †関数の宣言から関数の定義、本体のmain関数と全部同じファイルに書いてたら恐ろしく長くなります。そこでファイルを分割する事ができます。ここ ではmain関数(main.cpp)、関数の定義(func.cpp)、関数の宣言(func.h)の3つに分けた例を紹介します。
ここで関数の宣言を集めたファイルfunc.hの拡張子に注意してください。このファイルだけは拡張子が.hになります。この様なファイルは「ヘッダファイル」と呼ばれています。 #include "func.h" が追加されています。この意味はここで関数の宣言を読み込んでいるのです。このようにヘッダファイルは「#include」で読み込みます。 分割したファイルをコンパイルする時はコマンドプロンプトで bcc32 main.cpp func.cpp func.h とスペースで区切って、同時に全部を指定します。 関数とポインタ †下のプログラムは引数の値を+1する関数を定義して使ったプログラムです。 #include <iostream> using namespace std; void plusone(int x); int main(){ int a=1; plusone(a); cout << a << endl; return 0; } void plusone(int x){ x++; } これをコンパイルして実行してもaが1のままで変化しません。何が間違っていたのでしょうか? そこで活躍するのがポインタです。ポインタを使ってaのアドレスにアクセスしてaの値を書き換えます。 int main(){ int a=1; plusone(&a); cout << a << endl; return 0; } void plusone(int* p){ (*p)++; } こうすれば、 一般的にデータを関数に渡すときはアドレスだけを渡してポインタでアクセスする方が速いです。人間でも、連絡(アクセス)をとるときはその人が移動 するより、住所(アドレス)を教えてもらって手紙や電話で連絡した方が速くて便利ですよね。とくに渡すデータが配列などのように大きな量のときは基本的に ポインタを使います。 下の例ではベクトル(配列)の和を求める関数sumを作って、v1=(1.2,2)とv2=(0.3,4)の和を求めています。 #include <iostream> using namespace std; void sum(double* v1, double* v2, double* v3); int main(){ double v1[2]={1.2,2}; double v2[2]={0.3,4}; double v3[2]; sum(v1,v2,v3); for(int i=0; i<2; i++) cout << v3[i] << "\t"; cout << endl; return 0; } void sum(double* v1, double* v2, double* v3){ for(int i=0; i<2; i++) v3[i]=v1[i]+v2[i]; } sumは一番目と二番目の引数のベクトルの和が、三番目のベクトルに代入される関数です。sumの関数の中ではポインタを配列のように書いています。(これはポインタのところで解説しましたよね。) クラス †計算ライブラリ †コンパイル †コンパイラ †代表的なものに「Visual C++」「Borland C++」「gcc」などがあります。「Visual C++」はとても便利なものですが、非常に高価なアプリケーションなのでここではフリーソフトの「Borland C++」と「gcc」を紹介します。授業ではコンパイラはインストール済みなのでここは読み飛ばしてください。 Borland C++ Compiler (Windows) †
gcc (Linux, Mac) †例えばUbuntuなら、 sudo apt-get install gcc g++ でOK。 C言語を始めよう! †C言語(C++)専用の環境エディタです。あるととても便利です。コンパイラではないのでBorland C++が必要ですが、Borland C++の設定を簡単に行えます。Cを始めた初心者や「Visual Studio」はちょっとハードルが高いかなとか言う人におすすめです。操作が簡単にもかかわらず、かなりハイレベルなエディタです。 コンパイルの仕方 †とりあえず下の文を「C言語を始めよう!」やメモ帳などで打ち込んで、名前を「test.cpp」として保存してください。このとき、名前は好きなもので構いませんが名前は半角英数字にして、拡張子はcppとして下さい。この様なプログラミング言語で書かれたファイルを「ソースファイル」と呼ばれています。 #include<iostream> using namespace std; int main(){ cout << "Hello, World!" << endl; return 0; } このプログラムは画面に「Hello, World!」と出すものです。今は意味が分からなくても構いません(プログラミング入門者はこのHelloWorldのプログラムを最初に作るのが「伝統」となっています)。 「C言語を始めよう!」を使っている人は「!」のボタンの左の「矢印と四角?」のボタンを押せばコンパイルが始まります。 Hello, World! と出てくれば成功です。 コマンドプロンプトからもできます。メモ帳などの他のエディタを使っている人は、 まずコマンドプロンプトを開いて(スタート→プログラム→アクセサリ→コマンドプロンプト)、 cd <行きたい場所> と打って先ほど作ったファイルの場所まで行き、(Vistaの人はソースファイルの場所でShiftキーを押しながらマウスを右クリック→コマンド ウィンドウをここで開く)、 bcc32 test.cpp とすると、同じフォルダにtest.exeが作られているはずです。 test と打てばOKです。もちろんマウスでクリックしても構いません。 LinuxやMacの人はターミナルから g++ test.cpp でコンパイルして、実行ファイルのa.outが作られます。だから、 ./a.out とすれば実行されます。 2008-11-11 富田洋
|