4

プログラマーが変数conststatic. これらのキーワードの機能は理解できますが、なぜそれらを使用するのかわかりません。


The Official Guide to Learning OpenGL、バージョン 1.1 の2 章の例 1

    static GLint vertices[] = {25, 25,
                              100, 325,
                              175, 25,
                              175, 325,
                              250, 25,
                              325, 325};

    static GLfloat colors[] = {1.0, 0.2, 0.2,
                              0.2, 0.2, 1.0,
                              0.8, 1.0, 0.2,
                              0.75, 0.75, 0.75,
                              0.35, 0.35, 0.35,
                              0.5, 0.5, 0.5};

    glEnableClientState (GL_COLOR_ARRAY);
    glEnableClientState (GL_VERTEX_ARRAY);

    glColorPointer (3, GL_FLOAT, 0, colors);
    glVertexPointer (2, GL_INT, 0, vertices);

この単一のオブジェクトインスタンスでのみ使用されているのに、なぜこれらの配列を静的にする必要があるのでしょうか?


wikibooks チュートリアル 1OpenGL プログラミングの例 2

    GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);

    const char *fs_source =
    "#version 120           \n"
    "void main(void) {        "
    "  gl_FragColor[0] = 0.0; "
    "  gl_FragColor[1] = 0.0; "
    "  gl_FragColor[2] = 1.0; "
    "}";

    glShaderSource(fs, 1, &fs_source, NULL);

fs_source char 配列は、設定後に変更されません。しかし、それを一定にすることは絶対に必要ですか?パフォーマンスは向上しますか?

4

3 に答える 3

4

私はこれらのキーワードが何をするかを理解しています。

あなたは?

しかし、なぜ彼らがそれらを使用するのかわかりません。

あなたは?!

この単一のオブジェクトインスタンスでのみ使用されている場合、これらの配列を静的にする必要があるのはなぜですか?

何のオブジェクト?何のインスタンス?この例を引用した本は、C++ ではなく C で書かれており、C でオブジェクトとインスタンスを実装することは完全に可能ですが、言語自体には組み込みの定義がありませんこの1つのケースでは間違っています。

上記の例ではstaticがモジュール レベルでグローバル変数に適用されている場合。これの効果は、変数が定義されているコンパイル ユニットだけに変数が見えるということです。C プログラムでは、現在のコンパイル ユニットの外で参照されないすべての static を宣言することが一般的で推奨される方法です。

関数スコープ内の定数データで static を使用すると、関数が呼び出されるたびに変数の完全な初期化を行うオーバーヘッドが節約されます。

fs_source char 配列は、設定後に変更されません。

そして、あなたは実際にはできませんでした。C 言語は、 char配列の初期化の一部ではない文字列リテラルが型const char *であり、プログラム イメージの専用の読み取り専用セグメントに存在することを指定します。非初期化文字列リテラルの型は、const char *そのようなポインター変数をchar *呼び出しの未定義の動作に割り当てているためです。

しかし、それを一定にすることは絶対に必要ですか?

constを削除して でプログラムをコンパイルするとどうなるか試してください-Werr。これは実際には言語の正確さの問題です。

于 2012-08-21T23:36:16.980 に答える
4

はい、通常、パフォーマンス向上しますが、必ずしも想像どおりになるとは限りません。

これらのヒントを使用すると、コンパイラはさまざまな最適化 (スペースと時間の両方) を自由に選択できるため、プロセスのコードがより効率的になります。

たとえば、静的ストレージ期間変数(a)は、プログラムの起動時に一度初期化され、再度初期化する必要はありません。

何かを as としてマークするconstと、データが変更されないことが十分にわかっているため、コンパイラはより効率的なコードを生成できます。極端な例として、値を専用の CPU レジスタにロードし、メモリ内のデータを二度と見ないようにすることができます。

そうです、パフォーマンスを向上させることができます。これは、内部の同じ命令がより高速に実行される可能性があるためではなく、与えられた追加の知識に基づいてコンパイラがさまざまな命令を自由に使用できるためです。


(a) : それがあなたの持っている の意味であると仮定しますstatic。可視性の範囲を制限することに関して、キーワードが使用される他のいくつかのことがあります。これは、優れたプログラミングの実践です。

于 2012-08-21T23:04:26.510 に答える
1

私たちが話しているファイルでは、 varray.c (例 1):

この例の static はモジュール レベルで宣言されておらず、それらの可視性は関数内のみです。キーワードは、staticさまざまな時期にさまざまなことを意味しますが、この場合、他のコード ファイルからのアクセシビリティを制限するためではありません (ただし、スコープを関数のみに制限することにより、いずれにせよ起こります)。

これらの配列は、プログラムの実行中に一度だけ宣言/生成されます。これらの宣言の前に static キーワードを追加すると (setupPointers など)、これらのコード行 (59-64、65-70) は 1 回だけ実行され、ポインター自体は変更されず、それらの数値は "彼らはすでにそこにいるので、パイプを再び流れます(上記のパフォーマンスに関する回答を参照)。

これは、ユーザーがマウス ボタンをクリックすると、プログラムが 2 つの描画ルーチンを切り替えるためです。setupPointers関数が呼び出されるたびに配列を初期化するのではなく、一度だけ初期化するのが理にかなっています。

ええstatic、それはキーワードが機能する方法の1つであり、コンパイラーにこの変数を1回だけ初期化するように指示します。const似ていますが、「このメモリに一度だけ書き込む」という意味です。

それでは、なぜそれらをconstにしないのですか?と言うかもしれません。私は当然知っている?

おそらく、これらのリンクは人々を助けるでしょう:

varray.c

static キーワードに関するブログ投稿

于 2012-08-21T23:39:19.863 に答える