C言語におけるsizeof解析


1.定義:sizeofはC/C++のオペレータであり、オブジェクトまたはタイプが占めるメモリバイト数を返す役割を果たします.
値タイプsize_t,ヘッダファイルstddef.hで定義します.これはコンパイルシステムに依存する値であり、一般的にtypedef unsigned int size_と定義されている.t;コンパイラ林林総、しかし1つの規範としてchar、signedを保証します
charとunsigned charのsizeof値は1であり、結局charはプログラミングで使用できる最小データ型である.
MSDN上の解釈は、The sizeof keyword gives the amount of storage,in bytes,associated with avariable or a
type (including aggregate types). This keyword returns a value of type size_t.2. 構文:sizeofには3つの構文形式があります.1)sizeof(object)//sizeof(オブジェクト);2) sizeof( type_name );//sizeof(タイプ);3) sizeof object;//sizeofオブジェクト;
次の3つのsizeofの使用はすべて正しいです
#include <stdio.h>
main()
{
int b;
printf("%d
",sizeof b); printf("%d
",sizeof(b)); printf("%d
",sizeof(int)); }

4.基本データ型のsizeofここでの基本データ型とは、short、int、long、float、doubleのような単純な組み込みデータ型を指す.
関連しているので、システムによって値が異なる可能性があります.これは、できるだけ自分のプログラムの移植に迷惑をかけないように注意しなければなりません.一般に、32ビットコンパイル環境ではsizeof(int)の値は4である.
5.ポインタ変数のsizeofは、コンピュータ内部のアドレスバスの幅に等しい.したがって、32ビットコンピュータでは、ポインタ変数の戻り値は必ず4である(注意結果は
バイト単位)では,将来の64ビットシステムにおけるポインタ変数のsizeof結果は8と予想される.ポインタ変数のsizeof値は、ポインタが指すオブジェクトとは何の関係もありません.すべてのポインタ変数が占めるメモリサイズが等しいためです.
MFCメッセージ処理関数は、2つのパラメータWPARAM、LPARAMを使用して様々な複雑なメッセージ構造(構造体へのポインタを使用)を伝達することができる.6.配列のsizeof配列のsizeof値は、char a 1[]=「abc」;int a 2[3];sizeof(a 1);//結果は4で、文字の末尾にNULL終端sizeof(a 2)//が存在する.その結果,3*4=12(int依存)sizeofは配列要素を求める個数としては正しくなく,配列要素を求める個数にはint c 1=sizeof(a 1)の2つの書き方がある.
/sizeof( char );//全長/単一要素の長さint c 2=sizeof(a 1)/sizeof(a 1[0]);//総長/最初の要素の長さ.注意配列名を関数パラメータとして渡す
をクリックしてポインタに退化します.7.構造体のsizeofstruct S 1{char c;int i;};sizeofの結果はオブジェクトまたはタイプが占めるメモリバイト数に等しいので、S 1のメモリ割り当て状況を見てみましょう.S 1 s 1
= { 'a', 0xFFFFFFFF };s 1のアドレスは0 x 001 12 FF 78で、そのデータ内容は以下の通りである:0012 FF 78:61 CC CC CC FFFFFFFFFFの間に3バイトのCCが混在しているMSDNの説明を見てみる:When applied to a
structure type or variable, sizeof returns the actual size, which may include padding bytes inserted for alignment.これがバイト位置合わせです!なぜバイト整列計算機の構成原理が必要なのか、そうしないと計算機の取数速度を速めるのに役立ちます.
指令周期をもっと使わなければなりません.このため、コンパイラはデフォルトで構造体を処理し(実際には他の場所のデータ変数も同様)、幅2の基本データ型(shortなど)を2で割り切れるアドレスに配置し、幅4の基本データ型(shortなど)を4にする
データ型(intなど)はいずれも4で割り切れるアドレスにあり、このようにして、2つの数の間にパディングバイトを加える必要があるため、構造体全体のsizeof値が増加する.
1.sizeofは演算子であり、加算減算と同じ性質であり、実行時ではなくコンパイル時に実行されます.
もしプログラミングでこれを検証したら?
#include<iostream>
 
using namespace std;
 
int main()
{
    int i=1;
    cout<<i<<endl;
    sizeof(++i);
    cout<<i<<endl;
    return 1;
}

入力結果は1
               1
sizeofの++iの副作用は示されていないが,原因は1つしかないため,コンパイル時にsizeofが実行された後に++iが処理され,++iの副作用が解消された.sizeofが実行時に行われている場合は、必ず++iに注意してください.実際にsizeofの実装はマクロで行うべきであり,マクロはコンパイル時に実行される.具体的な実装については、以下を参照してください.
2.sizeof('a')C言語での結果は4で、C++での結果は1で、Cではsizeofが「数」に重点を置き、C++ではsizeofが「文字」に重点を置いているという文章を見たことがある.
3.マクロでsizeofを実現する2つの古典的な応用について述べた.
//      
#define _sizeof(T) ((size_t)((T*)0 + 1))
//     
#define array_sizeof(T) ((size_t)(&T+1)-(size_t)(&T))

まず2つの小さな例を挙げて、2つのマクロの応用を説明します.sizeof(int); の結果は4です.2番目に4サイズの配列int aを先に宣言した[4].ではarray_sizeof(a)の結果は16.
非配列のマクロ定義では、まず、0をT*型のポインタが指すアドレス(このときアドレスは0)に変換する.その後、T型のアドレスに1を加えると、T型のサイズ(すなわち、非配列Tのサイズが得られる)が加算されることになる.先のsize_tは、アドレスをint型の整数に変換して返すだけである.
簡単な例:int*p;p=p+1; --------pはint*タイプのポインタであり,p+1はアドレス空間に4バイト加算に相当する.
配列のマクロ定義は、非配列のマクロ定義と同様であり、理解を容易にするために、ここでは配列Tをユーザがカスタマイズしたタイプと見なすことができ、&Tは配列タイプを表すポインタであり、配列タイプポインタに1を加えることはアドレスにその配列サイズを加えることに相当する.ユーザがカスタマイズしたタイプであるため、0を強制的に配列タイプのアドレスに変換することはできず、1を加えたアドレスから前のアドレスを減算するしかなく、得られる差は配列自体が占めるバイトサイズである.