static作用の詳細


1.まず最初に紹介するのも最も重要な1つです:隠す
複数のファイルを同時にコンパイルすると、static接頭辞を付けないグローバル変数と関数はすべてグローバル可視性を有します.この言葉を理解するために、例を挙げて説明します.2つのソースファイルを同時にコンパイルします.1つはa.cで、もう1つはmainです.c.
以下はa.cの内容です.
 char a = 'A'; // global variable
void msg()
{
printf("Hello/n");
}

次は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つ目の役割は、変数コンテンツの持続性を維持することです.
静的データ領域に格納された変数は、プログラムの実行が開始されると初期化が完了し、唯一の初期化です.両方の変数が静的ストレージ領域に格納されます.グローバル変数とstatic変数ですが、グローバル変数に比べてstaticは変数の可視範囲を制御することができます.staticはあくまでstaticが隠すために使用されます.このような使い方はよくありませんが、例を挙げます.
 #include <stdio.h>
int fun(void){
static int count = 10; //
return count--;
}
int count = 1;
int main(void)
{
printf("global/t/tlocal static/n");
for(; count <= 10; ++count)
printf("%d/t/t%d/n", 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 <stdio.h>
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を備えている.
4.staticで宣言した関数と変数の小結
staticが宣言した変数には、C言語で2つの特徴があります.
 
1)、変数はプログラムのグローバル記憶領域に配置され、次の呼び出し時にも元の付与値を維持することができる.この点はスタック変数とスタック変数との違いです.
2)、変数はstaticでコンパイラに知らせ、自分は変数の作用範囲内でしか見られない.この点は、グローバル変数との違いです.
Tips:A.グローバル変数が単一のCファイルにのみアクセスされる場合、この変数を静的グローバル変数に変更してモジュール間の結合度を低減することができる.B.グローバル変数が単一の関数のみからアクセスされる場合、この変数をその関数の静的局所変数に変更して、モジュール間の結合度を低減することができる.C.動的グローバル変数、静的グローバル変数、静的ローカル変数にアクセスする関数を設計し、使用する場合、再入問題を考慮する必要がある.D.再入力可能な関数が必要な場合は、関数にstatic変数(このような関数は「内部メモリ」機能付きの関数と呼ばれる)E.関数にstatic変数を使用する必要はありません.たとえば、関数の戻り値がポインタタイプの場合、戻り値としてstaticのローカル変数のアドレスでなければなりません.autoタイプであれば、エラーポインタとして返されます.
関数にstaticを付けると、関数が静的関数になります.ただし、ここで「static」の意味は、格納方式ではなく、関数に対する役割ドメインが本ファイルに限られている(したがって内部関数とも呼ばれる)ことを意味する.内部関数を使用するメリットは、異なる人が異なる関数を作成するときに、自分で定義した関数が他のファイルの関数と同じ名前になるかどうかを心配する必要がないことです.
拡張分析:
用語staticは尋常ではない歴史を持っている.最初、Cにキーワードstaticを導入したのは、ブロックを終了しても存在するローカル変数を表すためである.その後、staticはCにおいて2つ目の意味を持つ:他のファイルにアクセスできないグローバル変数と関数を表す.新しいキーワードの導入を避けるためにstaticキーワードを使用して、この2つ目の意味を表します.最後に、C++はこのキーワードを再利用し、Javaのこのキーワードの意味と同じで、クラスに属していることを示す変数と関数(Javaのこのキーワードの意味と同じ)とは異なる3つ目の意味を与えます.
グローバル変数、静的グローバル変数、静的ローカル変数、およびローカル変数の違い
変数は、グローバル変数、静的グローバル変数、静的ローカル変数、およびローカル変数に分けられます.
         
ストレージ領域別に、グローバル変数、静的グローバル変数、および静的ローカル変数は、メモリの静的ストレージ領域に格納され、ローカル変数はメモリのスタック領域に格納されます.
         
役割ドメイン別に、グローバル変数はプロジェクトファイル全体で有効です.静的グローバル変数は、定義されたファイル内でのみ有効です.静的ローカル変数は定義された関数内でのみ有効であり、プログラムはメモリを1回しか割り当てず、関数が戻った後、この変数は消えない.ローカル変数は定義された関数内で有効ですが、関数が返されると無効になります.
グローバル変数(外部変数)の説明の前にstaticを冠して静的グローバル変数を構成する.グローバル変数自体が静的記憶方式であり、静的グローバル変数ももちろん静的記憶方式である.どちらもストレージ方式に違いはありません.この両者の違いは、非静的グローバル変数の役割ドメインがソースプログラム全体であるが、1つのソースプログラムが複数のソースファイルから構成されている場合、非静的グローバル変数は各ソースファイルで有効である.静的グローバル変数は、変数を定義するソースファイル内でのみ有効であり、同じソースプログラムの他のソースファイルでは使用できない役割ドメインを制限します.静的グローバル変数の役割ドメインは1つのソースファイルに限られているため、そのソースファイル内の関数にのみ共通であるため、他のソースファイルでエラーが発生することを回避できます.
以上の解析から,局所変数を静的変数に変更すると,その記憶方式が変化し,生存期間が変化することが分かる.グローバル変数を静的変数に変更すると,その役割ドメインが変更され,その使用範囲が制限される.
static関数は通常の関数の役割ドメインとは異なります.このファイルのみです.現在のソースファイルでのみ使用される関数は内部関数(static)として説明し、内部関数は現在のソースファイルで説明および定義する必要があります.現在のソースファイル以外で使用できる関数については、ヘッダーファイルで説明する必要があります.これらの関数を使用するソースファイルには、このヘッダーファイルが含まれます.
staticグローバル変数と一般的なグローバル変数の違いは何ですか.staticグローバル変数は一度だけ初期化され、他のファイルユニットで参照されないようにします.staticローカル変数と普通のローカル変数の違いは何ですか:staticローカル変数は1回だけ初期化され、次は前回の結果値に基づいています.static関数と一般関数の違いは何ですか.static関数はメモリに1つしかありません.一般関数は呼び出しごとにコピーグローバル変数と静的変数を維持します.手動で初期化しない場合は、コンパイラによって0に初期化されます.ローカル変数の値はわかりません.