ファイル分割(C、C++)
メリット
- 複数のプロジェクト(プログラム)間での関数・クラスの再利用を簡易化
- コンパイル時間の短縮化
- ソースファイルの可変性を高める
デメリット
- グローバル変数の受け渡し
- 多重インクルード(ヘッダーでヘッダーの読み込みを避けること推奨)
- ソースの量の増加
example_before.c
#include <stdio.h>
// この関数があることを周知させる
// (関数のプロトタイプ宣言)
void PrintfHelloWorld(void);
int main(void)
{
// 実行(関数の呼び出し)
PrintfHelloWorld();
return 0;
}
/// <summary>
/// Hello Worldを出力する
/// (関数の定義)
/// </summary>
void PrintfHelloWorld(void)
{
printf("Hello World");
}
example_after.h
#ifndef EXAMPLE_H_INCLUDED // インクルードガード
#define EXAMPLE_H_INCLUDED // インクルードガード
// この関数があることを、
// ヘッダーを読み込んだcファイルに周知させる
void PrintfHelloWorld(void);
#endif // !EXAMPLE_H_INCLUDED(インクルードガード)
※#ifndef、#define、#endif
ヘッダーを多重に読み込まないようにする(インクルードガード)
example_after_sub.c
#include "example_after.h"
#include <stdio.h>
/// <summary>
/// Hello Worldを出力する
/// (関数の定義)
/// </summary>
void PrintfHelloWorld(void)
{
printf("Hello World");
}
example_after_main.c
#include "example_after.h"
int main()
{
// 実行(関数の呼び出し)
PrintfHelloWorld();
return 0;
}
関数のオーバーロード
用途 : より再利用できるようにするため、引数の対応幅を広げる
int Add(int a, int b) { return a + b }
float Add(float a, float b) { return a + b }
インライン関数(簡単に説明できない、スマン)
処理が少なく、呼び出し回数が多い関数は
(※)関数呼び出しのオーバーヘッド がもったいないので...
用途 : 関数呼び出しのオーバーヘッドを削減する
inlineとは関数呼び出しの箇所に関数本体のコードを直接埋め込むことを
コンパイラに指示する機能
- (※)関数呼び出しのオーバーヘッド
- 実行中のプログラムから、呼び出したい関数の最初の命令へジャンプ(関数へのジャンプ)
- 関数に渡す値(引数)を、関数内で使えるようにメモリ上に配置(引数の受け渡し)
- 関数の終了後、元のプログラムに戻ってくるためのアドレスを記憶(戻りアドレスの保存)
- 関数内の処理を実行(関数の実行)
- 関数が計算した結果(戻り値)を、呼び出した元の場所へ(戻り値の受け取り)
- 関数が終了した後、記憶しておいた戻りアドレスへジャンプして、
元のプログラムの実行に戻る。
// 従来の関数
int PlusOne(int num)
{
return num + 1;
}
// インライン関数
inline int PlusOne(int num)
{
return num + 1;
}
※inlineを付けた関数は定義しなければならない
名前空間(C++、C#)
用途 : 同名の命名がなされているものを区別する
C++
namespace
{
宣言・定義
}
example.cpp
#include <iostream>
namespace One
{
inline void PrintfHelloWorld(void)
{
std::cout << "Hello World 1" << std::endl;
}
}
namespace Two
{
inline void PrintfHelloWorld(void)
{
std::cout << "Hello World 2" << std::endl;
}
}
int main(void)
{
One::PrintfHelloWorld();
Two::PrintfHelloWorld();
return 0;
}
C#
example.cs
using System;
namespace One
{
public class Sample
{
public static void PrintfHelloWorld()
{
Console.WriteLine("Hello World");
}
}
}
namespace Two
{
public class Sample
{
public static void PrintfHelloWorld()
{
Console.WriteLine("Hello World2");
}
}
}
class Program
{
static void Main()
{
One.Sample.PrintfHelloWorld();
Two.Sample.PrintfHelloWorld();
}
}