C特別キーワードstatic、extern、const等

7338 ワード

========================const========================
------------------------------------------------------------
定数:(構造型定数を定義できない)定数には、字面定数、シンボル定数、列挙定数のいくつかのタイプが含まれます.
--字面定数:整形定数、文字型定数、文字列定数.注意:配列定数、構造体定数などの構造型の字面定数は存在しません.しかし、構造型のシンボル定数が存在する. 
--符号定数:(構造型定数を定義可能)#defineとconstで定義した定数! 
--------------------------------------------------------------------------
--constはC言語のキーワードで、変数が変更されないことを制限します.
--機能:
1.const定数を定義でき、不変性があります.例:const int Max=100;Max++でエラーが発生します. 
2.タイプチェックを容易にし、コンパイラが処理内容をよりよく理解し、いくつかの危険性を解消します.例えば、void f(const int i){......}コンパイラはiが定数であることを知っていて、修正は許されません. 
3.意味が曖昧な数字の出現を避けることができ、同様にパラメータの調整と修正を容易に行うことができる.マクロの定義と同じように、変わらないことができるのはすでに、変わるとすべて変わります!(1)のように、Maxの内容を修正するには、const int Max=you want;だけでよい!4.修飾されたものを保護し、予期せぬ修正を防止し、プログラムの頑丈性を高めることができる.やはり上記の例では、関数内でiを修正するとコンパイラがエラーを報告する;例えば、void f(const int i){i=10;//error!}5.不要なメモリ割り当てを回避するために、スペースを節約できます.例:
 #define PI 3.14159 //    
  const double Pi=3.14159; //     Pi  RAM  ...... 
  double i=Pi; //   Pi    ,      ! 
  double I=PI; //         ,     
  double j=Pi; //       
  double J=PI; //      ,       ! 
const定義定数はアセンブリの観点から、#defineのように与えられるのではなく、対応するメモリアドレスを与えるだけである.
即時数ですので、constで定義された定数はプログラムの実行中にコピーが1つしかありませんが、#defineで定義された定数はメモリにいくつかのコピーがあります.
6.
能率が上がる.コンパイラは通常、通常のconst定数にストレージスペースを割り当てるのではなく、シンボルテーブルに保存します.これにより、コンパイル中の定数となり、ストレージとリードメモリの操作がなくなり、効率が向上します.
------------------------------------------------------------
--const変数&定数
const int n = 5;
int a[n];
ANSI Cが配列定義を規定する場合、長さは「定数」でなければなりません.「読取り専用変数」もできません.「定数」は「可変変数」に等しくありません.
--const&ポインタ
const int nValue; int const nValue; //nValue const
const char *pContent;  char const * pContent;//*pContent const, pContent  
char* const pContent; //pContent const,*pContent  
const char* const pContent;  char const* const pContent; //pContent *pContent  const
constはその後の変数のみを修飾し、
constはタイプの前に置くかタイプの後に置くかは区別されない(例ではintとcharと位置を入れ替える)が、ポインタ記号(*)の異なる位置では異なるタイプ(ポインタまたは変数)を表す
メモ:constが*の左側にある場合、ポインタが指す変数の値はポインタで直接変更できません.*の右側では、ポインタの向きは可変ではありません.例:
//            ,    
int x = 1; int y = 2;
const int* px = &x; //            int const* px = &x; 
px = &y; //  ,      
*px = 3; //  ,              
//             ,     
int x = 1;int y = 2;
int* const px = &x;
px = &y; //  ,         
*px = 3; //  ,             

--constはどのように内容を限定しますか
typedef char * pStr;             // 1
const char *p1 =" string"; //1 
const pStr p2 =" string"; //2 
p1++;//   
p2++;//  
-------------------------------// 2
int const * p1,p2;  //p2 const;(*p1)    ,  (*p1) const, p1    
int * const p1,p2;  //p1 const,(* const p1)   ,  const   p2。
const type m;限定mは可変ではない.例1は比較的特殊であり,typeは2式中のpStrと見なすことができ,置換後はconst pStr mとなり,前述の「左定値,右配向」と少し矛盾している.
--------------------------------------------------------------------------
--constとdefineマクロ定義:
1.コンパイラの処理方式が異なる:defineマクロは前処理段階で展開される;const定数はコンパイル実行フェーズで使用されます.2.タイプとセキュリティチェックの違い:defineマクロにはタイプがなく、タイプチェックを行わず、展開するだけです.const定数には具体的なタイプがあり、コンパイル段階でタイプチェックが実行されます.3.記憶方式が違う:defineマクロは展開するだけでメモリが割り当てられない;const定数はメモリに割り当てられます.(一般的には)4.constは、不要なメモリ割り当てを回避するためにスペースを節約できます.たとえば、次のようにします.
#define PI 3.14159 //    
const doulbe Pi=3.14159; //     Pi  ROM  ...... 
double i=Pi; //   Pi    ,      ! 
double I=PI; //         ,     
double j=Pi; //       
double J=PI; //      ,       !
const定義定数はアセンブリの観点から対応するメモリアドレスが与えられるだけで、
#defineのように即時数を与えるのではなく、constで定義された定数はプログラムの実行中にコピーが1部しかありません(グローバルな読み取り専用変数であり、静的領域があるため)、#defineで定義された定数はメモリにいくつかのコピーがあります.
5.マクロ置換は置換のみ、計算は行わず、式の解は行わない.
備考:#defineで定義された定数は、文字列の字面定数を除いてメモリを占有しないため、定数のアドレスを取ることができず、マクロ置換にすぎない.eg:#define NAME「pang dong」は本質的に文字列の字面定数であり、「静的記憶領域」を占有する.字面定数は、静的ストレージ領域/即時数と同じです.
========================static========================
-------------------------C中-------------------------
1.static修飾関数の変数(スタック変数):変数の生存期間を変更しても、役割ドメインはそのままの関数になります.一度だけ初期化されます.2.static修飾グローバル変数:制限グローバル変数はモジュール内でのみアクセスでき、他のモジュールではexternで呼び出しを宣言できません.3.static修飾関数:作用は修飾グローバル変数と類似しており、この関数がモジュール内でのみアクセスできることを制限し、できません他のモジュールではexternで呼び出しを宣言します.
//  a.c
static int i; //  a    
int j;          //     
static void init()         //  a    
{  }
void callme()          //     
{
    static int sum;
}
//  b.c
extern int j;                    //  a    
extern void callme();   //  a    
int main()
{  ...}
------------------------
C++中-------------------------
1.static静的データメンバーはクラス全体の所有に属し、クラスのすべてのオブジェクトは共同で維持されます.
2.static静的関数メンバーもクラス全体に属し、一般的に静的データメンバーを呼び出すために使用され、非staticメンバーに直接アクセスすることはできません(クラスを指定する必要があります).
class Point
{
public:
  ....
  static void show()
  { cout << count <<endl;}
private:
  ...
  static int count;    //     ,      ,     。           
}
int Point::count = 0; //          

int main()
{
   Point a(4,5);
   Point::show();  //   a.show();
}
備考:グローバル変数とグローバル静的変数の違い:グローバル変数のデフォルトは動的であり、役割ドメインはプロジェクト全体であり、1つのファイル内で定義されたグローバル変数であり、別のファイルではexternグローバル変数名の宣言によってグローバル変数を使用することができる.グローバル静的変数役割ドメインは、この変数が存在することを宣言するファイルであり、他のファイルはextern宣言を使用しても使用できません.
========================extern========================
externは、変数または関数の前に配置して、変数または関数の定義が別のファイル(宣言)にあることを示し、コンパイラにこの変数と関数に遭遇したときに他のモジュールで定義を探すように促すことができます.また、externはリンク指定にも使用できます.
-------------------------extern変数------------------
extern int a;//        a
int a; //        a
extern int a =0 ;//        a     。      ,     ,          。
int a =0;//        a,    ,
コメント:
1.宣言後、この変数を直接使用することはできません.定義してから使用する必要があります.2.4番目は3番目に等しく、外部で使用できるグローバル変数を定義し、初期値を与えます.3.定義は1つの場所にのみ表示されます.すなわちint aにかかわらず;それともint a=0ですか.一度しか現れませんが、そのextern int aは何度も現れます.4.グローバル変数を参照する場合は、extern int aを宣言します.このときexternは省略できませんが、省略したのでint aになります.これは定義であり、宣言ではありません.
関数の宣言にキーワードexternが含まれている場合は、この関数が他のソースファイルで定義される可能性があることを示すだけで、他の役割はありません.すなわち、extern int f();およびint f();関数の定義と宣言時にexternがあってもなくてもよい.
-------------------------------------------------------------------
1.宣言と定義の違い:
--関数はよく区別されています.
--変数:変数に記憶領域を割り当てるために定義され、変数に初期値を指定することもできます.プログラムでは、変数は1つの定義しかありません.宣言:変数のタイプと名前をプログラムに表示します.2つの関係に注意してください.宣言だけでなく、定義だけでなく、宣言もあります(前述のextern変数の例を参照できます).
2.グローバル変数について:
//A.cpp
int  i;
int main()
{ …… }
//B.cpp
int i;
A.cppではグローバル変数iを定義し、Bではグローバル変数iも定義した.私たちはAとBをそれぞれコンパイルして、正常にコンパイルすることができますが、リンクを行うとき、エラーが発生しました.つまりコンパイル段階では
各ファイルで定義されているグローバル変数は互いに不透明であり,AをコンパイルするときにBに気づかないことにもiが定義されており,同様にBをコンパイルするときにAに気づかないことにもiが定義されている.ただし、リンクフェーズでは、各ファイルの内容を「統合」するため、一部のファイルで定義されているグローバル変数名が同じであれば、この時点でエラー、すなわち、上記の繰り返し定義のエラーが発生します.したがって、
ファイル内に定義されたグローバル変数は、リンクが完了すると、プログラム全体に表示範囲が拡大されます.
3.externとヘッダファイルについて:元のソースファイルで別のソースファイルの変数/関数を使用するには、使用前にexternで変数/関数を宣言する必要があります.宣言の方法は、mファイルで、使用前にexternで変数/関数を宣言することができます.ヘッダファイルにexternで変数/関数を宣言するか、includeの別のソースファイルヘッダファイル(ヘッダファイルには変数/関数の宣言が含まれている必要があります.特に変数の宣言が定義と混同されないように注意してください).
4.プログラミングスタイル:
--変数定義を入れないでください.hファイルです.これにより、繰り返し定義エラーが発生しやすくなります.--変数がグローバルに設計されない限り、staticキーワードを使用して変数定義をソースファイルの役割ドメインに制限します.
--ヘッダファイルに変数を宣言し、使用するときにこのヘッダファイルを含めてこの変数を宣言できます.