static関数の役割
2573 ワード
C言語ではstaticの字面の意味が私たちを迷わせやすいが、実はその役割は3つある.
(1)まずその第1条を紹介するのも最も重要な1条です:隠す.
複数のファイルを同時にコンパイルすると、static接頭辞を付けないグローバル変数と関数はすべてグローバル可視性を有します.この言葉を理解するために、例を挙げて説明します.2つのソースファイルを同時にコンパイルします.1つはa.cで、もう1つはmainです.c.
以下はa.cの内容です
A Hello
a.cで定義されたグローバル変数aと関数msgがmainにある理由を聞くかもしれません.cで使う?前述したように、static接頭辞を付けていないグローバル変数と関数はすべてグローバル可視性を持ち、他のソースファイルにもアクセスできます.この例では、aはグローバル変数である、msgは関数であり、static接頭辞を付けていないため、別のソースファイルmainについてである.cは可視です.
staticを追加すると、他のソースファイルが非表示になります.例えばaとmsgの定義の前にstatic,mainを加える.cはそれらが見えなくなった.このプロパティを使用すると、名前の競合を心配することなく、異なるファイルで同じ名前の関数と同じ名前の変数を定義できます.Staticは関数と変数の接頭辞として使用でき、関数にとってstaticの役割は非表示に限られ、変数に対してstaticには次の2つの役割があります.(2)staticの第2の役割は、変数の内容を永続的に保持することである.静的データ領域に格納された変数は、プログラムの実行開始時に初期化が完了し、唯一の初期化でもある.静的記憶領域に格納される2つの変数は、グローバル変数とstatic変数であるが、グローバル変数に比べて、staticは変数の可視範囲を制御することができ、あくまでstaticであるやはり隠すために使われています.このような使い方はよくありませんが、例を挙げます.
プログラムの実行結果は次のとおりです.
global local static
1 10
2 9
3 8
4 7
5 6
6 5
7 4
8 3
9 2
10 1
(3)staticの3つ目の役割は、デフォルトで0に初期化することです.グローバル変数もこの属性を備えています.グローバル変数も静的データ領域に格納されているからです.静的データ領域では、メモリ内のすべてのバイトのデフォルト値が0 x 00で、場合によってはプログラマの作業量を減らすことができます.例えば、疎行列を初期化することで、すべてのメタを1つずつ素はすべて0に置いて、それから0ではないいくつかの元素を割り当てます.静的に定義すると、最初に0を置く操作が省けます.たとえば文字配列を文字列として使うとしても、文字配列の末尾に「0」をつけるたびに面倒だと感じます.文字列を静的に定義すれば、そこはもともと'0'だったので、この面倒を省くことができます.小さな実験をして検証してみてはいかがでしょうか.
プログラムの実行結果は以下の通りです.
integer: 0; string: (begin)(end)
最後にstaticの3つの役割について一言でまとめます.まずstaticの最も主要な機能は非表示であり、次にstatic変数が静的ストレージ領域に格納されるため、持続性とデフォルト値0を備えている.
(1)まずその第1条を紹介するのも最も重要な1条です:隠す.
複数のファイルを同時にコンパイルすると、static接頭辞を付けないグローバル変数と関数はすべてグローバル可視性を有します.この言葉を理解するために、例を挙げて説明します.2つのソースファイルを同時にコンパイルします.1つはa.cで、もう1つはmainです.c.
以下はa.cの内容です
char a = 'A'; // global variable
void msg()
{
printf("Hello
");
}
の下にmainがあります.cの内容int main(void)
{
extern char a; // extern variable must be declared before use
printf("%c ", a);
(void)msg();
return 0;
}
プログラムの実行結果は次のとおりです.A Hello
a.cで定義されたグローバル変数aと関数msgがmainにある理由を聞くかもしれません.cで使う?前述したように、static接頭辞を付けていないグローバル変数と関数はすべてグローバル可視性を持ち、他のソースファイルにもアクセスできます.この例では、aはグローバル変数である、msgは関数であり、static接頭辞を付けていないため、別のソースファイルmainについてである.cは可視です.
staticを追加すると、他のソースファイルが非表示になります.例えばaとmsgの定義の前にstatic,mainを加える.cはそれらが見えなくなった.このプロパティを使用すると、名前の競合を心配することなく、異なるファイルで同じ名前の関数と同じ名前の変数を定義できます.Staticは関数と変数の接頭辞として使用でき、関数にとってstaticの役割は非表示に限られ、変数に対してstaticには次の2つの役割があります.(2)staticの第2の役割は、変数の内容を永続的に保持することである.静的データ領域に格納された変数は、プログラムの実行開始時に初期化が完了し、唯一の初期化でもある.静的記憶領域に格納される2つの変数は、グローバル変数とstatic変数であるが、グローバル変数に比べて、staticは変数の可視範囲を制御することができ、あくまでstaticであるやはり隠すために使われています.このような使い方はよくありませんが、例を挙げます.
#include
int fun(void){
static int count = 10; //
return count--;
}
int count = 1;
int main(void)
{
printf("global\t\tlocal static
");
for(; count <= 10; ++count)
printf("%d\t\t%d
", count, fun());
return 0;
}
プログラムの実行結果は次のとおりです.
global local static
1 10
2 9
3 8
4 7
5 6
6 5
7 4
8 3
9 2
10 1
(3)staticの3つ目の役割は、デフォルトで0に初期化することです.グローバル変数もこの属性を備えています.グローバル変数も静的データ領域に格納されているからです.静的データ領域では、メモリ内のすべてのバイトのデフォルト値が0 x 00で、場合によってはプログラマの作業量を減らすことができます.例えば、疎行列を初期化することで、すべてのメタを1つずつ素はすべて0に置いて、それから0ではないいくつかの元素を割り当てます.静的に定義すると、最初に0を置く操作が省けます.たとえば文字配列を文字列として使うとしても、文字配列の末尾に「0」をつけるたびに面倒だと感じます.文字列を静的に定義すれば、そこはもともと'0'だったので、この面倒を省くことができます.小さな実験をして検証してみてはいかがでしょうか.
#include
int a;
int main(void)
{
int i;
static char str[10];
printf("integer: %d; string: (begin)%s(end)", a, str);
return 0;
}
プログラムの実行結果は以下の通りです.
integer: 0; string: (begin)(end)
最後にstaticの3つの役割について一言でまとめます.まずstaticの最も主要な機能は非表示であり、次にstatic変数が静的ストレージ領域に格納されるため、持続性とデフォルト値0を備えている.