0

Netbeans C/C++ でこの奇妙な状況に遭遇しました。状況は次のとおりです。プロジェクト エクスプローラーの [ソース ファイル] の下に、main.c と problem3.c があります。

main.c で

    #include <stdio.h>
    #include <stdlib.h>

    // long BigNumber(){
        // return 600851475143;
    // }


    int main(int argc, char* argv[]) {
        printf("%lu", BigNumber() );

        return (EXIT_SUCESS);
    }

problem3.c で

     long BigNumber(){
         return 600851475143;
     }

私の場合は、問題 3.c の BigNumber() を使用すると、403282979527正しくない が出力されます。しかし、main.c の BigNumber() を使用すると、600851475143.

背後にある魔法を説明できる人はいますか? プラットフォームのせいですか、それとも などのツールのせいmakeですか? Windows 7 32 ビット、NetBeans 7.3.1、MinGW を使用しています。

4

1 に答える 1

1

Windows 32 ビットは LP32 または 4/4/4 モデルに従い、int、long、およびポインターはすべて 32 ビット (4 バイト) の長さであり、格納する数値は 32 ビットより大きく、符号付きまたはいいえ。最初のケースでまったく機能するという事実は、実際には単なる偶然です。おそらく、それを他のファイルに移動することによって引き起こされるリンク手順は、あなたが見ている問題を引き起こす他の動作を「引き起こします」. gcc はここでもオーバーフローを警告します。

いくつかのオプションがありますが、単純なものはint64_t代わりにを使用することです(これが、結局のところ、これらすべてのタイプが存在するlong理由です!)。intxx_tまた、リテラルに LL サフィックスを使用して、それがlong longリテラルであることをコンパイラに通知し、printf を("llu"の代わりに使用するように変更する必要があります)"lu"long long

完全に修正:

#include <stdio.h>
#include <stdlib.h>

int64_t BigNumber() {
    return 600851475143LL;
}

int main(int argc, char* argv[]) {
    printf("%llu", BigNumber() );
    return 0;
}

この関数は適切に定義されているため、安全に移動できるはずです。

于 2013-11-11T04:46:54.247 に答える