sizeofに関する問題

3329 ワード

1.sizeofの概念:
sizeofはCの単一演算子であり、そのオペランドの記憶サイズをバイト形式で与える.オペランドは、式または囲まれたデータ型であってもよい.オペランドの格納サイズはオペランドの種類によって決まります.
2.sizeofの使い方:
sizeofは変数にカッコを付けなくてもいいし、カッコを付けてもいいですが、タイプにはカッコを付けなければなりません.sizeofは、関数タイプ、不完全タイプ、ビットフィールドには使用できません.不完全タイプとは、未知サイズの配列タイプ、未知コンテンツの構造または結合、voidタイプなど、位置格納サイズを持つタイプを指します.
3.sizeofとstrlenの比較:
1)sizeofは演算子、strlenは関数
2)sizeofオペレータの結果タイプはsize_t
3)sizeofはタイプでパラメータを作成できますが、strlenはchar*でのみパラメータを作成でき、'0'で終わる必要があります.
4)配列はsizeofのパラメータとして劣化せず,strlenのパラメータとしてポインタに劣化する.(Cの1つの特性:配列をパラメータとして関数に渡す場合、配列はその配列を指すポインタに自動的に劣化します.sizeofは関数ではなく演算子であることに注意してください)
5)ほとんどのコンパイラはコンパイル時にsizeofを計算しているが,これもsizeof(x)を用いて配列サイズを定義できる理由である.
6)strlenの結果は実行時に計算されます.タイプがメモリに占めるサイズを計算するのではなく、文字列の長さを計算するために使用されます.
4.古典的な問題:
 
double *(*a)[3][6];
cout<<sizeof(a)<<endl; //4 a   
cout<<sizeof(*a)<<endl;//72 *a    3*6        
cout<<sizeof(**a)<<endl;//24  **a      6   
cout<<sizeof(***a)<<endl;//4  ***a         
cout<<sizeof(****a)<<endl;//8  ****a   double  

5.次のプログラム出力:
 
#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;

struct{
          short a1;
          short a2;
          short a3;
}A;
struct{
          long a1;
          short a2;
}B;

int main()
{
          char* ss1 = "0123456789";
          char   ss2[] = "0123456789";
          char   ss3[100] = "0123456789";
          int      ss4[100];
          char    q1[] = "abc";
          char    q2[] = "a
"; char* q3 = "a
"; char * str1 = (char*)malloc(100); void * str2 = (void*)malloc(100); cout<<sizeof(ss1)<<endl;//4 cout<<sizeof(ss2)<<endl;//11 10 '\0' cout<<sizeof(ss3)<<endl;//100 cout<<sizeof(ss4)<<endl;//400 , int 4 cout<<sizeof(q1)<<endl;//4 3+1('\0') cout<<sizeof(q2)<<endl;//3 2+1 cout<<sizeof(q3)<<endl;//4 cout<<sizeof(A)<<endl;//6 2*3 cout<<sizeof(B)<<endl;//8 4+2 8(32 long 4byte) cout<<sizeof(str1)<<endl;//4 cout<<sizeof(str2)<<endl;//4 。。。。。 return 0; }

構造体のサイズの問題(データの位置合わせ):
デフォルトでは、構造体内の要素のアクセスと管理を容易にするために、構造体内の要素の長さがプロセッサのビット数よりも小さい場合、構造体の中で最も長いデータ要素がその単位であるようにします.つまり、構造体の長さは最も長いデータ要素の整数倍に違いありません.構造内にプロセッサのビット数よりも長い要素がある場合は、プロセッサのビット数を単位とします.しかし、構造体内のタイプが同じ連続要素は、配列と同じ連続空間内にあります.
構造体のデフォルトのバイト位置合わせは、一般的に3つの原則を満たします.
1)構造体変数のヘッダアドレスは、その最も広い基本タイプのメンバー変数の大きさによって除去することができる.
2)構造体の各メンバーの構造体ヘッダアドレスに対するオフセット量は、メンバーサイズの整数倍であり、必要に応じてコンパイラがメンバー間にバイトを追加する.
3)構造体の合計サイズは、構造体の最も広い基本タイプのメンバーサイズの整数倍であり、必要に応じてコンパイラは、最後のメンバーの後にパディングバイトを加算します.