QueSTudents Yuto Takei はじめに C++ 変数と型 演算子 ステートメントと制御構文 配列 オブジェクト指向の導入 クラスの実装 コンストラクタとデストラクタ 以下、第 2 回へ続く 休憩! はじめに ぐいぐい行きます・・・ 置いてかれないように・・・ 質問あればすぐに止めてください 途中で休憩いれます プログラミングは簡単です プログラマは狂人ではありません 独習 C++ 第3版 翔泳社 2002/11 ISBN4-79810-318-7 このスライドは 独習 C++ 改訂版 翔泳社 1999/04 ISBN4-88135-701-8 を基にしています。 はじめに C++ 変数と型 演算子 ステートメントと制御構文 配列 オブジェクト指向の導入 クラスの実装 コンストラクタとデストラクタ 以下、第 2 回へ続く 休憩! C++ 変数と型 演算子 ステートメントと制御構文 配列 休憩! これから扱うプログラミング言語は C++ (シープラス) です。 簡単にいえば C 言語の子供 1983 年 Bell 研究所生まれ ANSI/ISO 委員会によって標準化 最もよく利用される商用言語のひとつ メモ帳 + コンパイラ 学校では Emacs と g++ IDE (統合開発環境) 現場ではこれを利用するが普通 Visual Studio® 2005 (Microsoft) C++Builder® 2007 (Borland) Xcode (Apple) etc. 人間の書いたプログラム を機械語に翻訳するため のソフトウェア Hello world! #include <iostream> using namespace std; int main() { cout << "Hello world!" << endl; return 0; } コンソールとは、コンピュータと人間が対話す る画面のこと 黒い画面に白い文字とか char name[80]; cout << "What's your name?" << endl; cin >> name; cout << "Hi " << name << "!"; 変数は、プログラムの実行中の状態を保持する ために利用する type varName; type varName = initValue; type varName1, varName2, ...; int i = 10; コンピュータ内で、あるデータが何を示してい るのかを理解するためのもの 01000001 (0x41) 整数としてみれば 65 文字としてみれば A データが何の種類であるか、知る必要がある int, long – 32 ビット符号付き整数 __int8 – 8 ビット符号なし整数 整数型は先頭に unsigned をつければ符号なし、 signed をつければ符号付き float, double – 浮動小数点 char – 1 バイト文字 or 8 ビット整数 bool – 2 値変数 (真 true か偽 false か) オペランドの数で次のような分類がある 単項演算子 二項演算子 三項演算子 (多項演算子) 単項演算子は、前置もしくは後置 -operand, operand++ 二項演算子は、中置記法 operand1 + operand2 三項演算子は、特殊な記述を用いる expression ? value1 : value2 算術演算子: + - * / % 論理演算子: & | ^ ! ~ && || ビット シフト演算子: << >> 関係演算子: == != < > <= >= 条件演算子: ?:: インクリメント, デクリメント: ++ -代入演算子: = += -= *= /= %= &= |= ^= <<= >>= 主として数値計算を行うときに用いる演算子 加算: + 減算: 乗算: * 除算: / 剰余算: % 論理積, 論理和, 排他的論理和が定義される たとえば 214, 115 をオペランドとすると・・・ 11010110 &) 01110011 01010010 11010110 |) 01110011 11110111 11010110 ^) 01110011 10100101 条件論理演算子 (ショート サーキット) bool 型オペランドどうしにのみ定義 第 1 オペランドのみで値が判定できるなら、第 2 オペ ランドを評価しない 単項演算子としては否定と補数がある 否定演算子 ! は bool 型にのみ適用可 !true は false になり、!false は true になる 補数演算子 ~ は整数型に適用可 ビットごとに 0, 1 を反転させていく たとえば 214 の補数は 41 である ビットをずらすのに利用する 214 を左に 3 ビット分、シフトしてみる 11010110 =214 000 =167 214 << 3 = 176 左シフトの場合には、上位ビットは捨てられて、 下位ビットのほうに 0 が補填される 右シフトの場合には、下位ビットは捨てられて、 上位ビットのほうに 0 が補填される 2 つのオペランドの関係を比較する 等しいかどうか: == 等しくないかどうか: != 大小関係: < > <= >= (<= は ≤、>= は ≥ に対応) 比較関係が成立する場合には true が、そうで ない場合には false が演算結果となる 唯一の三項演算子 expression ? value1 : value2 expression: bool 型の評価対象式 評価対象式が true ならば value1 を、false な らば value2 を演算結果とする。 score >= 50 ? "合格" : "不合格" 実はショートサーキットは条件演算子を用いて 記述できる。 たとえば、bool 型の変数 A, B に対して A && B A || B 実はショートサーキットは条件演算子を用いて 記述できる。 たとえば、bool 型の変数 A, B に対して A && B A || B A ? B : false A ? true : B 変数に 1 を足して (もしくは引いて)、その値を 返す 前置と後置では動作が変わる int int int int a b a b = = = = 10; ++a; 10; a++; a = 11, b = 11 a = 11, b = 10 デクリメントは 1 を引く。挙動はインクリメン トと同様 単純代入演算子: 左オペランドに、右オペランド の値を代入する rank = "不可" 複合代入演算子: 左オペランドと右オペランドの 間で演算を行った後、その値を左オペランドに 代入する。 balance -= 30000 balance = balance - 30000 cf. ++a は a += 1 と同じ。 代入演算子の演算結果は、値を代入した後の左 オペランドの値になる k = (n % 2 == 0 ? n /= 2 : n -= 1) + 1 代入演算子の左オペランドは、値が代入できる ものでなければならない i + 3 = 10 これはコンパイル エラー int a = 10; int b = ++a++; このコードはどうなるでしょうか? 答え: 無効 ++a は、変数ではなく単なる値である。した がって (++a)++ は、++a という値に 1 を加える ことになるので無効。 プログラム中にはメモを残すべき 単一行コメント: // comment 複数行コメント: /* This is a comment. */ C++ はフリー フォーム言語 #include <iostream> using namespace std; int main() { cout << "Hello world!" << endl; return 0; } C++ はフリー フォーム言語 #include <iostream> using // using directive namespace /* comment */ std; int // this code is completely valid. main(){cout<< "Hello world!" << endl // break ; return 0; } 命令を記述する文章のこと ラベル付きステートメント 式ステートメント Null ステートメント 複合ステートメント (aka. コード ブロック) 条件分岐ステートメント 繰り返しステートメント ジャンプ ステートメント 宣言ステートメント expressionopt; expression は任意の式で、省略可能 3; // valid statement Null ステートメント: expression を省略したス テートメント ; // Null statement { statements } statements は複数のステートメント { cout << "Hello world!"; cout << endl; } { } // valid プログラムは命令の流れ (フロー) どのように実行されるかをコントロールする必 要がある 条件分岐 繰り返し ジャンプ if ステートメント if (expression) then-statement else else-statement else 句以下は省略可能 if (score >= 80) rank = "優"; else if (score >= 65) rank = "良"; else if (score >= 50) rank = "可"; else rank = "不可"; for ステートメント for (initializer; condition; iterator) statement iterator initializer for statement true condition false ループ初期化子, 継続条件, ステップ はすべて省略可能 ラベル付きステートメントを使う goto ステートメント: 任意のラベルへ飛ぶ for (int i = 0; ; i++) if (i == 5) goto loopOut; loopOut: // label definition cout << "i == 5"; High and Low switch ステートメント: ある値がどれと等しい かを元にして判定することができる。 switch (expression) { case value1: statement1 case および default は ラベル付きステートメント case value2: statement2 ... default: defaultStatement } case 句内では、break ステートメントを使わな い限り、次の case 句以降に流れ落ちる。 switch (10) { case 10: cout case 15: cout case 20: cout } // The output << "10 "; << "15 "; break; << "20 "; will be 10 and 15. while ステートメント while (expression) statement expression が true である限り statement を 実行する expression は、ループに入るときと、 statement が実行されるたびに評価される for ループのシンプル版 break ステートメント: ループ ブロックや switch 文を 1 段階脱出するのに使用 for (int i = 0; i < 10; i++) { if (i == 5) break; cout << i; } cout << "outside the loop"; continue ステートメント: ループ ブロックにお いて、継続条件式に飛ぶために使用 for (int i = 0; i < 10; i++) { if (i == 5) continue; cout << i; } cout << "outside the loop"; 試験データの処理 do-while ステートメント do statement while (expression); while ループとの違いは、継続条件式の評価が 処理ステートメントの実行後であること まず 1 回処理をした後、同じ処理を続けるか判 定するような場合に利用 こんな風なループもありと言えばあり: // entering loop lpStart: // do something... lpCond: if (expression) goto lpStart; else goto lpEnd; lpEnd:; // outside the loop 推奨しないが、究極的にはこれが一番柔軟 return ステートメント: 実行中の関数を脱出し、 呼び出し元に制御を戻す。同時に関数の戻り値 を与える return retValueopt; 戻り値を持つ関数ならば、retValue に戻り値の 型に合致する値を指定 戻り値がない関数ならば retValue は指定して はいけない int gcd(int a, int b) { if (a < b) return gcd(b, a); else if (b == 0) return a; else return gcd(b, a % b); } void proc() { // do something... return; } 次の値を求めよ 次の値を求めよ ∞ 6 𝑘=0 𝑘 𝑙=1 𝑘 𝑙=1 2𝑘 2𝑙 − 1 ⋅ 2𝑘 + 1 ⋅ 22𝑘+1 正弦関数の逆関数をテーラー展開 ∞ sin−1 𝑥 = 𝑛=0 2𝑛 2𝑛+1 𝑥 𝑛 ⋅ = 22𝑛 2𝑛 + 1 で、x = 1/2 とすれば OK 展開すると、こうなる: ∞ 𝑛=0 2𝑛 − 1 ‼ 𝑥 2𝑛+1 ⋅ 2𝑛 ‼ 2𝑛 + 1 𝜋 1 1 1⋅3 1⋅3⋅5 = + + + +⋯ 6 1 ⋅ 21 2 ⋅ 3 ⋅ 23 2 ⋅ 4 ⋅ 5 ⋅ 25 2 ⋅ 4 ⋅ 6 ⋅ 7 ⋅ 27 円周率の概算 配列とは、複数の同一型のオブジェクトを格納 するコンテナ 要は、複数の変数が一体となった変数 type arrayName[length]; type arrayName[length] = { elem1, elem2, ... } type: 配列内の要素の型 length: 配列の要素数 (定数指定) 長さを変数で指定するときには、new 演算子を 利用して動的に配列を割り当て type *ptName = new type[length]; 使用後には必ず delete 演算子で解放 delete[] ptName; ポインタの詳細については次回へ 要素は 0 番目から始まる 配列は作成した後には長さを変更できない 要素にアクセスするには [] 演算子を利用 int num; cin >> num; int* fibo = new int[num]; fibo[0] = fibo[1] = 1; for (int i = 2; i < num; i++) fibo[i] = fibo[i - 2] + fibo[i - 1]; エラトステネスの篩 はじめに C++ 変数と型 演算子 ステートメントと制御構文 配列 オブジェクト指向の導入 クラスの実装 コンストラクタとデストラクタ 以下、第 2 回へ続く 休憩! オブジェクト指向の導入 クラスの実装 コンストラクタとデストラクタ プログラミング パラダイムの一つ 構造化プログラミング データ指向プログラミング オブジェクト指向プログラミング etc. 設計対象となるシステムの構成要素をオブジェ クトとみなす手法 システムをマルチ スケールに分析する カプセル化 (encapsulation) ポリモーフィズム (polymorphism) 継承 (inheritance) システムの構成要素をオブジェクトとして扱う オブジェクトは、その構成要素が持つデータと、 そのデータに付随する処理とを、包含する オブジェクトは外部からの操作を受け付けるイ ンタフェースを持つ オブジェクトが提供するインタフェース以外で は、オブジェクトが持つデータにアクセスでき ない 完全なブラックボックス 複数の種類のオブジェクトに対して、同種の操 作を行うには、同じインタフェースを用いるこ とができる バイクにも大型トラックにも加速するためのイ ンタフェースがある。ユーザであるドライバは、 このインタフェースを同じように利用すること ができる あるオブジェクトが、別のオブジェクトの性質 を持つとき、そのオブジェクトの性質を継承す ることができる 「乗り物」オブジェクトは、「人の移動手段で ある」という性質を持つ 「バイク」や「自動車」は「乗り物」の性質を 継承する 今までオブジェクト、と言っていたが・・・ クラスは、オブジェクトの定義である インスタンスは、オブジェクトの実体である たとえば、自動車の設計図があればそれはクラ スであると考えることができ、それを基にして 実際に作成した自動車はインスタンスになる class キーワードを用いる class className { // private members public: // public members } objectListopt; メンバ変数やメンバ関数 などを定義 関数とは命令コードの集合体 type funcName(paramList) { カンマ区切りで変数宣 言リストを書く ... } type に void を指定すると、戻り値を持たない ルーチンになる 戻り値を返すには return ステートメントを利 用 プロトタイプ: 関数の実体 (つまりコード本体) を 定義しないこともできる int main(); あるクラスのメンバ関数に実体を与えるときに は、スコープ解決演算子 :: を用いて、どのクラ スの関数であるかを明示する必要がある class A { public: void Func(); }; void Func() { } 上のコードでは Func はグローバル関数 A::Func として定義すれば A クラスのメンバ関 数 Func の定義になる プログラムを書くときには、*.cpp という拡張子 のコード ファイルに記述する クラスの定義などについては、慣習的に、*.h と いう拡張子のヘッダ ファイルに記述する あるクラスを利用するときには、その定義が書 いてあるヘッダ ファイルを #include ディレク ティブでインクルードする 学生クラスの実装 C++ では、パラメータ リストが異なる同名の関 数を定義することができる ただし、戻り値が異なるだけで、パラメータ リ ストと関数名が同じなのは不可 ポリモーフィズムを実現 (cf. インタフェース) cf. メソッド シグニチャ: 関数名、パラメータ リ スト、戻り値の組み合わせをひとまとめ たとえば絶対値を返す関数 int, char, double などの値の絶対値がほしい 関数オーバーロードがなかったとすれば、iAbs, cAbs, dAbs のように複数の関数を実装しなければいけない パラメータの型が異なるのでオーバーロードで対応。 結果として abs という関数だけで済む 絶対値関数の実装 クラスには初期化処理と終了処理を組み込むこ とができる コンストラクタ: インスタンスの作成時に実行さ れる関数。パラメータを取ることができるが、 戻り値は持てない。関数名は className と同じ デストラクタ: インスタンスが破棄されるときに 実行される関数。パラメータも戻り値も取れな い。関数名は ~className になる 両方ともアクセス修飾できる 戻り値は void ではなく、そもそも存在しない 逆ポーランド記法 (RPN) への変換 中置記法: (1 + 5) * (8 + 1) = 54 逆ポーランド記法: 1 5 + 8 1 + * 54 = 2 項演算子のオペランドを連続して記述した後に、オ ペレータを置く記述法 逆ポーランド記法 (RPN) への変換
© Copyright 2024 ExpyDoc