こんにちは、静的および外部ポインターの使用法は何ですか?? それらが存在する場合
5 に答える
いつ使用できるかについての質問に答えるために、いくつかの簡単な例を示します。
静的ポインターを使用して、常に同じバッファーをプログラムに返す関数を実装し、最初に呼び出されたときにそれを割り当てることができます。
char * GetBuffer() {
static char * buff = 0;
if ( buff == 0 ) {
buff = malloc( BUFSIZE );
}
return buff;
}
extern (つまりグローバル) ポインターを使用して、他のコンパイル単位が main のパラメーターにアクセスできるようにすることができます。
extern int ArgC = 0;
extern char ** ArgV = 0;
int main( int argc, char ** argv ) {
ArgC = argc;
ArgV = argv;
...
}
簡単な答え: それらは存在しません。C99 6.7.1 には、「宣言内の宣言指定子には、最大で 1 つのストレージ クラス指定子を指定できます」と記載されています。extern
とstatic
は両方ともストレージ クラス指定子です。
複数の翻訳単位でグローバルに使用できるようにするポインターがあるとします。1 つの場所 (foo.c) で定義したいのですが、他の翻訳単位で複数の宣言を許可します。「extern」キーワードは、これがオブジェクトの定義宣言ではないことをコンパイラに伝えます。実際の定義は別の場所に表示されます。リンカーがオブジェクト名を使用できるようにするだけです。コードがコンパイルおよびリンクされると、すべての異なる翻訳単位がその名前で同じオブジェクトを参照します。
1 つのソース ファイル内の関数でグローバルに使用できるようにしたいが、他の翻訳単位からは見えないようにしたいポインタもあるとします。「静的」キーワードを使用して、オブジェクトの名前がリンカーにエクスポートされないことを示すことができます。
1 つの関数内でのみ使用したいポインターもあるが、そのポインターの値は関数呼び出し間で保持されているとします。オブジェクトに静的な範囲があることを示すために、"static" キーワードを再度使用できます。そのためのメモリはプログラムの起動時に割り当てられ、プログラムが終了するまで解放されないため、オブジェクトの値は関数呼び出し間で保持されます。
/**
* foo.h
*/
#ifndef FOO_H
#define FOO_H
/**
* Non-defining declaration of aGlobalPointer; makes the name available
* to other translation units, but does not allocate the pointer object
* itself.
*/
extern int *aGlobalPointer;
/**
* A function that uses all three pointers (extern on a function
* declaration serves roughly the same purpose as on a variable declaration)
*/
extern void demoPointers(void);
...
#endif
/**
* foo.c
*/
#include "foo.h"
/**
* Defining declaration for aGlobalPointer. Since the declaration
* appears at file scope (outside of any function) it will have static
* extent (memory for it will be allocated at program start and released
* at program end), and the name will be exported to the linker.
*/
int *aGlobalPointer;
/**
* Defining declaration for aLocalPointer. Like aGlobalPointer, it has
* static extent, but the presence of the "static" keyword prevents
* the name from being exported to the linker.
*/
static int *aLocalPointer;
void demoPointers(void)
{
/**
* The static keyword indicates that aReallyLocalPointer has static extent,
* so the memory for it will not be released when the function exits,
* even though it is not accessible outside of this function definition
* (at least not by name)
*/
static int *aReallyLocalPointer;
}
簡潔な答え。static は永続的であるため、関数で宣言すると、関数を再度呼び出すと、値は前回と同じになります。グローバルに宣言すると、そのファイルでのみグローバルになります。
Extern は、グローバルに宣言されているが別のファイルで宣言されていることを意味します。(基本的に、この変数が存在し、これが定義されていることを意味します)。
C で extern キーワードを正しく使用する方法を参照してください。
基本的に、(標準 C の) "静的" を関数で使用すると、関数が終了すると通常のように変数が消去されなくなります (つまり、関数が呼び出されるたびに古い値が保持されます)。「Extern」は、変数のスコープを拡張して、他のファイルで使用できるようにします (つまり、グローバル変数にします)。