私は以下のようなコードに出くわしました:
#define SOME_VALUE 0xFEDCBA9876543210ULL
これSOME_VALUE
は後で割り当てられunsigned long long
ます。
質問:
ULL
この場合のように後置をする必要がありますか?- 使用する整数のタイプを指定する必要がある状況は何ですか?
- この場合、CとC ++の動作は異なりますか?
C では、16 進リテラルは、接尾辞がない場合にその値を表すことができるint
, unsigned int
, long
, unsigned long
,long long
またはの最初の型を取得します。unsigned long long
C++ に同じ規則があるとしても、私は驚かないでしょう。
リテラルにデフォルトよりも大きな型を与えたい場合、またはその符号を強制したい場合は、接尾辞が必要です。たとえば、
1 << 43;
接尾辞がないと、(ほぼ確実に) 未定義の動作になりますが1LL << 43;
、たとえば問題ありません。
printf("%ld", SOME_VALUE);
場合SOME_VALUE
、間違った出力になる可能性があります。C++ でサフィックスを指定する使用の良い例は、オーバーロードされた関数です。以下に例を示します。
#include <iostream>
void consumeInt(unsigned int x)
{
std::cout << "UINT" << std::endl;
}
void consumeInt(int x)
{
std::cout << "INT" << std::endl;
}
void consumeInt(unsigned long long x)
{
std::cout << "ULL" << std::endl;
}
int main(int argc, const char * argv[])
{
consumeInt(5);
consumeInt(5U);
consumeInt(5ULL);
return 0;
}
結果:
INT
UINT
ULL
接尾辞を指定しない場合、整数リテラルの型はint
コンパイラによって推定されます。一部の整数リテラルは、その型が であると推定される場合にオーバーフローする可能性があるint
ため、接尾辞を追加して、型が 以外のものであると推定するようコンパイラに指示しますint
。それはあなたが書くときあなたがすることです0xFEDCBA9876543210ULL
。
浮動小数点数を記述するときに接尾辞を使用することもできます。1.2
は 、double
は1.2f
フロートです。
数値の正しい値を取得することが唯一の目的である場合は、接尾辞は必要ありません。C は、値が適合する型を自動的に選択します。
接尾辞は、式の中でどのように相互作用するかなどの目的で、式の型を強制したい場合に重要です。小さい型 (たとえば、1ULL<<n
or x*10LL
)をオーバーフローする算術演算を実行する場合は、long または long long にする必要があります。署名されていないセマンティクス ( c-'0'<10U
、または などn%2U
) があります。