web-dev-qa-db-ja.com

C ++のintとlongの違いは何ですか?

間違っている場合は修正してください。

intは4バイトで、値の範囲は-2,147,483,648〜2,147,483,647(2 ^ 31)です。
longは4バイトで、値の範囲は-2,147,483,648〜2,147,483,647(2 ^ 31)です。

C++の違いは何ですか?それらは同じ意味で使用できますか?

111
Joel

実装に依存します。

たとえば、Windowsでは同じですが、たとえばAlphaシステムではlongは64ビットでしたが、intは32ビットでした。この 記事 は、可変プラットフォームでのインテルC++コンパイラーのルールをカバーしています。要約する:

  OS           Arch           size
Windows       IA-32        4 bytes
Windows       Intel 64     4 bytes
Windows       IA-64        4 bytes
Linux         IA-32        4 bytes
Linux         Intel 64     8 bytes
Linux         IA-64        8 bytes
Mac OS X      IA-32        4 bytes
Mac OS X      Intel 64     8 bytes  
101
Rob Walker

あなたが持っている唯一の保証は:

sizeof(char) == 1
sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long) <= sizeof(long long)

// FROM @KTC. The C++ standard also has:
sizeof(signed char)   == 1
sizeof(unsigned char) == 1

// NOTE: These size are not specified explicitly in the standard.
//       They are implied by the minimum/maximum values that MUST be supported
//       for the type. These limits are defined in limits.h
sizeof(short)     * CHAR_BIT >= 16
sizeof(int)       * CHAR_BIT >= 16
sizeof(long)      * CHAR_BIT >= 32
sizeof(long long) * CHAR_BIT >= 64
CHAR_BIT         >= 8   // Number of bits in a byte

参照: longは少なくとも32ビットであることが保証されていますか?

78
Martin York

X64用にコンパイルする場合、使用するコンパイラに応じて、intとlongの差は0〜4バイトのどこかになります。

GCCはLP64モデルを使用します。つまり、64ビットモードではintは32ビットですが、longは64ビットです。

たとえば、MSVCはLLP64モデルを使用します。つまり、64ビットモードでもintとlongは32ビットです。

13
Adrian

C++仕様自体 (古いバージョンですが、これには十分です)はこれを開いたままにします。

4つの符号付き整数型があります: 'signed char '、' short int '、' int '、および' long int '。このリストでは、各タイプは少なくともリスト内でその前にあるストレージと同じくらいのストレージを提供します。プレーンintは、実行環境のアーキテクチャによって提案された自然なサイズを持ちます*。

[脚注:つまり、ヘッダー<climits>。 --- foonoteの終了]

12
Kevin Haines

Kevin Hainesが指摘しているように、intはINT_MINとINT_MAX内に収まらなければならない実行環境によって提案された自然なサイズを持っています。

C89標準では、UINT_MAXは2 ^ 16-1以上でなければなりません、USHRT_MAX 2 ^ 16-1およびULONG_MAX 2 ^ 32-1。これにより、ビット数は、shortおよびintで少なくとも16、longで32になります。 charの場合、少なくとも8ビット(CHAR_BIT)。 C++は、limits.hファイルのこれらの規則を継承するため、C++では、これらの値に対して同じ基本的な要件があります。ただし、notは、intが少なくとも2バイトであることから導出する必要があります。理論的には、char、int、およびlongはすべて1バイトで、その場合はCHAR_BITは少なくとも32でなければなりません。「バイト」は常にcharのサイズであるため、charが大きい場合、バイトは8ビットだけではないことに注意してください。

コンパイラーに依存します。 longは少なくともintと同じ大きさになることが保証されていますが、それ以上になることは保証されていません。

6
Andru Luvisi

ほとんどの場合、バイト数と値の範囲は、C++ではなくCPUのアーキテクチャによって決まります。ただし、C++は最小要件を設定しています。これはlitbが適切に説明し、Martin Yorkはわずかなミスを犯しました。

Intとlongを同じ意味で使用できないのは、それらが常に同じ長さではないためです。 Cは、バイトが8ビット、intが2バイトで、ハードウェア命令で直接処理できるPDP-11で発明されました。 Cプログラマーは4バイトの算術演算を必要とすることが多かったため、longが発明され、ライブラリ関数で処理される4バイトでした。他のマシンには異なる仕様がありました。 C標準には、いくつかの最小要件があります。

5

プリミティブ型サイズのコンパイラベンダーの実装に依存すると、別のマシンアーキテクチャ、OS、または別のベンダーのコンパイラでコードをコンパイルした場合に戻ってきます。

ほとんどのコンパイラベンダーは、明示的なタイプサイズのプリミティブタイプを定義するヘッダーファイルを提供しています。これらのプリミティブ型は、コードが別のコンパイラに移植される可能性がある場合に使用する必要があります(すべてのインスタンスで常にこれをお読みください)。たとえば、ほとんどのUNIXコンパイラにはint8_t uint8_t int16_t int32_t uint32_t。 MicrosoftにはINT8 UINT8 INT16 UINT16 INT32 UINT32。 Borland/CodeGearのint8 uint8 int16 uint16 int32 uint32。これらの名前は、意図する値のサイズ/範囲を少し思い出させます。

何年もの間、私はBorlandの明示的なプリミティブ型名と#include次のC/C++ヘッダーファイル(primitive.h)は、C/C++コンパイラーのこれらの名前で明示的なプリミティブ型を定義することを目的としています(このヘッダーファイルは実際にすべてのコンパイラーをカバーしているわけではありませんが、使用したいくつかのコンパイラーをカバーしていますWindows、UNIX、およびLinuxでは、(まだ)64ビット型も定義していません)。

#ifndef primitiveH
#define primitiveH
// Header file primitive.h
// Primitive types
// For C and/or C++
// This header file is intended to define a set of primitive types
// that will always be the same number bytes on any operating operating systems
// and/or for several popular C/C++ compiler vendors.
// Currently the type definitions cover:
// Windows (16 or 32 bit)
// Linux
// UNIX (HP/US, Solaris)
// And the following compiler vendors
// Microsoft, Borland/Imprise/CodeGear, SunStudio,  HP/UX
// (maybe GNU C/C++)
// This does not currently include 64bit primitives.
#define float64 double
#define float32 float
// Some old C++ compilers didn't have bool type
// If your compiler does not have bool then add   emulate_bool
// to your command line -D option or defined macros.
#ifdef emulate_bool
#   ifdef TVISION
#     define bool int
#     define true 1
#     define false 0
#   else
#     ifdef __BCPLUSPLUS__
      //BC++ bool type not available until 5.0
#        define BI_NO_BOOL
#        include <classlib/defs.h>
#     else
#        define bool int
#        define true 1
#        define false 0
#     endif
#  endif
#endif
#ifdef __BCPLUSPLUS__
#  include <systypes.h>
#else
#  ifdef unix
#     ifdef hpux
#        include <sys/_inttypes.h>
#     endif
#     ifdef Sun
#        include <sys/int_types.h>
#     endif
#     ifdef linux
#        include <idna.h>
#     endif
#     define int8 int8_t
#     define uint8 uint8_t
#     define int16 int16_t
#     define int32 int32_t
#     define uint16 uint16_t
#     define uint32 uint32_t
#  else
#     ifdef  _MSC_VER
#        include <BaseTSD.h>
#        define int8 INT8
#        define uint8 UINT8
#        define int16 INT16
#        define int32 INT32
#        define uint16 UINT16
#        define uint32 UINT32
#     else
#        ifndef OWL6
//          OWL version 6 already defines these types
#           define int8 char
#           define uint8 unsigned char
#           ifdef __WIN32_
#              define int16 short int
#              define int32 long
#              define uint16 unsigned short int
#              define uint32 unsigned long
#           else
#              define int16 int
#              define int32 long
#              define uint16 unsigned int
#              define uint32 unsigned long
#           endif
#        endif
#      endif
#  endif
#endif
typedef int8   sint8;
typedef int16  sint16;
typedef int32  sint32;
typedef uint8  nat8;
typedef uint16 nat16;
typedef uint32 nat32;
typedef const char * cASCIIz;    // constant null terminated char array
typedef char *       ASCIIz;     // null terminated char array
#endif
//primitive.h
5
Roger Nelson

C++ Standard は次のように言っています:

3.9.1、§2:

「signed char」、「short int」、「int」、「long int」、「long long int」の5つの符号付き整数型があります。このリストでは、各タイプは少なくともリスト内でその前にあるストレージと同じくらいのストレージを提供します。プレーンintは、実行環境のアーキテクチャで提案されている自然なサイズです(44)。他の符号付き整数型は、特別なニーズを満たすために提供されています。

(44)つまり、 ヘッダー<climits>で定義されているINT_MINおよびINT_MAXの範囲の値を含むのに十分な大きさ

結論:作業しているアーキテクチャに依存します。その他の仮定はすべて誤りです。

4
Jérôme Radix