カワサキの技術ブログ

エンジニア志望によるゆるゆる備忘録。

【新・明快C++入門】学習メモ(6-2,3,4章)

『新・明快C++入門』第6章(関数)

6-2 「参照と参照渡し」(p216~221)

参照オブジェクト

  • 型名& 変数名 初期化子;
int x = 10;
int& y = x;    // yはxを参照
  • yに対してxの別名(エイリアス)を与える。
  • 詳細は後日別記事にする(かも)。

6-3 「有効範囲と記憶域期間」(p222~229)

有効範囲

Javaで勉強した「グローバル変数」「ローカル変数」と同じ概念

ファイル有効範囲
  • 識別子が宣言された直後からソースファイル終わるまでで利用可能
ブロック有効範囲
  • 識別子が宣言された直後から、それを含むブロック終端までで利用可能

記憶域期間

静的記憶域期間
  • staticを用いて関数内で宣言されたオブジェクト(変数)はプログラム終了まで破棄されない
//関数内での宣言
static int a;
  • 関数が何度呼び出されても、staticをつけて宣言された変数の値は前回呼出し終了時の値が引き継がれる。
自動記憶域期間
  • 関数内でstaticを用いずに宣言されたオブジェクト(変数)。
  • プログラムが宣言されたブロック内を過ぎるとオブジェクトは破棄される。

6-4 「多重定義とインライン関数」(p230~235)

関数の多重定義

  • 仮引数の個数や種類が異なる同名の関数を定義することができる(Javaにおけるメソッドのオーバーロードと同じ)。
  • 仮引数の並び、個数をシグネチャという。

インライン関数

  • inline 戻り値の型 識別子(引数)
// インライン関数の宣言
inline void sum(int a, int b);
  • コンパイル時に関数の中身が展開されて埋め込まれる。
  • 関数の呼出しが行が行われないため、実行速度向上が期待できる。

参考文献

【新・明快C++入門】学習メモ(6-1章)

『新・明快C++入門』(柴田)第6章(関数)

6-1「関数とは」(p188~215)

C++における関数のルール

  • main関数で使用する関数を、main関数より後ろに記述するとコンパイルエラー。
  • 先頭で関数宣言しておけば大丈夫。
#include <iostream>

using namespace std;

//関数宣言(仮引数名は省略可能)
int hoge(int, double, char);

int main()
{
    //関数呼出し
    hoge(1, 2.0, 'a');
}

//main関数以降に関数を配置できる。
int hoge(int a, double b, char c)
{
    //---処理内容---//
}


デフォルト実引数

  • 実引数が省略された時に仮引数に与える値。
  • 関数呼び出し時に実引数を渡せばそれが仮引数に入れられる。
  • 関数宣言時に引数の後ろから順に、途中の引数を飛ばさずに設定可能。
#include <iostream>

using namespace std;

//bとcがデフォルト引数
void sum(int a, int b=10, int c=100)
{
    cout << a + b + c << '\n';
}

int main(){
    //sum()はコンパイルエラー
    
    sum(1);
    sum(1, 2);
    sum(1, 2, 3);
}

実行結果

111      // 1 + 10 + 100
103     // 1 + 2 + 100
6       // 1 + 2 + 3


ビット演算子、シフト演算子

参考文献

【C++】列挙型(enum型)の確認

 はじめに

C++の勉強を行なっていて、列挙型(enum型)というものに出くわしました。
初めて勉強したことなので、記憶を定着させるために列挙型の基本をまとめていきたいと思います。

目次

  • 列挙型とは?
    • 列挙型の定義
    • 列挙型の構造と使い方
  • 応用的な使い方
    • switch文といっしょに使う
    • 列挙子の値を変更してみる
  • まとめ
  • 参考文献

列挙型とは

列挙型の定義

列挙型とはデータ型(intやcharなど)のひとつです。
整数値に特定の名前を付与して、それらの整数値をまとめて管理できるようにしたものが列挙型になります。

列挙型の構造

列挙型は以下のように宣言して使用することができます。

//enum型の定義
enum 列挙型名 {列挙子[1],  列挙子[2], 列挙子[3]・・・};

//enum型の宣言
列挙型名 変数名 (初期化子);

具体的なソースコードは以下の通りです。

#include <iostream>

using namespace std;

int main()
{
    //enum型の定義
    enum color { Red, Blue, White, Black };

    //enum型の宣言
    color favoriteColor = Red; 
    color imageColor = Blue;

    cout << "好きな色の番号は:" << favoriteColor << '\n';
    cout << "自分のイメージカラーの番号は:"  <<  imageColor << '\n';
}

実行結果

好きな色の番号は:0
自分のイメージカラーの番号は:1


このように、列挙型を宣言した後に列挙子を代入することで、列挙子に対応した数値を表すことができます。数値は宣言時に0, 1, 2...の順に自動で割り振られ、自分で自由に割り振ることもできます(後述)。

応用的な使い方

列挙型の応用的な使い方を紹介します。

switch文といっしょに使う

列挙型はswitch文と併用すると効果的です。

#include <iostream>

using namespace std;

int main()
{
    //enum型の定義
    enum season {Spring, Summer, Autumn,  Winter, Invalid};

    int type;
    cout << "好きな季節を入力してください\n";
    
    //好きな季節を番号で入力
    do {
        cout << "春->0, 夏->1,  秋-> 2, 冬-> 3, 終了-> 4 \n";
        cin >> type;
    } while ( type < Spring  ||  type > Invalid);

    if(type !=  Invalid){
        //int型typeをseason型にキャスト
        season selected = static_cast<season>(type);
        switch(selected) {
            case Spring : 
                cout  << "桜\n"; 
                break;
            case Summer : 
                cout << "海\n"; 
                break;
            case Autumn : 
                cout << "紅葉\n"; 
                break;
            case Winter : 
                cout << "雪\n";
                break;
        }
    }
}

実行結果

好きな季節を入力してください
春->0, 夏->1,  秋-> 2, 冬-> 3, 終了-> 4 
3
雪


このように、do~while文の継続条件switch文のcase判定に列挙子を用いることがdけえきます。
単なる数値ではなく意味のある名前を用いて条件を判定するため、ソースコードを読みやすくすることができます。

列挙子の値を変更してみる

それぞれの列挙子に対応した数値を変更することも可能です。

#include <iostream>

using namespace std;

int main()
{
    //enum型の定義
    enum enghlishNumber {One = 1, Two, Three, Four, Five, Ten = 10, Eleven};
        
    //enum型の宣言と代入
    enghlishNumber en01, en03, en10, en11;
    en01 = One;
    en03 = Three;
    en10 = Ten;
    en11 = Eleven;
    
    cout << "One: " << en01 << '\n';
    cout << "Three: " << en03 << '\n';
    cout << "Ten: " << en10 << '\n';
    cout << "Eleven: " << en11 << '\n';
}

実行結果

One: 1
Three: 3
Ten: 10
Eleven: 11


このように、列挙子に対応する数値を1から始めたり、また途中で数値を変更したりすることができます。
手動で割り振った場合、それ以降の数値は前の値に1を足した値になります。

まとめ

列挙型(enum型)についてみてきました。
列挙型を使うことで特定の値に特定の名前をつけることができるため、特定名を用いた条件判定を行うことができます。
また、列挙子には自動で数値が割り振られるため、いちいち定置オブジェクトとして宣言するよりも楽にミスなく定義することが可能です。
そのため、列挙型を使うことができる場合にはすすんで使用するべきです。

参考文献