[C言語入門] 演算子の使い方(9)
高木です。こんばんは。
この「演算子の使い方」もはや9回です。
どれだけこのネタで引っ張るんだといわれそうですが、時間はかかっても最後までやりますよ。
というわけで、今回は加減演算子についての解説です。
加減演算子
加減演算子というと難しそうに聞こえますが、要するに足し算(加算)と引き算(減算)の演算子です。
単項算術演算子の+と-もありますので、加減演算子のほうは二項+演算子、二項-演算子という言い方をすることもあります。
加減演算子のオペランドはいくつかの組み合わせが考えられます。
単純なのは両方のオペランドともに算術型の場合ですね。
それ以外には、一方または両方のオペランドがポインタ型の場合があります。
オペランドの組み合わせとしては以下のものが考えられます。
- 算術型 + 算術型
- 算術型 – 算術型
- ポインタ型 + 整数型
- ポインタ型 – 整数型
- 整数型 + ポインタ型
- ポインタ型 – ポインタ型
ここで、ポインタ型は(修飾版または非修飾版の)オブジェクト型へのポインタ型でなければなりません。
関数型や不完全型へのポインタはダメということですね。
コンパイラによっては、void*を加減演算子のオペランドに取ることができるものもありますが、標準規格ではできません。
また、ポインタ型同士の引き算では、両方のオペランドは適合する型へのポインタ型でなければなりません。
全然違う型へのポインタ同士の減算はできません。
両方のオペランドが算術型の場合、実際の演算の前に「通常の算術型変換」が行われます。
「通常の算術型変換」が行われた結果の型が、演算の評価結果の型になります。
評価結果の型で表現可能な範囲であれば、両方のオペランドが算術型の加減算の結果は代数的な演算の結果に一致します。
そうではない場合、評価結果の型が符合無し整数型であれば、その型の最大値+1を法とする剰余が結果の値になります。
結果の型が符合付き整数型や浮動小数点型であれば、オーバーフローが生じる場合があります。
浮動小数点型には複素数型も含まれることに注意してください。
一方のオペランドがポインタ型でもう一方のオペランドが整数型の場合は次のようになります。
ポインタP
が配列A
のi
番目の要素を指す場合(すなわち&A[i]
である場合)、整数値N
との加算結果P+N
またはN+P
は&A[i+N]
になります。
ポインタが配列ではないオブジェクトを指す場合、そのオブジェクト型を要素とする1要素の配列とみなします。
減算の場合も同様で、P-N
は&A[i-N]
になります。
ただし、i+N
またはi-N
はオーバーフローが生じてはなりません。
または、結果のポインタは実際の配列の要素、または配列の末尾の要素をひとつ越えたところを指していなければなりません。
配列の末尾の要素をひとつ越えたところを指すポインタを単項*演算子のオペランドとした場合の動作は未定義です。
適合するポインタ型同士の減算の評価結果はptrdiff_t型になります。
ptrdiff_t型は<stddef.h>ヘッダで定義されている符合付き整数型です。
同じ配列のi
番目の要素を指すポインタP
とj
番目の要素を指すポインタQ
の減算結果は、i-j
になります。
i
およびj
は、配列の要素または末尾の要素をひとつ越えた添字でなければなりません。
ポインタに対する加減算は、可変長配列型へのポインタに対しても同様に行うことができます。