web-dev-qa-db-ja.com

sizeofが演算子と見なされるのはなぜですか?

sizeofが関数ではなく演算子と見なされるのはなぜですか?

オペレーターとしての資格を得るにはどのようなプロパティが必要ですか?

82
Arpit

C標準はそう言っており、唯一の票を獲得するからです。

結果として:

  • Sizeofのオペランドは、オブジェクト式ではなく、括弧付きの型sizeof (int)にすることができます。
  • 括弧は不要です:int a; printf("%d\n", sizeof a);はまったく問題ありません。これらはよく見られます。1つ目は型キャスト式の一部として必要なため、2つ目はsizeofの優先順位が非常に高いためです。したがって、_sizeof a + b_はsizeof (a+b)と同じではありません。しかし、それらはsizeofの呼び出しの一部ではなく、オペランドの一部です。
  • Sizeofのアドレスを取得することはできません。
  • Sizeofのオペランドである式は、実行時に評価されません(_sizeof a++_はaを変更しません)。
  • Sizeofのオペランドである式は、voidまたは関数型を除く任意の型を持つことができます。確かに、それはsizeofのポイントのようなものです。

関数は、これらすべての点で異なります。関数と単項演算子の間にはおそらく他の違いもありますが、sizeofが必要な理由があっても、sizeofが関数になれない理由を示すのに十分だと思います。

169
Steve Jessop

コンパイル時定数として使用できます。これは、関数ではなく演算子の場合にのみ可能です。例えば:

union foo {
    int i;
    char c[sizeof(int)];
};

構文上、演算子ではない場合、関数は引数として型を取ることができないため、プリプロセッサマクロである必要があります。 sizeofは型と変数の両方を引数として取ることができるため、これは実装が難しいマクロです。

21
John Kugelman

C標準はそう言っており、唯一の票を獲得しているからです。

そして、sizeofは型を取り、

一般に、関数のドメインまたはコドメイン(または両方)に実数よりも大幅に複雑な要素が含まれる場合、その関数は演算子と呼ばれます。逆に、関数のドメインにもコドメインにも実数よりも複雑な要素が含まれていない場合、その関数は単に関数と呼ばれる可能性があります。コサインなどの三角関数は、後者の例です。

さらに、汎用F(x、y、z、...)形式よりも速くまたは簡単な表記法に進化した関数が頻繁に使用される場合、結果の特殊形式は演算子とも呼ばれます。例には、加算「+」や除算「/」などの中置演算子や、階乗「!」などの後置演算子が含まれます。この使用法は、関係するエンティティの複雑さとは無関係です。

(Wikipedia)

5

それは機能ではないからです。次のように使用できます。

int a;
printf("%d\n", sizeof a);

関数にはエントリポイント、コードなどがあります。関数は実行時に実行(またはインライン化)する必要があり、sizeofはコンパイル時に決定する必要があります。

4
Michał Górny

なぜなら:

  • 値を関数に渡すと、オブジェクトのサイズは関数に渡されないため、sizeof "関数"にはサイズを決定する方法がありません。
  • cでは、関数は1つのタイプの引数のみを受け入れます。 sizeof()は、あらゆる種類の異なるもの(変数と型!Cの関数に型を渡すことはできません)を受け入れる必要があります
  • 関数の呼び出しには、引数およびその他の不要なオーバーヘッドのコピーが含まれます
1
Artelius

関数とは少し異なります-sizeofの値はコンパイル時に解決されますが、実行時ではありません!

1
Dewfy

コンパイル時演算子であるため、オブジェクトのサイズを計算するには、コンパイル時にのみ使用可能な型情報が必要です。これはC++には当てはまりません。

1
João Silva

sizeof演算子は、ランタイムではなくコンパイル時のエンティティであり、関数のように括弧を必要としません。コードをコンパイルすると、コンパイル時に値がその変数のサイズに置き換えられますが、関数が実行された後の関数では、戻り値がわかります。

sizeof()演算子は、コンパイル時に発生します。パラメータまたは引数を決定するために使用できます。

0
ganesh