static と extern は、変数のスコープと有効期間を定義する C のストレージ クラスです。 C の変数と同様に、これらのキーワードをさまざまなユース ケースのポインタと共に使用できます。
目次:
<オール>始めましょう。
C/C++ の静的ポインター
静的 一度初期化された変数は、プログラムが終了するまで存在します。これらの変数は、スコープの外に出た後でも値を保持します。宣言および初期化されると、再宣言されません。つまり、メモリが割り当てられると、そのプログラムが終了するまで存在します。以下に示す静的ポインター宣言。
static int * ptr; // A static pointer of type int is defined
この宣言は、ポインター自体が静的ストレージ期間を持つ必要があることを示しています。ポインターが指すもののストレージクラスについては何も言いません。このポインターに異なる値を割り当てるだけで、プログラムの実行中に異なる時点で変更される可能性があります。
これらの変数のスコープは、宣言されている場所によって異なります。変数が関数内で宣言されている場合、それらのスコープはローカルです。静的変数がグローバル領域で宣言されている場合、プログラム内またはその特定の C ファイル内のどこからでもアクセスできます。初期値 0 または NULL は、コンパイラによって割り当てられます。同じ例を以下に示します。
#include <stdio.h>
void foo(){
int a = 10, b = 20;
static int *c; //static pointer variable declaration
//re-declaration is not done in case of static variables
if(c == 0)
c = &a;
else
c = &b;
printf("value = %d\n", *c);
printf("address of pointer = %d\n", &c);
printf("address of memory pointed by pointer c = %d\n", c);
printf("address of a = %d\n", &a);
printf("address of b = %d\n", &b);
}
int main(){
foo();
foo();
}
出力:
value = 10
address of pointer = 4218932
address of memory pointed by pointer c = 6422204
address of a = 6422204
address of b = 6422200
value = 20
address of pointer = 4218932
address of memory pointed by pointer c = 6422200
address of a = 6422204
address of b = 6422200
上記のプログラムでは、関数 foo() が main() から呼び出されます。最初の反復では、コンパイラによって初期化された静的変数には '0' (ゼロ) が含まれているため、'a' の値が割り当てられ、静的変数であるため、関数の実行が完了した後もこれを保持します。そのため、foo() の 2 回目の反復では、静的ポインター 'c' が b の値に割り当てられます。出力ウィンドウでも同じことがわかります。静的ポインタのアドレスは、プログラムの実行中は一定です。ただし、それが指す場所は変更できます。
静的ポインターを使用して、常に同じバッファーをプログラムに返す関数を実装できます。これは、シリアル通信で役立ちます。
char * Buffer(){
static char *buff;
if(buff == 0)
buff = malloc( BUFFER-SIZE );
return buff;
}
C/C++ の外部ポインタ
外部 ストレージ クラスは、変数が大規模なプログラムの他の場所で定義されていることを指定します。変数を Extern として指定することにより、プログラマは、別の場所で宣言されている変数を、あたかもローカルで宣言されているかのように使用できます。外部変数は、他の場所で使用するために宣言された正当な値で初期化されたグローバル変数に他なりません。これらの変数はグローバルに 1 回だけ初期化できますが、必要に応じて何度でも宣言できます。 extern として宣言された変数にはメモリが割り当てられません。
#include <stdio.h>
void foo(){
int a = 11;
extern int *ptr;
//specifies compiler to search for this variable outside this function
printf("Default value = %d (NULL pointrer)\n", ptr);
ptr = &a;
printf("After assignment %d\n", *ptr);
}
int main(){
foo();
}
int *ptr; // Globle pointer declaration
// pointer initialized by compiler - null pointer
出力:
Default value = 0 (NULL pointrer)
After assignment 11
Exrern ポインターを使用すると、グローバルに使用可能なポインターを作成でき、さまざまなシナリオで役立ちます。その用途の 1 つは、他のファイルのメイン関数またはプロジェクトの関数からコマンド ライン引数にアクセスすることです。
extern int ArgC = 0;
extern char ** ArgV = 0;
int main( int argc, char ** argv ) {
ArgC = argc;
ArgV = argv;
...
}
OpenGenus でのこの記事を読めば、C/C++ での Static ポインターと extern ポインターの完全なアイデアが得られるはずです。