GNU/Linux >> Linux の 問題 >  >> Linux

LinuxCプログラミングチュートリアルパート10-可変スコープ

Cプログラミングチュートリアルシリーズをフォローしている場合は、変数の概念に注意する必要があります。変数の基本について説明しましたが、ここで説明する変数に関連するもう1つの重要な側面があります。変数のスコープ

以前のチュートリアルの1つで使用した値の交換コードから始めましょう:

#include <stdio.h>

void swap (int val1, int val2)
{
int temp = 0;

temp = val1;
val1 = val2;
val2 = temp;

printf("\nSwapped values are: %d and %d", val1,val2);

}

int main()
{
int a=0, b=0;

printf("Enter two integer values\n");

scanf("%d %d",&a,&b);

printf("Entered values are: %d and %d", a,b);

swap(a,b);

return 0;
}

ここで、このコードでは、変数「val1」と「val2」はローカルスコープを持っています。つまり、関数「swap」が呼び出されたときに有効になり、「swap」の呼び出しが終了するとすぐに終了します。関数「swap」の呼び出しの前後に「val1」と「val2」にアクセスすることはできません。同様に、変数「a」と「b」のスコープもローカルです-関数「main」に対してローカルです。

これらのローカルスコープ変数は自動変数とも呼ばれることに注意してください。

現在、ローカルスコープを持つ変数は、それらが宣言されているブロックに制限されていますが、スコープがグローバルである別のタイプの変数があります。名前が示すように、グローバルスコープ変数は関数間で使用できます。たとえば、変数「var」はグローバル整数変数であり、「main」関数と「swap」関数の両方で使用できます。

#include <stdio.h>

int var;

void swap (int val1, int val2)
{
int temp = 0;

temp = val1;
val1 = val2;
val2 = temp;

printf("\nSwapped values are: %d and %d", val1,val2);

}

int main()
{
int a=0, b=0;

printf("Enter two integer values\n");

scanf("%d %d",&a,&b);

printf("Entered values are: %d and %d", a,b);

swap(a,b);

return 0;
}
>

デフォルトでは、値「0」がグローバル変数に割り当てられます。ただし、ローカル変数の場合はそうではありません。ローカル変数を定義するときに値を割り当てる必要があります。そうしないと、ガベージ値が保持されます。たとえば、次のプログラムでは:

#include <stdio.h>

int var;

int main()
{
int a;

printf("Local variable 'a' currently holds: %d", a);

printf("\n Global variable var currently holds: %d", var);


return 0;
}

'a'の値がゼロ以外になる可能性が高くなります。一方、「var」は最初は常にゼロになります。

次に、同じ名前のグローバル変数とローカル変数がありますか?ええと、答えはイエスです。では、次のコードが出力で何を生成するのでしょうか。

#include <stdio.h>

int var = 5;

int main()
{
int var = 10;

printf("Local variable 'a' currently holds: %d", var);

printf("\n Global variable var currently holds: %d", var);


return 0;
}

どちらの場合も、出力は「10」になります。理由は、ローカル変数「var」がグローバル変数「var」をオーバーライドするためです。では、次の論理的な質問は、この場合、「main」内のグローバルな「var」にアクセスする方法です。悲しいことに、答えはノーです。実際、C言語を使用する場合は、このような状況に陥らないようにする必要があります。

次は、「外部」変数の概念です。素人の用語では、任意の変数宣言でキーワード'extern'を使用することにより、この変数がすでに別の場所で宣言/定義されていることをコンパイラーに伝え、ここで使用しているだけです。たとえば、次のコードでは、コンパイラは、main関数内でprintfステートメントをコンパイルしようとしたときに、「var」が存在することを認識していません。

#include <stdio.h>

int main()
{

printf("\n Global variable var currently holds: %d", var);


return 0;
}

int var = 5;

そのため、コンパイル中に次のようなエラーが発生します。

main.c: In function ‘main’:
main.c:14:58: error: ‘var’ undeclared (first use in this function)
printf("\n Global variable var currently holds: %d", var);
^
main.c:14:58: note: each undeclared identifier is reported only once for each function it appears in

ただし、ここで「var」をexternとして宣言すると、すべてが正常に機能することがわかります。これは、コンパイラが最終的に元の「var」宣言に到達するためです。

#include <stdio.h>

int main()
{
extern int var;

printf("\n Global variable var currently holds: %d", var);


return 0;
}

int var = 5;

そして、正しい出力が得られます:

Global variable var currently holds: 5

これがexternの仕組みです。外部変数は、プログラム/プロジェクトが複数のソースコードファイルに分割されていて、たとえば「file1」で使用したい場合によく使用されます。これは「file2」で定義された変数です。

そして最後に、変数スコープについて説明しているので、ここでも「静的」変数について説明するとよいでしょう。静的変数は、スコープ外になった後も値を保持するという意味で特別です。これは、それらが一度だけ初期化されることを意味します。これは初めてです。

static int counter 

以下は、静的変数を使用して関数が呼び出された回数をカウントするコードです。

#include <stdio.h>

int swap (int val1, int val2)
{
static int counter = 1;
int temp = 0;

temp = val1;
val1 = val2;
val2 = temp;

printf("\n Function called %d times\n", counter);
counter++;
}

int main()
{
int a=9, b=4;

swap(a,b);
swap(a,b);
swap(a,b);

return 0;
}

出力は次のとおりです:

 Function called 1 times 

Function called 2 times

Function called 3 times

ご覧のとおり、変数'counter'は、スコープ外になった後もその値を保持していました。グローバル変数と同様に、静的変数にもデフォルト値「0」があります。

このチュートリアルでは、Cプログラミング言語の変数のスコープに関連するいくつかの重要な概念について説明しました。 extern変数、static変数、global変数、およびlocal変数の違いをよりよく理解するために、独自のプログラムを作成することを忘れないでください。そしていつものように、疑問や質問がある場合は、下のコメントにドロップしてください。


Linux
  1. Cプログラミングチュートリアルパート3-変数の基本

  2. Cプログラミングチュートリアルパート5-文字変数

  3. Linux Cプログラミングチュートリアルパート9:文字列

  1. LinuxCプログラミングチュートリアルパート8-値による呼び出しとポインタ/アドレスによる呼び出し

  2. LinuxCプログラミングチュートリアルパート8-値による呼び出しとポインタ/アドレスによる呼び出し

  3. LinuxCプログラミングチュートリアルパート8-値による呼び出しとポインタ/アドレスによる呼び出し

  1. Kali LinuxBurpSuiteチュートリアル

  2. Cプログラミングチュートリアル4-変数とメモリ

  3. LinuxCプログラミングチュートリアルパート14-ビット演算子の実際の例