目次

なんとなく、逆引きインデックスも作ってみましたのでそちらもどうぞ。

変数

まずは変数について解説します。ポインタを理解する上で基礎となる部分ですので、しっかり理解しておきましょう。このページが苦なく読めるレベルであれば、ポインタについてもすぐに理解できると思います。

変数とは?

変数とは、「文字や数値など、データを格納することのできる領域」のことです。

実際の使われ方に即して言うと、単に「データを一時的に保存しておきたいときに使うもの」といったところでしょうか。

#include <stdio.h>

int main()
{
    int foo;
    .....
    return 0;
}

例えば整数型変数fooの宣言は上のようにするのでした。

※以下、ソースコードは適宜include文や関数宣言を省きます。

変数とメモリ

変数の値はパソコン内のメモリと呼ばれる場所に格納されています。格納されている値を参照するには、その場所=メモリアドレス(番地)を知っておく必要があります。

が、変数名とメモリアドレスは1対1で関連付けられているので、変数から値を取り出す際はこのことを意識しなくてもよいようになっています。

メモリと変数の関係

しかしこのことは後々ポインタを理解していく上で非常に重要となってきます。イメージだけでも今のうちにつかんでおきましょう。

変数のスコープ

ある変数の「スコープ」とは、「その変数の名前が有効な範囲」のことです。

そしてC言語における変数のスコープは、原則として「その変数の宣言がある最も内側のブロックの内部」となります。スコープの外では、同じ名前の別の変数を宣言することも可能です。

※ブロックとは"{"と"}"で囲まれた部分のことです。

やはり、例を見てみましょう。

int main()
{
    int foo;
    ....
    if(....)
    {
        int bar;
    }
    ....
}

この場合、fooのスコープはmain関数全体、barのスコープはif文の中のみとなります。if文の外(前でも後ろでも)で変数barを使うことはできません。

別の例も見てみましょう。

void hoge(void)
{
    int foo = 50;
}

int main()
{
    int foo=100;
    printf("%d\n",foo);
    hoge();
    printf("%d\n",foo);
    return 0;
}

これを実行すると、

100
100

と表示されます。main関数のfooとhoge関数のfooは互いのスコープ外、つまり別物なので、hoge関数でfooが変更されるようなことはありません。

さて、では次の例ではどうでしょうか。

void hoge(int foo)
{
    foo = 50;
}

int main()
{
    int foo=100;
    printf("%d\n",foo);
    hoge(foo);
    printf("%d\n",foo);
    return 0;
}

太字部分が主な変更点です。一見、main関数とhoge関数が変数fooで繋がっているような印象を受けるかも知れませんが、結果は先ほどと同じです。

hoge関数にはfooの、つまり「100」を渡しただけですし、hoge関数のfooは、引数として新たに宣言されたものにすぎないからです。今の二つの結果は、hogeのfooを全て別の名前にしておけば明らかですよね。

※関数の引数は{〜}の外で宣言を行っていますが、スコープはその関数内になります。

しかし、「グローバル変数」というものを使えば、関数間で同じ変数を共有することが可能です。グローバル変数は、すべてのブロックの外側で宣言をした変数です。

int foo;

void hoge()
{
    foo = 50;
}

int main()
{
    foo=100;
    printf("%d\n",foo);
    hoge();
    printf("%d\n",foo);
    return 0;
}

これだと、

100
50

と表示されます

しかし、グローバル変数はメンテナンス性を低下させる恐れがあったり、メモリを無駄遣いしてしまう等の理由からあまり好まれません。特に、多人数で大きなプログラムを書くときに不用意に使うと、他のメンバーから白い目で見られかねません(笑)。

そこでポインタの登場です。ポインタを使えば、グローバル変数を使わなくても値の受け渡しを行うことができるようになります。

※勿論、「グロバール変数を使った方がいい場面」もないわけではありません。

Point!

  • 変数の本体は、メモリの一部分
  • メモリは、アドレスを指定することでその場所の値を参照できる
  • 変数の名前は、その宣言があった最も内側のブロック内でのみ有効(スコープ)
  • グローバル変数はどこからでも参照できるが、欠点も多いので注意

生兵法なので、怪我しないようにね。

inserted by FC2 system