Project_OKI’s diary

エンジニアの勉強ブログ

C言語基礎知識34(静的変数、static修飾子について)

静的変数、static修飾子について

この記事では、C言語における静的変数と、static修飾子について記載する。

 

1. 目的

 ・静的変数とstatic修飾子の意味について知る。

 ・C言語で静的変数とstatic修飾子の使い方を知る。

 

目次

 

2. 静的変数とは

 ・最初にメモリ上に領域を確保して、最後まで同じ場所を使い続ける変数のこと。

 ・プログラムにおいて特定の関数などで共有され、値を保持し、使いまわすことが出来る。

 ・通常、関数内でローカル変数作成した場合、関数が終了すると、

  次の関数実行時には、値はリセットされる。

  これを動的変数という。

 

 ・静的変数を使用すると、値が保持された状態になる。

 ・静的変数を使用するのに、static修飾子を使用する。

  (staticとは静的という意味)

 

3. static修飾子とは

 ・static:静的なという意味

 ・記憶クラス指定子のひとつ

 ・ローカル変数を静的領域に配置する。

  →通常関数内の変数は、次回呼び出した場合、値を保持していないが、

   satic修飾子を使用すると、値が保持され、次回呼び出し時にもその値となる。

 ・グローバル変数や関数の有効範囲を制限する。(他のファイルからのアクセス制限)

 ・関数のブロックスコープで使用すると、その変数又は、関数はそのブロック内でのみ有効となる。

 

 3.1静的変数(static修飾子)の使い方

 ・必要ヘッダファイル:string.h

 ・static修飾子を使用する。

 → static 変数型 変数名;

 例:

     static int scounter = 0;    // 静的変数の宣言
 
 3.2 静的変数を使用したプログラム

  (1) satic修飾子を使用すると、値が保持され、次回呼び出し時にその値が保持されている。

#include <stdio.h>

void exampleFunction() {
    static int scounter = 0;    // 静的変数の宣言
    int dcounter = 0;           // 動的変数の宣言
    scounter++; // 変数の値をインクリメント
    dcounter++;
    printf("Static Counter: %d\n", scounter);
    printf("Dynamic Coutner: %d\n",dcounter);
}

int main() {
    exampleFunction(); // Counter: 1
    exampleFunction(); // Counter: 2
    exampleFunction(); // Counter: 3
    return 0;
}

実行結果:https://paiza.io/projects/vCI7NohiApZDtY0DPj3Sww

 

 ・プログラム説明

  (a) exampleFunctionが実行されるたびに、scounter及びdcounterを+1する。

  (b) scounterは、静的変数の為、2回目にexampleFunctionが実行されると、2になる。

   dcounterは、通常の変数(動的変数)の為、2回目にexampleFunctionが実行されても、1になる。

 

 

 (2) グローバル変数や関数の有効範囲を制限する。(他のファイルからのアクセス制限)

//main.cファイル
#include <stdio.h>
#include "sub.h"

int main() {
    //staticFunction(); // staticで使用されている為、ここでは使えない。
    func1();
    return 0;
}
//sub.cファイル
#include <stdio.h>
#include "sub.h"

//プロトタイプ関数宣言(ファイル内)
static void staticFunction();

void func1(){
    staticFunction();   ///静的関数を呼び出し
}

// ファイル内の静的関数
static void staticFunction(){
    printf("This is a static function.\n");
}
//sub.hファイル
void func1();

実行結果:https://paiza.io/projects/n03zb2EIbvQ2kNQLl1QDLA?language=c

 

上記staticFunction関数は、staticを用いて、sub.cで作成している為、

sub.cファイル内でしか使用できない。

main.c内で使用しようとするとエラーになる。

 

 

 (3) 関数のブロックスコープで使用すると、その変数又は、関数はそのブロック内でのみ有効となる。

#include <stdio.h>
int main(void){
    // Your code here!
     int i;
    for (i = 0; i < 3; i++) {
        static int blockStaticVar = 0;  // ブロックスコープ内の静的変数
        blockStaticVar++;               // +1
        printf("Block static variable: %d\n", blockStaticVar);
    }

    // blockStaticVarはこのスコープ外では無効
    // printf("Outside block: %d\n", blockStaticVar); // エラー
    return 0;
}

 実行結果:https://paiza.io/projects/2WZJitA9S1VFZjSnkd_bzw?language=c

 

 3.4 静的変数の特徴

 有効範囲(Scope):
  静的変数は、宣言されたブロック(関数内の場合)又は

  ファイル(関数外の場合)内でのみアクセス可能。

 

  関数内の静的変数は、その関数内でのみ有効。

  関数外の静的変数は、そのファイル内のどの関数からでもアクセス可能。

 

 寿命(Lifetime):
  静的変数は、プログラムが実行される間ずっと存在し、メモリを占有する。

  関数内の静的変数は、関数が呼び出されたときに初期化されるが

  その値は関数呼び出しの間保持される。

  関数外の静的変数は、プログラムが終了するまでメモリを占有し続ける。

 

 初期化:
 静的変数は、明示的な初期化が行われない場合、ゼロまたはデフォルトの値で初期化される。

 関数内の静的変数は、最初の実行時に初期化され、以降の呼び出しでも初期化は行われない。

 

 ローカル状態の保持:
  静的変数は、関数内で使用される場合、その関数の複数の呼び出しの間で値を保持

する。

  つまり、関数が呼び出されるたびに変数が再初期化されない。

  関数間で情報の共有や永続的な状態の保持などの用途に使用れる。

  

  関数内でのみ使用される場合でも、静的な性質を持つため、

  そのメモリは関数呼び出しのたびに割り当てられる自動変数とは異なり、

  プログラムの実行中に保持され続ける。

 

関連記事

過去の記事:

知らないと損するお金の話(ふるさと納税、確定申告とワンストップ納税どっちが得?) - Project_OKI’s diary

C言語基礎知識6(関数) - Project_OKI’s diary

C言語基礎知識7(構造体1) - Project_OKI’s diary

C言語基礎知識8(enum:列挙型) - Project_OKI’s diary

C言語基礎知識9(typedef) - Project_OKI’s diary

C言語基礎知識10(extern宣言) - Project_OKI’s diary

C言語基礎知識11(#define) - Project_OKI’s diary

 

組み込みC言語

https://wa3.i-3-i.info/word11860.html

https://chat.openai.com/?model=text-davinci-002-render-sha

https://chat.openai.com/?model=text-davinci-002-render-sha