名前空間
変種
操作

その他の演算子

From cppreference.com
< c‎ | language

他の主要なカテゴリに分類されない演算子のコレクション。

Operator 演算子名 説明
(...) 関数呼び出し f(...) 関数f() を、ゼロ個以上の引数で呼び出します。
, カンマ演算子 a, b aを評価し、その戻り値を無視して副作用を完了した後、式bを評価し、その評価の型と結果を返します。
(type) 型キャスト (type)a aの型をtypeにキャストします。
? : 条件演算子 a ? b : c aが論理的に真(ゼロに評価されない)の場合、式bを評価し、そうでなければ式cを評価します。
sizeof sizeof演算子 sizeof a aのバイト単位のサイズ
_Alignof
(C11 以降)
_Alignof演算子 _Alignof(type) typeに必要なアライメント
typeof typeof演算子 typeof(a) aの型

目次

[編集] 関数呼び出し

関数呼び出し式は次の形式をとります。

expression ( argument-list (optional) )

ここで、

- 関数型へのポインタの任意の式(lvalue変換後)
argument-list - カンマ区切りの式のリスト(カンマ演算子であってはならない)。任意の完全なオブジェクト型。引数を取らない関数を呼び出す場合は省略できます。

関数呼び出し式の動作は、呼び出される関数のプロトタイプが呼び出し時点でスコープ内にあるかどうかに依存します。

[編集] プロトタイプを持つ関数への呼び出し

1) パラメータの数と引数の数は一致しなければなりません(可変長引数パラメータが使用されている場合を除く)。
2) 各パラメータの型は、対応する引数の修飾されていない型をパラメータの型に変換する代入による暗黙の変換が存在するような型でなければなりません。
さらに、[]の間にstaticキーワードを使用する配列型のすべてのパラメータについて、引数式は、パラメータのサイズ式で指定された少なくともその数の要素を持つ配列の要素へのポインタを指定しなければなりません。
(C99以降)
3) 引数は、未指定の順序で、シーケンスなしで評価されます。
4) 代入が行われ、各引数の値が対応する関数パラメータにコピーされます。パラメータ型とその再帰的な要素やメンバーの型修飾子は無視されます(注意: 関数はパラメータを変更できますが、その変更は引数に影響しません。Cの関数呼び出しは値渡しのみです)。
5) 関数が実行され、その戻り値が関数呼び出し式の値となります(関数がvoidを返す場合、関数呼び出し式はvoid式になります)。
void f(char* p, int x) {}
int main(void)
{
    f("abc", 3.14); // array to pointer and float to int conversions
}

プロトタイプを持たない関数への呼び出し

1) 引数は、未指定の順序で、シーケンスなしで評価されます。
2) すべての引数式に対して、デフォルト引数プロモーションが行われます。
3) 代入が行われ、各引数の値が対応する関数パラメータにコピーされます。パラメータ型とその再帰的な要素やメンバーの型修飾子は無視されます。
4) 関数が実行され、その戻り値が関数呼び出し式の値となります(関数がvoidを返す場合、関数呼び出し式はvoid式になります)。
void f(); // no prototype
int main(void)
{
    f(1, 1.0f); // UB unless f is defined to take an int and a double
}
void f(int a, double c) {}

プロトタイプを持たない関数への関数呼び出しの動作は、以下の場合に未定義となります。

  • 引数の数がパラメータの数と一致しない。
  • 引数のプロモートされた型が、パラメータのプロモートされた型と互換性がない場合。ただし、
  • 同じ整数型の符号付きバージョンと符号なしバージョンは、引数の値が両方の型で表現可能な場合、互換性があるとみなされます。
  • voidへのポインタと(修飾されている可能性のある)文字型へのポインタは互換性があるとみなされます。
(C23まで)

[編集] 注記

呼び出される関数を指定するexpressionの評価と、すべての引数は互いにシーケンスなしですが、関数の本体が実行を開始する前にシーケンスポイントがあります。

(*pf[f1()]) (f2(), f3() + f4()); // f1, f2, f3, f4 may be called in any order

関数呼び出しは関数へのポインタに対してのみ定義されていますが、関数指定子による関数からポインタへの暗黙の変換により機能します。

int f(void) { return 1; }
int (*pf)(void) = f;
 
int main(void)
{
    f();    // convert f to pointer, then call
    (&f)(); // create a pointer to function, then call
 
    pf();    // call the function
    (*pf)(); // obtain the function designator, convert to pointer, then calls
 
    (****f)(); // convert to pointer, obtain the function, repeat 4x, then call
    (****pf)(); // also OK
}

printfのように未使用の引数を無視する関数は、未定義の動作を呼び出すことを避けるために、スコープ内にプロトタイプを持つ必要があります(そのような関数のプロトタイプは、必然的に可変長引数パラメータを使用します)。

現在の標準の関数パラメータ準備セマンティクスは、呼び出し中にパラメータが引数から代入されると指定しているため、const修飾されたパラメータまたはメンバー型を誤って拒否し、多くのプラットフォームで関数パラメータに実装不可能なvolatileのセマンティクスを不適切に適用するため、欠陥があります。C11以降の欠陥報告DR427では、そのようなセマンティクスを代入から初期化に変更することが提案されましたが、欠陥ではないとして却下されました。

関数呼び出し式で、expressionが識別子のみで構成され、その識別子が宣言されていない場合、その識別子は以下のように宣言されているかのように扱われます。

extern int identifier(); // returns int and has no prototype

したがって、以下の完全なプログラムは有効なC89です。

main()
{
    int n = atoi("123"); // implicitly declares atoi as int atoi()
}
(C99まで)

[編集] カンマ演算子

カンマ演算子式は次の形式をとります。

lhs , rhs

ここで、

lhs - 任意の式
rhs - 別のカンマ演算子ではない任意の式(言い換えれば、カンマ演算子の結合規則は左から右)

まず、左オペランドであるlhsが評価され、その結果の値は破棄されます。

次に、シーケンスポイントが発生するため、lhsのすべての副作用が完了します。

次に、右オペランドであるrhsが評価され、その結果がカンマ演算子によって非lvalueとして返されます。

[編集] 注記

lhsの型はvoidである場合があります(つまり、voidを返す関数への呼び出しであるか、voidキャストされた式である可能性があります)。

カンマ演算子はC++ではlvalue式になり得ますが、Cでは決してlvalue式にはなりません。

カンマ演算子はstructを返すことができます(structを返す唯一の他の式は、複合リテラル、関数呼び出し、代入、および条件演算子です)。

以下のコンテキストでは、カンマは別の意味を持つため、カンマ演算子は式のトップレベルに現れることができません。

そのようなコンテキストでカンマ演算子を使用する必要がある場合は、括弧で囲む必要があります。

// int n = 2,3; // error, comma assumed to begin the next declarator
// int a[2] = {1,2,3}; // error: more initializers than elements
int n = (2,3), a[2] = {(1,2),3}; // OK
 
f(a, (t=3, t+2), c); // OK, first, stores 3 in t, then calls f with three arguments

トップレベルのカンマ演算子は、配列の境界でも許可されません。

// int a[2,3]; // error
int a[(2,3)]; // OK, VLA array of size 3 (VLA because (2,3) is not a constant expression)

カンマ演算子は、定数式では、トップレベルであるかどうかにかかわらず許可されません。

// static int n = (1,2); // Error: constant expression cannot call the comma operator

[編集] キャスト演算子

キャスト演算子」を参照してください。

[編集] 条件演算子

条件演算子式は次の形式をとります。

condition ? expression-true : expression-false

ここで、

condition - スカラー型の式
expression-true - conditionがゼロと等しくないと比較された場合に評価される式
expression-false - conditionがゼロと等しく比較された場合に評価される式

expression-trueおよびexpression-falseとして許可される式は以下の通りです。

(C23以降)
  • 一方がポインタで、もう一方がヌルポインタ定数(NULLなど)である場合またはnullptr_t(C23以降)
  • 一方がオブジェクトへのポインタで、もう一方が(修飾されている可能性のある)voidへのポインタである場合
1) まず、conditionを評価します。シーケンスポイントがこの評価の後にあります。
2) conditionの結果がゼロと等しくないと比較された場合、expression-trueを実行します。そうでなければ、expression-falseを実行します。
3) 評価の結果から、以下のように定義される「共通型」への変換を行います。
1) 式が算術型の場合、共通型は通常の算術変換後の型です。
2) 式が構造体/共用体型の場合、共通型はその構造体/共用体型です。
3) 式が両方ともvoidの場合、条件演算子式全体はvoid式になります。
4) 一方がポインタで、もう一方がヌルポインタ定数またはnullptr_t(C23以降)の場合、型はそのポインタの型になります。
5) 両方がポインタの場合、結果は両方のポインタ対象型のcvr修飾子を結合した型へのポインタになります(つまり、一方がconst int*で、もう一方がvolatile int*の場合、結果はconst volatile int*になります)。そして、型が異なる場合、ポインタ対象型は複合型になります。
6) 一方がvoidへのポインタの場合、結果はcvr修飾子を結合したvoidへのポインタになります。
7) 両方がnullptr_t型の場合、共通型もnullptr_tになります。
(C23以降)
#define ICE(x) (sizeof(*(1 ? ((void*)((x) * 0l)) : (int*)1)))
 
// if x is an Integer Constant Expression then macro expands to
 
sizeof(*(1 ? NULL : (int *) 1))  // (void *)((x)*0l)) -> NULL
 
// according to point (4) this further converts into
 
sizeof(int)
 
// if x is not an Integer Constant Expression then macro expands to
// according to point (6)
 
(sizeof(*(void *)(x))           // Error due incomplete type

[編集] 注記

条件演算子はlvalue式にはなりませんが、構造体/共用体型のオブジェクトを返すことがあります。構造体を返す唯一の他の式は、代入カンマ関数呼び出し、および複合リテラルです。

C++では、lvalue式になり得ることに注意してください。

この演算子と代入の相対的な優先順位の詳細については、「演算子の優先順位」を参照してください。

条件演算子は右から左への結合規則を持ち、連鎖を可能にします。

#include <assert.h>
 
enum vehicle { bus, airplane, train, car, horse, feet };
 
enum vehicle choose(char arg)
{
    return arg == 'B' ? bus      :
           arg == 'A' ? airplane :
           arg == 'T' ? train    :
           arg == 'C' ? car      :
           arg == 'H' ? horse    :
                        feet     ;
}
 
int main(void)
{
    assert(choose('H') == horse && choose('F') == feet);
}

[編集] sizeof演算子

sizeof演算子」を参照してください。

[編集] _Alignof演算子

_Alignof演算子」を参照してください。

[編集] typeof演算子

typeof演算子」を参照してください。

[編集] 参考文献

  • C23標準 (ISO/IEC 9899:2024)
  • 6.5.2.2 関数呼び出し (p: TBD)
  • 6.5.3.4 sizeof および _Alignof 演算子 (p: TBD)
  • 6.5.4 キャスト演算子 (p: TBD)
  • 6.5.15 条件演算子 (p: TBD)
  • 6.5.17 カンマ演算子 (p: TBD)
  • 6.7.3.5 Typeof 指定子 (p: 115-118)
  • C17標準 (ISO/IEC 9899:2018)
  • 6.5.2.2 関数呼び出し (p: 58-59)
  • 6.5.3.4 sizeof および _Alignof 演算子 (p: 64-65)
  • 6.5.4 キャスト演算子 (p: 65-66)
  • 6.5.15 条件演算子 (p: 71-72)
  • 6.5.17 カンマ演算子 (p: 75)
  • C11標準 (ISO/IEC 9899:2011)
  • 6.5.2.2 関数呼び出し (p: 81-82)
  • 6.5.3.4 sizeofおよび_Alignof演算子 (p: 90-91)
  • 6.5.4 キャスト演算子 (p: 91)
  • 6.5.15 条件演算子 (p: 100)
  • 6.5.17 カンマ演算子 (p: 105)
  • C99標準 (ISO/IEC 9899:1999)
  • 6.5.2.2 関数呼び出し (p: 71-72)
  • 6.5.3.4 sizeof 演算子 (p: 80-81)
  • 6.5.4 キャスト演算子 (p: 81)
  • 6.5.15 条件演算子 (p: 90-91)
  • 6.5.17 カンマ演算子 (p: 94)
  • C89/C90標準 (ISO/IEC 9899:1990)
  • 3.3.2.2 関数呼び出し
  • 3.3.3.4 sizeof 演算子
  • 3.3.4 キャスト演算子
  • 3.3.15 条件演算子
  • 3.3.17 カンマ演算子

[編集] 関連項目

共通の演算子
代入 インクリメント
デクリメント
算術 論理 比較 メンバ
アクセス
その他

a = b
a += b
a -= b
a *= b
a /= b
a %= b
a &= b
a |= b
a ^= b
a <<= b
a >>= b

++a
--a
a++
a--

+a
-a
a + b
a - b
a * b
a / b
a % b
~a
a & b
a | b
a ^ b
a << b
a >> b

!a
a && b
a || b

a == b
a != b
a < b
a > b
a <= b
a >= b

a[b]
*a
&a
a->b
a.b

a(...)
a, b
(type) a
a ? b : c
sizeof


_Alignof
(C11 以降)
(C23まで)

alignof
(C23以降)

C++ ドキュメント: その他の演算子
English 日本語 中文(简体) 中文(繁體)