staticな関数、変数

記憶クラス指定子のエントリで、関数内部の変数に static をつけるとその変数は関数を抜けても値を保持する、というようなことを書いた。

static にはもうひとつの使い方がある。
関数や、関数の外で宣言される変数に static をつけると、その関数や変数はファイルの中だけで有効になる。

これは、外部に公開したくない関数や変数をファイル内に隠蔽する効果がある。また、グローバル空間に公開されないので、関数や変数の名前が衝突することを避けることにもなる。

というわけで、ファイルの外部に公開しない関数や変数には static をつけておくのがいいようだ。

#include

#include "btree.h"

typedef struct tree {
    int value;
    struct tree *left;
    struct tree *right;
} Tree;

static Tree *Insert(Tree *root, int val);
static int Traverse(Tree *root, int ary[], int n);
static void FreeTree(Tree *root);

void BTreeSort(int ary[], const int n)
{
    int i;
    Tree *root = NULL;

    for (i = 0; i < n; i++) {
        root = Insert(root, ary[i]);
    }
    Traverse(root, ary, 0);
    FreeTree(root);
}

static Tree *Insert(Tree *root, int val)
{
    if (root == NULL) {
        root = (Tree *)malloc(sizeof(Tree));
        root->value = val;
        root->left = NULL;
        root->right = NULL;
    } else {
        if (val < root->value) {
            root->left = Insert(root->left, val);
        } else {
            root->right = Insert(root->right, val);
        }
    }

    return root;
}

static int Traverse(Tree *root, int ary[], int n)
{
    if (root->left != NULL) {
        n = Traverse(root->left, ary, n);
    }
    ary[n++] = root->value;
    if (root->right != NULL) {
        n = Traverse(root->right, ary, n);
    }

    return n;
}

static void FreeTree(Tree *root)
{
    if (root == NULL) {
        return;
    } else {
        FreeTree(root->left);
        FreeTree(root->right);
        free(root);
        return;
    }
}