sizeof演算子

以下について、sizeofでサイズを調べてみます。

  1. 文字列リテラル
  2. 初期値を持つchar型配列
  3. 初期値を持つint型配列
  4. char型配列を指すポインタ変数
  5. 文字リテラル
  6. 空文字列
  1 #include <stdio.h>
  2 
  3 int main()
  4 {
  5     char    data[] = "ABCDE";
  6     int     data2[] = {1,2,3,4,5};
  7     char    *pdata = data;
  8 
  9     printf("1: sizeof(\"ABCDE\")   = %d\n", sizeof("ABCDE"));
 10     printf("2: sizeof(data)      = %d\n", sizeof(data));
 11     printf("3: sizeof(data2)     = %d\n", sizeof(data2));
 12     printf("4: sizeof(pdata)     = %d\n", sizeof(pdata));
 13     printf("5: sizeof(*pdata)    = %d\n", sizeof(*pdata));
 14     printf("6: sizeof('A')       = %d\n", sizeof('A'));
 15     printf("7: sizeof(\"\")        = %d\n", sizeof(""));
 16 
 17     if(sizeof(char) - 100 < 0)
 18         printf("OK.\n");
 19     else
 20         printf("NG.\n");
 21 
 22     return 0;
 23 }

結果は、

1: sizeof("ABCDE")   = 6
2: sizeof(data)      = 6
3: sizeof(data2)     = 20
4: sizeof(pdata)     = 4
5: sizeof(*pdata)    = 1
6: sizeof('A')       = 4
7: sizeof("")        = 1
NG
  1. 文字列リテラルは、末尾にナル文字が付加されるので、6バイト。
  2. 初期値を持つchar型配列は、末尾にナル文字が付加されるので、6バイト。
  3. 初期値を持つint型配列は、char型配列と違ってナル文字は付加されないので、5*4=20バイト。
  4. char型配列を指すポインタ変数は、当然4バイト。
  5. ポインタの参照先はchar型なので、1バイト。
  6. 文字リテラルは、int型なので4バイト。
  7. 空文字列は1バイト。

文字リテラルがint型であること、初期値を持つchar型配列は末尾にナル文字が付加される、という点は留意したいです。
また、sizeofそのものの注意点として…

  1. sizeofが返すsize_t型とは、符号なし広義整数型である。「符号なし」のため、
  2. size_t型は符号なしなので、演算時の二項変換などに注意する。例えば、17〜20行目において、「sizeof(char)-100」の評価結果は「-99」となりそうだが、-演算子の左オペランドがunsignedだが右オペランドが100(signed int)であるため、右オペランドはunsignedに型変換され、評価結果はunsignedとなる。そのため、条件<0は、つねに成立しない。
  3. C99以前では、sizeof演算子オペランドは評価されない。例えば、sizeof(i++)において、iはインクリメントしない。ただしC99では可変長配列が導入されたため、sizeofは定数式ではなくなった。