C言語整形定数定義

1995 ワード

本の中でこのようなテーマを見ました.
1年に何秒あるかを示すために、前処理命令defineで定数を宣言します.本の中で与えられた答えは:
#define  SECONDS_PER_YEAR  (60 * 60 * 24 * 365)UL

このマクロ定義をテストするウィジェットを書きます.次のようにします.
#include 

#define SECONDS_PER_YEAR (60*60*24*365)UL

int main()
{
    printf("%lu\r
", SECONDS_PER_YEAR); return 0; }

GCCコンパイル・タイムズを使用すると、次のエラーが発生します.
error: ‘SECONDS_PER_YEAR’ undeclared (first use in this function)
C 99規格を調べてみると(もちろん、最新のC規格C 11も調べられますが、私が使っているコンパイラの多くはC 99のみをサポートしているものです)、6.4.4節で定数の定義について述べ、それを見てみました
整形定数の定義については、次のようになります.
10進数整数定数の場合、decimal-constant integer-suffixoptはdecimal-constantとinteger-suffixの間に括弧がない形式で定義されます.だから、文章
冒頭の本で出した例題の答えは間違っている.以下、C言語における整形定数の定義について詳しく説明する.
C言語の整形定数、デフォルトのタイプについては、C 99規格の6.4.4.1節を参照してください.
The type of an integer constant is the first of the corresponding list in which its value can be represented.
すなわち、C言語の10進数整数はintタイプとしてデフォルト設定され、長さがint表現範囲を超え、long intの範囲内であればlong intタイプとみなされ、long int
表示できない場合はlong long intタイプとみなされます.一般的な32ビットシステムでプログラミングされている多くの人にとって、intとlongは32ビットであるため、最後にULを追加する可能性のある役割は明らかではありません.
しかし、組み込み環境プログラミングの人にとっては、これが必要です.プログラムが走る環境は16ビットであり、intは16ビットでlongは32ビットである可能性があるので、このときUL接尾辞を付ける必要があります.
マクロ定義の場合:
#define SECONDS_PER_YEAR  60 * 60 * 24 * 365
では60*60*24*365の結果はintとみなされ、16ビットの環境ではオーバーフローします.最後にULを追加すると、次のようになります.
#define SECONDS_PER_YEAR  60 * 60 * 24 * 365UL
上記C 99規格における整形定数の定義によれば、ULはまず365に結合され、すなわち365はunsigned longタイプの数とみなされ、C言語算術計算におけるタイプに従って上昇することが分かる.
計算式全体の計算結果もULタイプとみなされることが原則として知られている.
マクロ定義の場合:
#define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL
エラーが発生したのは、ULが結合された数字を見つけられず、16ビットの環境で60を先に計算したからです.×60×24×365は、オーバーフローして、それからこのオーバーフローした値をULと結合して、すでに意味がなくて、だからコンパイルします
間違いを報告します.
参考資料:
[1]C 99規格
[2]   http://bbs.21ic.com/icview-196689-1-1.html
[3]   http://blog.csdn.net/ropenyuan/article/details/6157589