4-1 識別子とC++のキーワード
- 識別子は、関数や型、変数といった名前に相当するもののこと
- 概ね下記のルール
- 大文字小文字は区別
- 数字で始めることはできない
- アンダースコアで始まっても良い
- いくつか使用できないキーワードがある
- 識別子の付け方の3例
- スネークケース: アンダースコアで単語区切りを示す。
my_test_function
- アッパーキャメル: 各単語の最初の文字を大文字にする。
MyTestFunction
- ロワーキャメル: 最初の文字だけ小文字に、残りは各単語の最初の文字を大文字にする。
myTestFunction
- Boostや標準ライブラリではスネークケースが、Qtでは両キャメルケースが使われる
- キーワードは変数、関数名などには使えない
- 文脈依存キーワードは変数、関数名などに使えるが、好ましくない
- 代替表現も変数、関数名などに使えるが、好ましくない
- 暗黙的に定義される識別子は下記など
識別子 |
型 |
内容 |
__FILE__ |
文字列リテラル |
ソースファイル名 |
__LINE__ |
数値リテラル |
ソースコードの__LINE__ が出現した行番号 |
__func__ |
文字型の配列 |
関数名 |
__cplusplus |
数値リテラル |
c++としてコンパイルされたときのバージョン |
4-2 宣言と定義
- 宣言とは、変数や関数、クラスなどのプログラムを構成する何かの存在を伝えるもの
return-type function-name(parameters, ...);
struct struct-name;
class class-name;
union union-name;
enum class enum-name;
enum class enum-bame : underlying-type;
- 関数を事前に宣言しておくことで、定義がプログラムの後ろのほうにあっても関数を呼び出すことができる
- 定義は関数やクタスの中身がどのようになっているかを記述すること
- インスタンス化にはそのクラスがどのくらいのサイズのメモリを使用するのか知る必要があるが、宣言だけでは分からない
- ポインタや参照はアドレス値のみなので、定義がなくても引数、戻り値にできる
- ファイル分割を行う場合は、ヘッダファイルに宣言を、ソースファイルに定義を記述するといったテクニックが必要になる
- クラス定義中にメンバ関数の定義を記載することもできる
- クラス定義が長くなりやすいので、短い関数に限るべき
4-3 スコープ
- 変数の有効な範囲をスコープ、変数が有効になっている期間のことを生存期間という
- 関数定義の
{
から}
までを関数スコープという
- 関数スコープの中で定義された変数と仮引数は関数から処理が戻るときに破棄される
- ブレースで囲めばスコープを作れる
- グローバルスコープは
main
関数が呼ばれる前から終了するまで
global
変数はこのスコープが生存期間
- 関数の外側で定義された変数
static
変数もプログラム終了するまで生存する
global
変数もstatic
にできるが、その場合はファイルスコープな変数になる
static
変数は初期化することができるが、初期化はその宣言にたどり着いた一度目にしか行われない
static
変数は寿命が長い以外はローカル変数と違いがない
- グローバル変数は、どこで使われているか見通しが立てづらいので、
static
変数でもうまく記述できない場合にのみ使うべき
- すでに破棄されてしまっている変数をさしたポインタをダングリングポインタとよぶ
4-4 初期化構文付き条件分岐
- C++17で追加された機能
if
文, switch
文でもセミコロンを使って変数の初期化ができるようになった
if (type_name var_name = init_value; condition)
{
...
}
switch (type_name var_name = init_value; condition)
{
...
}
- 1ファイルの場合
- ソースファイルを実行形式ファイルに変換する手順をコンパイルと呼ぶ
- 複数ファイルの場合
- ソースファイルのヘッダファイルを読み込んだり、マクロの展開などの前処理をプリプロセスとよぶ
- プリプロセス済みソースをオブジェクトファイルに変換することをコンパイルとよぶ
- オブジェクトファイルを結合して、実行形式ファイルに変換する手順をリンクとよぶ
- これらをまとめてビルドとよぶ
extern
キーワードをつけると、実体を持たない変数を宣言できる
global
変数を複数ソースやヘッダファイルで宣言すると、それぞれのオブジェクトで実体をもってしまう
- グローバルスコープの変数でしか使えない
static
な変数なglobal
変数はそのソース内でしか使用できないのでextern
できない
static
変数はヘッダで定義してはいけない
extern type-name var-name;