C ++学習レコード-外部変数、静的変数、宣言と定義、グローバル変数とローカル変数

  • ローカル変数とグローバル変数の違い
  1. ローカル変数は関数内で定義されており、関数外からはアクセスできません。({}によって制限された領域で定義されます)
  2. グローバル変数はすべての関数の外部で定義され、スコープ内のすべての関数にアクセスできます。以下に詳しく説明します。
  3. ローカル変数の有効期間は、それが定義されている{}にあります。グローバル変数は、すべての関数(メイン関数を含む)を除いて、プログラムで定義されている任意の変数です。
  4. グローバル変数のスコープは、変数の定義からプログラム全体の終わりまでのプログラムの一部です。これは、グローバル変数の後に定義されたすべての関数からグローバル変数にアクセスできることを意味します。
#include<iostream>
using namespace std;
void California (); // Function prototype

int BIRDS = 500; // Global constant
int main()
{
    
    
    cout <<  "In main there are " << BIRDS << " birds.\n";
    California();
    cout <<  "In main there are " << BIRDS << " birds.\n";
    return 0;
}

void California()
{
    
    
    const int BIRDS = 10000;
    cout << "In California there are " << BIRDS << " birds.\n";
}

输出:
In main there are 500 birds.
In California there are 10000 birds.
In main there are 500 birds.

以上のことから、一時的にローカル変数とグローバル変数を理解しましょう。

  • C ++での宣言と定義の違い

「C ++ Primer」第4版セクション2.3.5は次のように述べています。

  1. 変数の定義:変数にストレージスペースを割り当てるために使用され、変数の初期値を指定することもできます。プログラムでは、変数には1つだけの定義があります。しかし、複数の宣言が存在する可能性があります
  2. 変数宣言:変数のタイプと名前をプログラムに示すために使用されます。
  3. 定義は宣言でもあります。変数を定義するときは、その型と名前を宣言します。
  4. externキーワード:extern変数名を定義せずにキーワードを使用して宣言します。
extern int i;// 是声明,不是定义,也即不分配空间。
int i;// 是声明,同时也定义,为其分配了空间。
任何包含了显式初始化的声明即成为定义。
我们能给由extern关键字标记的变量赋一个初始值,但是这么做也就抵消了extern的作用。extern语句如果包含初始值就不再是声明,而变成定义了:
extern int i = 10;//定义,extern作用被抵消

函数的声明和定义区分比较简单,带有{
    
    }的即为定义,没带{
    
    }即为声明。
int max(int a, int b); //函数的声明

定義は1つだけですが、複数の宣言が存在する可能性があることを示す例を挙げてください

#include<iostream>
using namespace std;
extern int a;//声明
int main(){
    
    
	int a = 10;//定义
	int a = 11;//此时,编译器会报错。
	a = 11;//此时,并不会报错,这不在是定义了,而是赋值。
	cout << a << endl;
	return 0;
}
  • 静的キーロールの概要 参照
  1. 隠す。(静的関数と静的変数は両方とも)
    複数のファイルを同時にコンパイルする場合、静的で接頭辞が付けられていないすべてのグローバル変数と関数はグローバルな可視性を持ちます。
    説明する例を挙げてください。2つのソースファイルを同時にコンパイルします。1つはacで、もう1つはmain.cです。
//a.c
char a = 'A'; // global variable
void msg()
{
    
    
     printf("Hello\n");
}
 
//main.c
 
int main()
{
    
    
     extern char a; // extern variable must be declared before use
     printf("%c ", a);
     (void)msg();
     return 0;
}
输出:
Hello

acで定義されたグローバル変数aと関数をacで使用msgできるのはなぜmain.cですか?接頭辞のない
すべてのstaticグローバル変数と関数にはグローバルな可視性があり、他のソースファイルにもアクセスできます。この例でa、これはグローバル変数でありmsg、関数であり、staticプレフィックスがないため、他のソースファイルmain.cに表示されます。
追加staticすると、他のソースファイルからは非表示になります。たとえばamsgの定義の前に追加staticすると、main.cに表示されません。この機能を使用すると、名前の競合を気にせずに、異なるファイルに同じ名前の関数と変数を定義できます。static関数や変数の接頭辞として使用できます。関数の場合static、関数は非表示に限定されます。

  1. static2番目の役割は、可変コンテンツを永続的に保つことです。static変数のメモリ関数とグローバルライフタイム)

静的データ領域に格納されている変数は、プログラムの開始時に初期化されます。これが唯一の初期化です。静的ストレージ領域に格納される変数には、グローバル変数と静的変数の2種類がありますが、グローバル変数と比較すると、変数staticの表示範囲を制御できます。結局、静的は非表示に使用されます。この使用法は一般的ではありませんが、
PS:static関数でローカル変数として定義されている場合、その存続期間はソースプログラム全体ですが、スコープは自動変数と同じであり、変数は関数でのみ使用できます。変数を定義します。関数を終了した後、変数はまだ存在しますが、使用できません。

#include <stdio.h>
 
int fun(){
    
    
    static int count = 10; //在第一次进入这个函数的时候,变量a被初始化为10!并接着自减1,以后每次进入该函数,a
    return count--; //就不会被再次初始化了,仅进行自减1的操作;在static发明前,要达到同样的功能,则只能使用全局变量:    
 
}
 
int count = 1;
 
int main(void)
{
    
    
     printf("global\t\tlocal static\n");
     for(; count <= 10; ++count)
               printf("%d\t\t%d\n", count, fun());
     return 0;
}
输出:
global  local static
1 10
2 9
3 8
4 7
5 6
6 5
7 4
8 3
9 2
10 1

-上記の2つのポイントに基づいて、結論を導き出すことができます。ローカル変数を静的変数に変更すると、ストレージモードが変更されます。つまり、有効期間が変更されます。グローバル変数を静的変数に変更すると、そのスコープが変更され、使用範囲が制限されます。したがってstatic、場所によってこの指定子の役割は異なります。

  1. static3番目の役割は、デフォルトで0に初期化することです(static変数)

実際、グローバル変数も静的データ領域に格納されるため、グローバル変数にもこの属性があります。静的データ領域では、メモリ内のすべてのバイトのデフォルト値は・です0x00。この機能により、場合によってはプログラマの作業負荷を軽減できます。たとえば、スパース行列を初期化するには、すべての要素を1つずつ配置してから、0そうでない0いくつかの要素に値を割り当てることができます。静的と定義されている場合、初期設定0操作は省略されます。もう1つの例は、文字配列を文字列として使用することですが、毎回文字配列の最後‘\0’追加するのは面倒すぎると思います文字列が静的として定義されている場合、この問題は元々存在しているため保存されます‘\0’。少し実験して確認することをお勧めします。

#include <stdio.h>
 
int a;
 
int main()
{
    
    
     int i;
     static char str[10];
     printf("integer: %d; string: (begin)%s(end)", a, str);
     return 0;
}
输出:
integer: 0; string: (begin) (end) 

最後にstatic、3つの関数の1文の要約を作成します。まず、staticの主な機能は非表示にすることです。次に、static変数は静的ストレージ領域に格納されるため、永続性とデフォルト値があります0

  1. static クラスでの役割

続く-
参照用、まだ見られない-参照用のクラスでの静的の役割、
まだ見られない-staticとconstの違い

  • extern 機能概要

C言語でexternは、変数または関数の宣言の前に修飾子を使用して、「この変数/関数は他の場所で定義されているため、ここで引用する必要がある」ことを示します。externグローバル変数を宣言するときは、最初に明確にする必要がありますextern。スコープはプロジェクト全体ですextern int aつまり、.hファイルに書き込むときです。リンクするとき、リンカーは他の.cppファイルに移動してそこにあるかどうかを確認します。いずれかがあるint aない場合は、リンクがエラーを報告します。

  1. extern変更された変数宣言

ファイルacがbcの変数を参照する必要int vがある場合は、acextern int v宣言してから、変数を参照できますv
ここvで、参照される変数のリンク属性は外部である必要があることに注意してください。つまり、acを参照する必要があります。これは、acvの宣言に依存するだけでなくextern int vv参照できる変数自体にも依存します。
これには、C言語の別のトピックである変数のスコープが含まれます。extern修飾子を使用して他のモジュールから参照できる変数は、通常、グローバル変数です。
もう1つの非常に重要な点はextern int v、acのどこにでも配置できることです。たとえば、fun定義の宣言先頭でac関数をextern int v実行でき、次に変数を参照できますv。この方法でのみ、fun参照スコープを関数化できます。v忘れてください、これはまだ可変スコープの問題です。このため、多くの人がそれを使用するときに懸念を抱いています。extern宣言はファイルスコープでのみ使用できるようです。

shengming.h

extern int a;
extern int b;

shengming.cpp //此处并不需要加 #include ”shengming.h"

int a = 10;
int b = 20;

main.cpp

#include <iostream>
#include "shengming.h"
using namespace std;
int main()
{
    
    
    cout << a << " " << b << endl;
    return 0;
}
输出: 10 20
  1. extern変更された関数宣言

本質的に、変数と関数の間に違いはありません。関数名は、関数のバイナリブロックの先頭へのポインタです。
プロトタイプbcのように、関数内でファイルac bcを参照する必要int fun(int mu)がある場合は、acextern int fun(int mu)宣言でき、それを使用funして何でもできます
変数の宣言と同様に、extern int fun(int mu)acのどこにでも配置できますが、必ずしもacのファイルスコープのスコープ内に配置する必要はありません。
他のモジュールの関数を参照する場合、最も一般的な方法は、これらの関数宣言のヘッダーファイルをインクルードすることです。externヘッダーファイルを使用してインクルードし、どのような違いが機能するかを参照しますか?
extern引用の方法は、ヘッダーファイルを含めるよりもはるかに簡潔です。extern使い方は簡単で、参照したいextern関数宣言できます
これの明らかな利点の1つは、プログラムのコンパイルプロセス(正確には前処理)を高速化し、時間を節約できることです。大規模なCプログラムをコンパイルする過程で、この違いは非常に明白です。

  1. extern修飾子は、CまたはC ++関数の呼び出し仕様を示すために使用できます。

たとえば、C ++でCライブラリ関数を呼び出す場合extern “C”、関数を参照するステートメントを使用してC ++でプログラミングする必要があります。

これはリンカ用であり、リンク時にC関数仕様を使用してリンクするようにリンカに指示します。主な理由は、C ++プログラムとCプログラムは、コンパイル後にターゲットコードで異なる命名規則を使用するためです。
参考資料-externを使用してCとC ++を混合してコンパイルする

  • externと静的に変更されたグローバル変数の違い

staticキーワードには、静的グローバル変数、静的ローカル変数、クラスの静的メンバーの宣言など、多くの機能があります。ここでの主な議論は、グローバル変数を変更するときの彼とexternの違いです。注意すべき点が2つあり
ます。1。staticがグローバル変数を変更する場合、宣言と定義が同時に与えられます
。2。staticのグローバルスコープは、それ自体のコンパイル単位にすぎません。externはプロジェクト全体を指し、コンパイル単位は.cppファイルとそれに含まれるヘッダーファイルを指します。つまり、staticがグローバル変数を変更する場合、「global」のスコープはexternよりも小さくなります。したがって、静的を使用してヘッダーファイルでグローバル変数を宣言(および定義)しても、上記で説明した定義が繰り返されるという問題は発生しません。
グローバル変数を変更するには、externとstaticの違いを参照してください

externが静的変数として変更された他のファイルにアクセスしたい場合、それは許可されていません。externは定義ではありませんが、他のソースファイルで定義されている非静的グローバル変数の導入(宣言)です。

未読の参照

おすすめ

転載: blog.csdn.net/JACKSONMHLK/article/details/114236757