c++におけるsizeof()の使い方の紹介

11952 ワード

1.定義
sizeofはオペレータです.
オブジェクトまたはタイプが占めるメモリバイト数を返す役割を果たします.
 
2.文法
sizeofには3つの文法形式があります.
1)  sizeof (object);//sizeof(オブジェクト)
2)  sizeof object;//sizeofオブジェクト
3)  sizeof (type_name);//sizeof(タイプ)
オブジェクトは、様々なタイプの変数であり、式(一般的にsizeofは式を計算しません).
sizeofはオブジェクトに対してメモリサイズを求め,最終的にはオブジェクトのデータ型に変換して評価する.
sizeof(式);//値は式の最終結果のデータ型のサイズです.
 
例:
int i;  
sizeof(int); //  4  
sizeof(i); //  4,   sizeof(int)  
sizeof i; //  4  
sizeof(2); //  4,   sizeof(int),  2    int  
sizeof(2 + 3.14); //  8,   sizeof(double),             double  

char ary[sizeof(int) * 10]; //OK,    

 
 
1.基本データ型のsizeof
ここでの基本データ型とは、short、int、long、float、doubleのような単純な組み込みデータ型を指す.
メモリサイズはシステムに関連付けられているため、システムによって値が異なる場合があります.
 
2.構造体のsizeof
構造体のsizeofはバイト位置合わせの問題に関連する.
なぜバイト整列が必要なのですか?コンピュータの構成原理は、コンピュータの取数速度を速めるのに役立つことを教えてくれます.そうしないと、命令周期がかかります.そのため、コンパイラはデフォルトで構造体を処理し(実際には他の場所のデータ変数も同様)、幅2の基本データ型(shortなど)を2で割り切れるアドレスに配置し、幅4の基本データ型を(intなど)はいずれも4で割り切れるアドレスにあり,順次類推される.これにより,2つの数の間にパディングバイトを加える必要がある可能性があり,構造体全体のsizeof値が増加する.
バイト整列の詳細は、コンパイラの実装に関連していますが、一般的には、3つのガイドラインを満たしています.
1)構造体変数のヘッダアドレスは、その最も広いベースタイプのメンバのサイズによって割り切れることができる.
2)構造体の各メンバーの構造体ヘッダアドレスに対するオフセット量(offset)は、メンバーサイズの整数倍であり、必要に応じてコンパイラはメンバー間にパディングバイト(internal adding)を加算する.
3)構造体の合計サイズは、構造体の最も広い基本タイプのメンバーサイズの整数倍であり、必要に応じて、コンパイラは最後のメンバーにパディングバイトを加算します.
 
注意:空の構造体(データメンバーを含まない)のsizeof値は1です.「空間を占有しない」変数がどのようにアドレスを取られ、2つの異なる「空の構造体」変数がどのように区別されるかを考えてみましょう.そこで、「空の構造体」変数も格納され、コンパイラは1バイトの空間を占有に割り当てるしかありません.
 
例:
struct S1  
{  
    char a;  
    int b;  
};  
sizeof(S1); //  8,    , char     3   。  
  
struct S2  
{  
    int b;  
    char a;  
};  
sizeof(S2); //  8,    , char     3   。  
  
struct S3  
{  
};  
sizeof(S3); //  1,        


3.連合体のsizeof
構造体はメモリ組織に上場する順序式で、連合体は重畳式で、各メンバーはメモリを共有している.したがって、連合体全体のsizeofは、各メンバーのsizeofの最大値である.
 
例:
union u  
{  
    int a;  
    float b;  
    double c;  
    char d;  
};  
  
sizeof(u); //  8  

 
4.配列のsizeof
配列のsizeof値は、配列に使用されるメモリバイト数に等しい.
注意:1)文字配列が文字列を表す場合、sizeof値は'/0'を計算します.
2)配列がパラメータである場合、そのsizeof値はポインタのsizeof値に相当する. 
例1:
char a[10];  
char n[] = "abc";   
  
cout<<"char a[10]                 "<<sizeof(a)<//  ,  10  
  
cout<<"char n[] = /"abc/"           "<<sizeof(n)<//     , '/0'    ,  4


例2:
void func(char a[3])  
{  
    int c = sizeof(a); //c = 4,    a       ,    ,   char *a。  
}  
  
void funcN(char b[])  
{  
    int cN = sizeof(b); //cN = 4,    。  
} 


5.ポインタのsizeof
ポインタは別のオブジェクトを記録するためのアドレスであるため、ポインタのメモリサイズは当然、コンピュータ内部のアドレスバスの幅に等しい.
32ビットコンピュータでは、ポインタ変数の戻り値は必ず4である.
ポインタ変数のsizeof値は、ポインタが指すオブジェクトとは何の関係もありません.
例:
char *b = "helloworld";  
char *c[10];  
double *d;  
int **e;  
void (*pf)();    
  
cout<<"char *b = /"helloworld/"     "<<sizeof(b)<//       ,  4  
cout<<"char *b                    "<<sizeof(*b)<//      ,  1  
cout<<"double *d                  "<<sizeof(d)<//  ,  4  
cout<<"double *d                  "<<sizeof(*d)<//       ,  8  
cout<<"int **e                  "<<sizeof(e)<//      ,  4  
cout<<"char *c[10]                "<<sizeof(c)<//    ,  40  
cout<<"void (*pf)();              "<<sizeof(pf)<//    ,  4  

 
6.関数のsizeof
sizeofは、1つの関数に対して評価を呼び出すこともでき、その結果、関数は値タイプのサイズを返し、関数は呼び出されません.
関数の評価形式:sizeof(関数名(実パラメータテーブル))
注:1)戻り値タイプが空の関数は評価できません. 
2)関数名は評価できません.
3)パラメータのある関数に対してsizeofを用いる場合は,実パラメータ表を書く.
例:
#include   
using namespace std;  
  
float FuncP(int a, float b)  
{  
    return a + b;  
}  
  
int FuncNP()  
{  
    return 3;  
}  
  
void Func()  
{  
}  
  
int main()  
{  
cout<<sizeof(FuncP(3, 0.4))<//OK,  4,sizeof(FuncP(3,0.4))   sizeof(float)  
cout<<sizeof(FuncNP())<//OK,  4,sizeof(FuncNP())   sizeof(int)  
/*cout<*/  
/*cout<*/  
return 0;  
}