演算子とは演算の内容を指示する記号です。
式とは定数、変数、関数の返却値などを演算子を使って結合したものです。
演算子には優先順位があります。
次の表の優先順位は、その演算子の優先順位を表しています。
演算子は優先順位が高いものから評価されます。
例えば「1+2*3」の場合は、「4.加減演算子」より「3.乗除演算子」の方が優先順位が高いので、「3.乗除演算子」が先に評価され、値は「7」となります。
演算子には結合規則（結合性）があります。
次の表の結合規則は、「→（左から右、左結合）」と「←（右から左、右結合）」とで結合の方向を表しています。
演算子の優先順位が同じ優先順位の場合は、結合規則の方向に演算が行われます。
例えば「a=b=1」の場合は、「14.代入演算子」は「←（右から左、右結合）」なので「b=1」が先に行われ、aとbの値はともに「1」となります。
数学と同様に()で囲むことにより優先させることができます。
オペランドとは、演算子が操作を行う対象のことであり、
定数、変数、関数の返却値、及びオペランドと演算子の組み合わせなどがオペランドとなりえます。
オペランドのデータ型は、より大きなオペランドのデータ型に変換されます（暗黙の型変換）『ISO/IEC 9899:2011』p.39「6.3.1.8 Usual arithmetic conversions」『JISX3010:2003』p.33「6.3.1.8 通常の算術型変換」。
算術演算子とは加減乗除などの算術的な計算を行う演算子です。
算術演算子には、加法を指示する+、減法を指示する-、
乗法を指示する*、除法を指示する/および剰余を指示する%があり、
また、-は符号の反転を指示するためにも用いられる。
代入演算子とは代入を指示する演算子です。
代入演算子には右辺の値を左辺が指す変数へそのまま代入するように指示する=があります。
//例 変数に算術演算子を用いた式の値を、代入演算子を用いて代入します。
int main(void)
{
	int i = -1;  // iを-1で初期化します。
	i = 1 * 1; // iに1×1である1を代入します。
	i = 1 / 1; // iに1÷1である1を代入します。
	i = 1 % 1; // iに1÷1の余りである0を代入します。
	i = 1 + 1; // iに1+1である2を代入します。
	i = 1 - 1; // iに1-1である0を代入します。
}
比較演算子とは、左辺と右辺の比較を指示する演算子です。
比較演算子は左辺が右辺と比較して、
「<（より小さい）」、「>（より大きい）」「<=（以下）」「>=（以上）」
「==（等しい）」「!=（等しくない）」の場合は真(1)を、
それ以外の場合は偽(0)を、値として返す。
『JISX3010:2003』p.62「6.5.8 関係演算子」
『JISX3010:2003』p.63「6.5.8 等価演算子」
C99で、true や false など論理値定数とのbool（論理型）が追加されました。
//例 変数に比較演算子を用いた式の値を、代入演算子を用いて代入します。
int main(void) {
  bool r;       // 変数 r を論理型として宣言
  r = 10 < 20;  // true
  r = 10 > 20;  // false
  r = 10 <= 20; // true
  r = 10 >= 20; // false
  r = 10 == 20; // false
  r = 10 != 20; // true
}
論理演算子とは、論理値の計算を指示する演算子です。
論理演算子には否定を指示する!、『JISX3010:2003』p.58「6.5.3.3 単項算術演算子」
論理積を指示する&&、『JISX3010:2003』p.65「6.5.8 論理AND演算子」
論理和を指示する||があります。『JISX3010:2003』p.65「6.5.8 論理OR演算子」
否定とは論理値の真と偽を入れ替えることを表す。
論理積とは左右両方の論理値がともに真であるときのみ真(1)を、それ以外は偽(0)を値として返す。
論理和とは左右両方の論理値のうちいずれか一方でも真であるとき真(1)を、それ以外は偽(0)を値として返す。
//例 変数に論理演算子を用いた式の値を、代入演算子を用いて代入します。
int main(void) {
  int r;
  r = !0;     // rに1を代入します。
  r = 0 && 1; // rに0を代入します。
  r = 0 || 1; // rに1を代入します。
}
&&演算子と||演算子とは、短絡評価を行う。
短絡評価とは、第1オペランドの値でその式の値が決まるとき、第2オペランドを評価しないことです。
&&演算子は第1オペランドの値が偽(0)の時、第2オペランドを評価しません。
||演算子は第1オペランドの値が真(0以外)の時、第2オペランドを評価しません。
短絡評価は、第2オペランドに副作用を伴う式を指定したとき、特に注意が必要です。
つまり、第2オペランドに関数呼び出しの式を指定して、短絡評価が行われた時、
その関数呼び出しは実行されません。
C言語には、排他的論理和の論理演算子は定義されていません。
しかし、排他的論理和は、否定・論理積・論理和を用いて次のように記述できます。
(!p != !q)
(p && !q) || (!p && q)
(p || q) && (!p || !q)
(p || q) && !(p && q)
排他的論理和とは、2つの論理値のいずれかただ１つのみが真であるとき真(1)を、それ以外は偽(0)を値として返す。
増分及び減分演算子とは、変数の値に1を加えたり、1を引いたりすることを指示する演算子です。
増分及び減分演算子には、それぞれ後置演算子と前置演算子とがあります。
後置演算子は変数の値を返した後に、増減を行う。『JISX3010:2003』p.54「6.5.2.4 後置増分及び後置減分演算子」
前置演算子は変数の値を返す前に、増減を行う。『JISX3010:2003』p.57「6.5.3.1 前置増分及び前置減分演算子」
増分及び減分演算子を単独で用いた場合、後置と前置との結果に違いはありません。
//例 後置++演算子を単独で用います。
int main(void) {
  int i = 0;
  i++; // iには1が格納されます。
}
//例 前置++演算子を単独で用います。
int main(void) {
  int i = 0;
  ++i; // iには1が格納されます。
}
ただし、増分及び減分演算子を代入演算子とともに用いた場合、後置と前置との結果に違いがあります。
//例 後置++演算子を代入演算子とともに用います。
int main(void) {
  int i = 0;
  int j;
  j = i++; // iには1が格納され、jには0が格納されます。
}
//例 前置++演算子を代入演算子とともに用います。
int main(void) {
  int i = 0;
  int j;
  j = ++i; // iには1が格納され、jには1が格納されます。
}
ISO/IEC 9899:2017§6.5.2.5 ''Compound literals''
括弧で囲まれた型名の後に、ブレースで囲まれた初期化子並び( ''initializer lists'' )を続けた後置式( ''postfix expression'')は、複合リテラル（ふくごう- 、''Compound literals''）です。
複合リテラルは、初期化子並びで与えられる値を持つ名前のないオブジェクトを与えます。
型名が未知のサイズの配列を指定している場合、そのサイズは初期化子並びによって決定され、複合リテラルの型は完成した配列の型になります。それ以外の場合（型名がオブジェクト型を指定している場合）は，型名で指定された型が複合リテラルの型となります。いずれの場合も結果は左辺値です。
複合リテラルの値は、初期化子並びで初期化された無名のオブジェクトの値です。複合リテラルが関数本体の外にある場合、そのオブジェクトは静的な保存期間を持ちますが、そうでない場合は、囲んでいるブロックに関連付けられた自動保存期間を持ちます。
初期化子並びに関するすべての意味的規則は、複合リテラルにも適用されます。
文字列リテラル、およびconst修飾された型を持つ複合リテラルは、異なるオブジェクトを指定する必要はありません。
関数の引数に定数として構造体を渡したいとき、変数を宣言して値を代入し、それを渡す必要があります。
構造体変数を関数に渡す : 
struct sPoint {
  int x, y;
};
void DrawPoint(const struct sPoint *p) { printf("%d %d\n", p->x, p->y); }
int main(void) {
  struct sPoint p = { 200, 100 };
  DrawPoint(&p);
}
複合リテラルを使えば上の処理をより簡潔に下のように書くことができます。
複合リテラルを引数として関数に渡す : 
struct sPoint {
  int x, y;
};
void DrawPoint(const struct sPoint *p) { printf("%d %d\n", p->x, p->y); }
int main(void) {
  DrawPoint(&(struct sPoint){.x = 200, .y = 100});
  // あるいは
  DrawPoint(&(struct sPoint){200, 100});
}
[https://paiza.io/projects/_siGLtD_i_cxUpu17XIcGQ?language=c 配列の複合リテラル] : 
int main(void) {
  for (int *ip = (int[]){ 2, 3, 5, 7, 11, -1}; *ip > 0; ip++)
    printf("%d\n", *ip);
}
実行結果:
2
3
5
7
11
文字列の複合リテラル
int main(void) {
  puts((char []){'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', '\n', 0});
}
sizeof演算子とは、オペランドの大きさ（バイト数: 型は size_t）を返す演算子です。『JISX3010:2003』p.58「6.5.3.4 sizeof演算子」
sizeof演算子はオペランドの大きさをバイト数で返す。
//例 sizeof演算子の使用例
int main(void)
{
	char c;
	int i;
	float f;
	double d;
	long v[100];
	printf("charのサイズは%zu。\n", sizeof(char));
	printf("intのサイズは%zu。\n", sizeof(int));
	printf("floatのサイズは%zu。\n", sizeof(float));
	printf("doubleのサイズは%zu。\n", sizeof(double));
	printf("変数cのサイズは%zu。\n", sizeof c);
	printf("変数iのサイズは%zu。\n", sizeof i);
	printf("変数fのサイズは%zu。\n", sizeof f);
	printf("変数dのサイズは%zu。\n", sizeof d);
	printf("配列vのサイズは%zu。\n", sizeof *v);
	printf("sizeof(sizeof 0)のサイズは%zu。\n", sizeof(sizeof(0)));
}
_Alignof演算子とは、オペランドのアラインメント要件（バイト数: 型は size_t）を返す演算子です。『ISO/IEC 9899:2011』p.64「6.5.3.4 The sizeof and _Alignof operators」
_Alignof演算子はオペランドのアラインメント要件をバイト数で返す。
_Alignof演算子のオペランドには（sizeof演算子と異なり）式を指定できません。
ヘッダファイルが標準に追加された。
//例 _Alignof演算子の使用例
int main(void)
{
	printf("charのアラインメント要件は%zu。\n", _Alignof(char));
	printf("intのアラインメント要件は%zu。\n", _Alignof(int));
	printf("floatのアラインメント要件は%zu。\n", _Alignof(float));
	printf("doubleのアラインメント要件は%zu。\n", _Alignof(double));
    return 0;
}
実行例（環境：  Intel Xeon Processor (Cascadelake)  上の FreeBSD 13.0-STABLE #0 stable/13-6e405dd9e x clang version 11.0.1/llvmorg-11.0.1-0-g43ff75f2c3fe）
 charのアラインメント要件は1。
 intのアラインメント要件は4。
 floatのアラインメント要件は4。
 doubleのアラインメント要件は8。
キャスト演算子とは、式の値を指定された型に型変換した値を返す演算子です。『JISX3010:2003』p.59「6.5.4 キャスト演算子」
型キャストとは、式の値を指定されたデータ型に変換します（明示的な型変換）。
//例 型キャストの使用例
int main(void)
{
	double d = 3.14;
	printf("dを整数型に変換した値は%d。\n", (int)d); //浮動小数点型の変数dを整数型に変換したものを表示します。
}
各オペランドは整数型をもたなければなりません。
<<演算子の結果は、左オペランドを右オペランド分左にシフトした値です。
>>演算子の結果は、左オペランドを右オペランド分右にシフトした値です。『JISX3010:2003』p.62「6.5.7 ビット単位のシフト演算子」
ビット単位のシフト演算子の使用例:
int main(void) {
  unsigned char c = 0xaa;   // 0b10101010
  unsigned char d = c << 1; // 0b01010100
  unsigned char e = c >> 1; // 0b01010101
  printf("dの値は%#x。\n", d);
  printf("eの値は%#x。\n", e);
}
~演算子は右オペランドの各ビットを0なら1へ1なら0へ反転します。
右オペランドは整数型をもたなければなりません。
『JISX3010:2003』p.58「6.5.3.3 単項算術演算子」
2項&演算子の結果は、オペランドのビット単位の論理積です。
つまり、対応するビットが両方ともセットされている場合ビットをセットし、それ以外の場合ビットをセットしません。
各オペランドの型は、整数型でなければなりません。
『JISX3010:2003』p.64「6.5.10 ビット単位のAND演算子」
^演算子の結果は、オペランドのビット単位の排他的論理和です。
つまり、対応するビットのいずれか一方だけがセットされている場合ビットをセットし、それ以外の場合ビットをセットしません。
各オペランドの型は、整数型でなければなりません。
『JISX3010:2003』p.64「6.5.11 ビット単位の排他OR演算子」
|演算子の結果は、オペランドのビット単位の論理和です。
つまり、対応するビットの少なくとも一方がセットされている場合ビットをセットし、それ以外の場合ビットをセットしません。
各オペランドの型は、整数型でなければなりません。
『JISX3010:2003』p.65「6.5.10 ビット単位のOR演算子」
~演算子の使用例:
int main(void) {
  unsigned char c = 0xaa; // 0b10101010
  unsigned char d = ~c;   // 0b01010101
  printf("dの値は%#x。\n", d);
}
ビット単位のAND演算子の使用例:
int main(void) {
  unsigned char c = 0x3;   // 0b00000011
  unsigned char d = 0x5;   // 0b00000101
  unsigned char e = c & d; // 0b00000001
  printf("eの値は%#x。\n", e);
}
ビット単位の排他OR演算子の使用例:
int main(void) {
  unsigned char c = 0x3;   // 0b00000011
  unsigned char d = 0x5;   // 0b00000101
  unsigned char e = c ^ d; // 0b00000110
  printf("eの値は%#x。\n", e);
}
ビット単位のOR演算子の使用例:
int main(void) {
  unsigned char c = 0x3;   // 0b00000011
  unsigned char d = 0x5;   // 0b00000101
  unsigned char e = c | d; // 0b00000111
  printf("eの値は%#x。\n", e);
}
条件演算子は、式1が0と比較して等しい場合式2を評価し、等しくない場合式3を評価します。
式2または式3の値を結果とします。『JISX3010:2003』p.65「6.5.15 条件演算子」
次のようなif文は、条件演算子を用いて、次のように書き換えることができます。
// aとbの内、大きいほうをcに代入します。
if (a > b)
  c = a;
else
  c = b;
↓
c = (a > b) ? a : b;
形式E1 op= E2の複合代入は、
左辺値E1がただ一回だけ評価される点を除いて、
単純代入式E1 = E1 op (E2)と同じとします。『JISX3010:2003』p.68「6.5.16.2 複合代入」
次のような代入文は、複合代入を用いて、次のように書き換えることができます。
a = a * b;  a *= b;
a = a / b;  a /= b;
a = a + b;  a += b;
a = a - b;  a -= b;
a = a << b; a <<= b;
a = a >> b; a >>= b;
a = a & b;  a &= b;
a = a ^ b;  a ^= b;
a = a | b;  a |= b;
コンマ演算子は、左オペランドをボイド式として評価し、次に右オペランドを評価しそれを結果として返す。『JISX3010:2003』p.68「6.5.17 コンマ演算子」
コンマ演算子の使用例:
int main(void) {
  int i = 1, j = 2, k;
  k = (i, j); // kにはjの値が代入されます。
  printf("kの値は%d。\n", k);
}
N2176 C17 ballot ISO/IEC 9899:2017 § Annex A (informative) ''Language syntax summary'' から、§6.5 ''Expressions''：式に関連した部分を抜粋しました。
トークンはリンクになっています。
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''