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


93

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

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

回答:


181

C標準がそう言っているので、それが唯一の票を得ます。

結果として:

  • sizeofのオペランドはsizeof (int)、オブジェクト式ではなく、括弧で囲まれた型にすることができます。
  • 括弧は不要ですint a; printf("%d\n", sizeof a);。完全に問題ありません。彼らは、多くの場合、それらは型キャスト式の一部として必要に応じて、およびsizeofが非常に高い優先順位を持つ第二ので、そうしているまずので、見ているsizeof a + bと同じではありませんsizeof (a+b)。しかし、それらはsizeofの呼び出しの一部ではなく、オペランドの一部です。
  • sizeofのアドレスを取得することはできません。
  • sizeofのオペランドである式は、実行時に評価されsizeof a++ません(aを変更しません)。
  • sizeofのオペランドである式は、void以外の任意の型、または関数型を持つことができます。確かに、それは一種のsizeofのポイントです。

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


3
うわー、まさに私が考えていたもの!
crashmstr 2009

7
それをよりよく言うことはできません。
クレメントエレマン2009

可変長配列(VLA)により、最近の状況はより複雑になっていると思います。IIRC、標準ではsizeof、式にVLAが含まれている場合でも副作用を許可します。
Aaron McDaid、2015年

@glglglいいえ、意味がありません。そのコンテキストで(int)は、特別なことは何もありません-括弧内の型の名前だけです。ここの括弧は、構文の一部ですsizeof-型のサイズを取得する場合は必須ですが、式のサイズを取得する場合は必須ではありません。たとえば、こちらを
anatolyg

1
標準では、sizeofsizeof unary-expressionとの2つの表記法を使用しています。sizeof ( type-name )そのため、C11標準では、「キャスト」ではなく括弧で囲まれた型名と見なされます。最終結果はほとんど同じです。(比較として、キャスト式は( type-name ) cast-expressionです。)そして、コメントのMarkdownがQ&A Markdownとは異なる動作をするのが嫌いです。
ジョナサンレフラー

24

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

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

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


4
+1ですが、引数がVLA-可変長配列の場合は、コンパイル時の定数ではないことに注意してください。
ジョナサンレフラー

6

C標準がそう言っているので、それが唯一の票を得ます。

そして、sizeofタイプを取り、

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

さらに、関数が頻繁に使用されて、一般的なF(x、y、z、...)形式よりも高速または簡単な表記法に進化した場合、結果の特殊な形式も演算子と呼ばれます。例には、加算 "+"や除算 "/"などのインフィックス演算子や、階乗 "!"などのポストフィックス演算子が含まれます。この使用法は、関係するエンティティの複雑さとは無関係です。

(ウィキペディア)


これはおそらく、C規格(およびその他のプログラミング言語)が「演算子」および「関数」という用語を使用する動機を説明していると考えられます。
スティーブジェソップ

5

関数ではないからです。あなたはそれをそのように使うことができます:

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

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


2

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


1

なぜなら:

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


1

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


0

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


-1

Sizeof()、明らかに関数と演算子の両方だと思います。どうして?関数は、エントリの段階でエントリの括弧を保持するためです。ただし、主に演算子原因演算子もアクション文字であるため、sizeofは括弧内のオペランドに作用するアクションステートメントです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.