printf("%ld %ld\n",sizeof(me),sizeof(*me));//output is 8 80 how??
実際には次のようになります。
printf("%zu %zu\n",sizeof(me),sizeof(*me));//output is 8 80 how??
"%zu"
size_t
から取得した値など、値の正しいフォーマット文字列ですsizeof
。"%ld"
一部のシステムではたまたま動作する可能性がありますが (あなたのシステムでも動作するようです)、それを当てにするべきではありません。
コンパイラが をサポートしていない場合は、(引数を期待する) を"%zu"
使用して、引数を明示的に変換できます。"%lu"
unsigned long
printf("%lu %lu\n", (unsigned long)sizeof(me), (unsigned long)sizeof(*me));
これは、使用しているコンパイラのポインターのサイズ(8 バイト、64 ビット) である8
ためです。プログラムを別のシステムでコンパイルして実行すると、多くのシステムが 32 ビット ポインターを持っているため、. (これは 1 バイトが 8 ビットであることを前提としています。これはほとんどのシステムに当てはまりますが、言語によって保証されていません。)sizeof(me)
4
ほとんどのコンパイラはすべてのポインタを同じサイズにしますが、それは言語でも保証されていません。たとえば、ワードアドレスのマシンでは、int*
ポインターは単なるマシンレベルのアドレスである可能性がありますが、char*
ポインターは、それが指すワード内のどのバイトを指定するために追加情報を必要とする場合があります。ポインターのサイズが異なるシステムに遭遇する可能性はほとんどありませんが、すべてのポインターが同じサイズであると想定しても意味がありません。
構造体のサイズに関しては、コンパイラーによっても異なります。これがあなたの構造です:
struct krishna {
int i,j,k,l,m;
char c;
double d;
char g[48];
};
char
は常に正確に 1 バイトであり、char[48]
常に正確に 48 バイトです。
のバイト数は、int
システムによって異なります。最近では 4 バイトが最も一般的です。
a のサイズdouble
は通常 8 バイトですが、これもさまざまです (8 バイトでないシステムを見たことがないと思いますがsizeof (double)
)。
i
構造体のメンバーは、宣言された順序で配置されるため、構造体の最初にあなたの意志があり、その後にj
、k
などが続きます。
最後に、コンパイラは多くの場合、各メンバーが適切に位置合わせされるように、メンバー間または最後のメンバーの後にパディング バイトを挿入します。たとえば、多くのシステムでは、4 バイトを 4 バイトの倍数のオフセットに揃える必要があります。位置がずれていると、アクセスが遅くなったり、非常に困難になったりする可能性があります。int
システムsizeof (struct krishna)
上でたまたま 80 バイトであるという事実は、それほど重要ではありません。(a) コンパイラーが構造のレイアウト方法を決定するために使用する一般的な規則、および (b) これらの規則がシステムごとに異なるレイアウトになる可能性があるという事実を理解することがより重要です。
struct krishna
言語定義とコンパイラは、 type のオブジェクトを持つことができること、およびそれらのオブジェクトとそのメンバーにアクセスして、格納した値を取得できることを保証します。a の大きさを知る必要がある場合struct krishna
、答えは単純にsizeof (struct krishna)
です。何らかの理由で、それよりも詳細を知る必要がある場合 (たとえば、外部から課されたレイアウトを一致させる必要がある場合)、いくつかの実験を行ったり、コンパイラのドキュメントを参照したりできますが、詳細が適用されることに注意してください。使用しているシステムで使用しているコンパイラにのみ。(多くの場合、システムのABIによってコンパイラの選択が制限されます。)
sizeof
また、 and offsetof
(検索) を使用して、各メンバーが割り当てられている場所を確認することもできます。