C++(3)式の再学習(sizeofの使用の詳細を含む)


第五章式
1.余剰オペレータを求める操作数は整数型(bool,char,short,int,longタイプおよび対応するunsignedタイプを含む)のみである.
2.論理和論理またはオペレータは、常に左のオペランドを計算してから右のオペランドを計算します.これらの評価ポリシーは、論理式の結果が左のオペランドの値だけでは決定されない場合にのみ、右のオペランドが求められます.
3.リレーショナルオペレータはboolタイプの結果を返すため、リレーショナルオペレータを直列に使用できません.(i4.ビットオペレータの場合、システムはそのオペランドのシンボルビットをどのように処理するかを確保できないため、unsigned整数オペランドを使用することを提案する.
5.シフト操作の右操作数は負数ではなく、左操作数の桁数より厳格に小さい値でなければならない.そうしないと、操作効果は定義されていない.
6.付与操作は右結合性を有する:
int i = j = 520; //ok, j = 520, i = j;

7.混同に注意=と=:
if (i = 42) // 42  i,   i 0,if    

if (i == 42) //  i    42

8.自増、自減オペレータ:
前置操作はプラス1の値を返すので、オブジェクト自体を返し、左の値です.
後置操作は右の値を返します.
**前置操作の性能は後置操作より良い:前置操作は1をプラスして結果を返すだけでよい;一方、後続操作では、1を追加しない前の値を操作結果として返すために、元の値を保存する必要があります(コンパイラは、オブジェクト全体とポインタの場合、この作業を最適化できますが、複雑な反復器タイプでは、比較的大きなパフォーマンスの違いが発生する可能性があります).
9.
cout << *iter++ << endl;
//   :
cout << *(iter++) << endl;
//   :
cout << *iter << endl;
++iter;

//             ,    *(iter++),   ,iter   ,  (iter++)          ,           ;

10.sizeofオペレータ:
a.まず、関数ではなくオペレータです.
b.戻りタイプsize_t、単位はバイトである.
c.sizeofオペレータは、関数タイプ(すなわち、関数ポインタタイプ、関数戻り値との区別に注意)に使用できません.不完全タイプまたはビットフィールド(不完全タイプとは、未知のストレージサイズを持つ配列タイプarray[]、未知のコンテンツの構造または連合タイプ、voidタイプなど)です.
d.関数呼び出しにはsizeofを使用し、コンパイル段階で関数戻り値のタイプに置き換えられる(関数は実行されないことに注意).
e.**sizeofは式の値を計算しません.その内容(括弧の中の部分)はタイプに置き換えられます.計算結果のタイプです.つまり、式の計算結果のタイプサイズを返します.
char ch = 1;
int num = 1;
int n1 = sizeof(ch+num);
int n2 = sizeof(ch = ch+num);

/*   : * ch = 1; * n1 = 4; * n2 = 1; *   : * ch+num    int, n1 = sizeof(int) = 4; * ch = ch+num    char, n2 = 1; *  sizeof        ,  ch    ; * /

f.オペランドが配列タイプを有する場合、その結果は配列の総バイト数である.
g.オペランドがコンビネーションタイプである場合、sizeofはその最大バイトメンバーのバイト数である.
h.オペランドが構造タイプである場合、sizeofはメンバータイプの総バイト数に等しくない.構造体にメンバー整列があるため、バイト充填がある可能性がある.(簡単な紹介:1.構造体の大きさは構造体の最大メンバーの大きさの整数倍に等しい;2.構造体のメンバーのヘッダアドレスは構造体のヘッダアドレスに対する【オフセット量はそのタイプの大きさの整数倍である】例えばdouble型メンバーの構造体に対するオフセット量は8の倍数であるべきである.3.コンパイラは、上記のルールを満たすために、構造体メンバーの後にバイトを入力します.**したがって、構造体メンバーの順序付けには、メモリを節約するために注意深く設計する必要があります.)
i.voidに対してsizeof操作はできないが、void*に対してsizeof操作(4 byte)を行うことができる.
j.sizeofは静的割り当てメモリの配列長を求めることができる(char配列の最後の'0'に注意).注記パラメータ配列:
void fun(int array[10])
{
    int n = sizeof(array);
}

ここでnの値は4である.ここでarrayはintタイプのポインタに変換されるため(関数間で配列を渡す場合、sizeパラメータを1つ追加することが望ましい).
k.sizeofは動的に割り当てられたメモリサイズを求めることができません!
int *a = new int[10];
int n = sizeof(a);

ここでnは4です.aはポインタですから.
l.stringはC++タイプの文字列であり、クラスであるためsizeof(s)は文字列の長さではなく、クラスstringの大きさを表す.
m.sizeofは、構造体のビットドメインメンバーのサイズを求めるために使用できませんが、ビットドメインメンバーを含む構造体のサイズを求めることができます.ビットドメイン:タイプサイズはすべてバイトを基本単位とし、1 byteは8 bitに等しいです.charタイプは1 byte,すなわち8 bitなので,2^8=256個の数を定義できる.しかしsizeof(bool)=1であり、boolはtrueとfalseの2つの数のみを表し、本来は1 bitしか必要としないが8 bitを占有している.ビットドメインによってメモリを細かく計算できます.簡単に言えば、構造体メンバー変数の後にコロン+整数がビットドメインを表します.
struct A
{
    bool b:1;
    char ch1:4;
    char ch2:4;
}item;

以上のb,ch 1,ch 2はドメインメンバーに即位し,bが1 bit,ch 1,ch 2の各4 bitのみを占有するようにした.なお、ビットドメイン変数は、構造体、クラス、unionでのみ使用できます.
11.カンマ式の結果は、その右端の式の値です.
12.
int *pi = new int; //     
int *pi = new int(); //    0

13.ゼロ値ポインタの削除は合法的であるが、意味がない.
14.ポインタが指すオブジェクトを削除したら、直ちにポインタを0にし、誤って使用しないようにポインタを使用する前に検査しなければならない.