C ++ 표준은 int, long 유형의 크기를 무엇이라고 말합니까?


696

기본 C ++ 유형의 크기에 대한 자세한 정보를 찾고 있습니다. 아키텍처 (16 비트, 32 비트, 64 비트)와 컴파일러에 따라 다릅니다.

그러나 C ++에 대한 표준이 있습니까?

32 비트 아키텍처에서 Visual Studio 2008을 사용하고 있습니다. 내가 얻는 것은 다음과 같습니다.

char  : 1 byte
short : 2 bytes
int   : 4 bytes
long  : 4 bytes
float : 4 bytes
double: 8 bytes

나는의 크기를 나타 신뢰할 수있는 정보를, 많은 성공없이 찾을려고 char, short, int, long, double, float다른 아키텍처와 컴파일러에서 (그리고 다른 종류의 내가 생각하지 않았다).


18
@thyrgle 선택에 의한 것이 아니라 ... 지원할 아키텍처가 너무 많아서 유연해야합니다.
크라 쿠스


4
모든 모호한 유형을 제거하지 않고 int32_t, uint32_t, int64_t 등과 같은 명확한 비트 길이 유형으로 모두 표준화하지 않겠습니까?
developerbmw

5
@thyrgle 실제로 이와 같은 것을 표준화하는 것은 꽤 어렵습니다. JVM이 작동하는 방식으로 인해 이러한 것들이 일정한 Java와는 달리 C / C ++는 기본적으로 팬시 추상화 계층 (적어도 Java만큼 많지 않음)없이 실행되는 시스템을 고수해야합니다. 중에서. INT의 크기가 중요한 사용할 수있는 경우 int16_t, int32_t그리고 int64_t((가) 필요 iostream내가 제대로 기억한다면 그것을 위해 포함). int64_t가 32 비트 시스템에서 문제를 가져서는 안된다는 점에서 좋은 점은 (성능에 영향을 줄 것입니다).
rbaleksandar

5
@rbaleksandar 그것들은 실제로에 정의되어 <cstdint>있지 않습니다 <iostream>.
저스틴 타임-복원 모니카

답변:


685

C ++ 표준은 정수 유형의 크기를 바이트 단위로 지정하지 않지만 보유 할 수있는 최소 범위를 지정합니다. 필요한 범위에서 최소 크기를 비트 단위로 추론 할 수 있습니다. 바이트 단위 로 비트 수CHAR_BIT정의하는 매크로 값과 그 값에서 최소 바이트 크기를 유추 할 수 있습니다 . 가장 애매 모호한 플랫폼을 제외하고는 8이고 8보다 작을 수 없습니다. "유니 코드 UTF-8 인코딩 형식의 8 비트 코드 단위"를 보유 할 수있을만큼 커야하기 때문입니다.

하나의 추가 제약 조건 char은 크기가 항상 1 바이트 또는 CHAR_BIT비트 (따라서 이름)라는 것입니다. 이것은 표준에 명시 적으로 명시되어 있습니다.

C 표준은 C ++ 표준에 대한 규범적인 참조 이므로 이러한 요구 사항을 명시 적으로 명시하지 않더라도 C ++에는 C 표준 (22 페이지)에 필요한 최소 범위가 필요합니다 . MSDN :

  1. signed char: -127 ~ 127 (참고 : -128 ~ 127이 아니라 1의 보수 및 부호 및 크기 플랫폼을 수용 함)
  2. unsigned char: 0 ~ 255
  3. "plain" char: signed char또는 범위와 동일 범위 unsigned char, 구현 정의
  4. signed short: -32767 ~ 32767
  5. unsigned short: 0 ~ 65535
  6. signed int: -32767 ~ 32767
  7. unsigned int: 0 ~ 65535
  8. signed long: -2147483647 ~ 2147483647
  9. unsigned long: 0 ~ 4294967295
  10. signed long long: -9223372036854775807 ~ 9223372036854775807
  11. unsigned long long: 0-18446744073709551615

C ++ (또는 C) 구현은 유형의 크기를 바이트 단위 sizeof(type)로 모든 값 에 대해 정의 할 수 있습니다

  1. 이 식은 sizeof(type) * CHAR_BIT필요한 범위를 포함 할 수있을 정도로 높은 비트 수로 평가되며
  2. 유형의 순서는 여전히 유효합니다 (예 :) sizeof(int) <= sizeof(long).

이 모든 것을 종합하면 다음이 보장됩니다.

  • char, signed char그리고 unsigned char적어도 8 비트
  • signed short, unsigned short, signed intunsigned int적어도 16 비트이다
  • signed long그리고 unsigned long적어도 32 비트이다
  • signed long long그리고 unsigned long long적어도 64 비트이다

크기 float나 크기를 double제외하고 double는 최소 정밀도를 제공하지 않습니다 float.

실제 구현 별 범위는 <limits.h>C의 헤더 또는 <climits>C ++ (또는 더 나은 헤더 에서 템플릿 화) std::numeric_limits에서 찾을 수 있습니다 <limits>.

예를 들어, 다음에 대한 최대 범위를 찾는 방법입니다 int.

씨:

#include <limits.h>
const int min_int = INT_MIN;
const int max_int = INT_MAX;

C ++ :

#include <limits>
const int min_int = std::numeric_limits<int>::min();
const int max_int = std::numeric_limits<int>::max();

49
오히려 C ++ 표준은 단어 byte 를 사용 char하여 일반적인 의미가 아니라 "1 "을 의미합니다.
Ben Voigt

4
@Programmer 답 (괄호 안의 1 점 참고) 또는 실제 표준 표현 (답변에 링크되어 있음)을 읽으십시오. C 표준은 가장 광범위한 2의 보수와 다른 표현을 갖는 1의 보수 아키텍처를 수용합니다. 최소 보장 범위는 구현이 제공하는 실제 범위와 거의 항상 다릅니다.
Alex B

9
@ 알렉스 B 당신은 당신의 대답에 이중에 대해 언급하지 않았습니다. 부동 소수점 변수에 대한 답변을 업데이트 할 수 있습니까?
Cool_Coder

3
@ Cool_Coder : 부동 소수점은 물고기의 전체 추가 주전자이며 게시물 크기를 쉽게 두 배로 늘립니다.
중복 제거기

3
@Mooing Duck : "모든 버전의 C ++에는 256 개의 고유 한 값이 필요합니다 [서명 된 문자 유형에 대해]"아니오. 최신 C ++ 사양에서 수정 될 때까지는 사실이 아니 었습니다. 이전 사양에서는 부호있는 문자 유형에 숫자에 맵핑되지 않는 비트 패턴이있을 수 있으므로 256 개의 고유 값이 있어야한다는 요구 사항이 누락되었습니다. "부호없는 문자 유형의 경우 값 표현의 모든 가능한 비트 패턴은 숫자를 나타냅니다. 이러한 요구 사항은 다른 유형에는 적용되지 않습니다."
Adrian McCarthy가

241

32 비트 시스템의 경우 '사실상'표준은 ILP32입니다. intlong, 포인터는 모두 32 비트 수량입니다.

64 비트 시스템의 경우 기본 Unix '실제'표준은 LP64 long이며 포인터는 64 비트 ( int32 비트)입니다. - 윈도우 64 비트 표준은 LLP64이다 long long포인터는 64 비트이다 (그러나 longint32 비트이다).

한 번에 일부 Unix 시스템은 ILP64 조직을 사용했습니다.

이러한 사실상의 표준 중 어느 것도 C 표준 (ISO / IEC 9899 : 1999)에 의해 제정되지는 않지만 모든 표준에 의해 허용됩니다.

그리고, 정의, sizeof(char)1펄 구성 스크립트 테스트에도 불구하고,.

기계 (Crays)가 있었다하는 것으로 CHAR_BIT의미 그건 8. IIRC보다 훨씬 더이었다, sizeof(int)또한 1이었고, 때문에 모두 charint있었다 32 비트.


73
이론상 상황이 아니라 가장 중요한 경우에 실제로 상황이 어떤지에 대해 +1합니다. 32 비트를 int로 사용하려면 64 비트를 오래 사용하십시오. 기본 사용 size_t를 원하면 "평원"은 다양하기 때문에 오래 사용하지 마십시오. 대부분의 응용 프로그램에서 작동합니다.
Eloff

37
답변은 +1입니다. @Eloff : 반대로 ... 32 비트 사용을 원 [u]int32_t하거나 비슷한 경우, 64 비트 사용을 원한다면 [u]int64_t... 헤더가없는 경우 컴파일 타임 선택 중 하나를 사용하여 다운로드하거나 만드십시오. 크기를 확인하기위한 이러한 유형 또는 정적 어설 션 pubs.opengroup.org/onlinepubs/009695299/basedefs/stdint.h.html 정확한 크기가 그다지 중요하지 않고 적어도 그 정도만 신경 쓰는다면 현대의 일반적인 PC / 서버 플랫폼에 대한 조언이 필요합니다.
Tony Delroy 2011

8
예를 들어, CHAR_BIT가 8보다 오래된 구식 크레이 기계는 아닙니다. 예를 들어 DSP는 종종 CHAR_BIT가 16 또는 32입니다. (예 : 이것들 참조 )
nos

2
@nos : 링크 주셔서 감사합니다. 홀수 건 사건에 대해 최신의 최신 시스템을 식별하는 것이 매우 도움이됩니다. 호기심에서, 그 기계에 설정된 코드는 무엇입니까? 코드 세트가 UTF-16 인 경우 0xFFFF는 유효한 문자가 아니며 코드 세트가 ISO 8859-x 코드 세트 인 경우 0xFFFF는 유효한 문자가 아닙니다 (0x00에서 0xFF까지의 문자 코드가 유효 함). 아직 EOF를 감지하는 데 문제가 있음을 확신하지는 못하지만 확실히주의를 기울일 필요가 있으며 아마도 int get_char(FILE *fp, char *c)EOF 또는 0을 반환하고 설정 하는 함수를 작성하고 사용할 수 있습니다 *c.
Jonathan Leffler

2
@joelw : C11 에서는 "int"가 32 비트 이하인 플랫폼에서 uint32_t x=1,y=2;x-y이 4294967295 여야하고 "int"가 33 비트 이상인 플랫폼에서는 -1이어야합니다. 또한, x*y"int"가 32 비트 이하인 경우 x 및 y의 모든 값에 대해 모듈 식 산술을 사용하여 평가해야하고, 65 비트 이상인 경우 일반적인 산술을 수행해야하지만 큰 값으로 발생할 수있는 사항에 대한 요구 사항은 없습니다. "int"가 33-64 비트 인 경우 x 및 y
supercat

88

실제로는 그런 것이 없습니다. std::size_t현재 아키텍처에서 부호없는 고유 정수 크기를 나타내는 경우가 종종 있습니다 . 즉 16 비트, 32 비트 또는 64 비트이지만이 답변에 대한 의견에서 지적한 것처럼 항상 그런 것은 아닙니다.

다른 모든 내장 유형은 컴파일러에 따라 다릅니다. 최신 C ++ 표준의 현재 작업 초안에서 발췌 한 두 가지 발췌가 있습니다.

부호있는 char, short int, int, long int 및 long long int의 5 가지 표준 부호있는 정수 유형이 있습니다. 이 목록에서 각 유형은 목록에서 이전 유형보다 최소한 많은 스토리지를 제공합니다.

각 표준 부호있는 정수 유형에 대해 대응하는 (그러나 다른) 표준 부호없는 정수 유형이 있습니다 : 부호없는 char, 부호없는 short int, 부호없는 int, 부호없는 long int 및 부호없는 long long int 스토리지와 동일한 정렬 요구 사항이 있습니다.

원하는 경우 이러한 기본 유형의 크기를 정적으로 (컴파일 타임) 어설 션 할 수 있습니다. 가정의 크기가 변경되면 사람들에게 코드 이식에 대해 생각하도록 경고합니다.


7
좋은 소식. 필요한 또 다른 최소 비트 크기는 다음과 같은 최소 비트 크기입니다 (c89 / c99에 limits.h와 함께 문서화되고 c ++로 대체 됨) : char> = 8, short and int> = 16, long> = 32.
Johannes Schaub-litb

1
또한 8 비트 AVR 플랫폼에서 size_t는 8 비트가 아니라 16 비트가됩니다. 포인터 및 int 크기는 16 비트이기 때문입니다. 따라서 프로세서 고유 데이터 크기는 size_t와 관련이 없습니다.
로봇 버그

80

표준이 있습니다.

C90 표준은

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

C99 표준은

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

C99 사양은 다음과 같습니다 . 다양한 적분 유형의 크기에 대해 자세히 설명합니다.

다음은 Windows 플랫폼 용 int 유형 크기 (비트)입니다.

Type           C99 Minimum     Windows 32bit
char           8               8
short          16              16
int            16              32
long           32              32
long long      64              64

이식성이 염려되거나 유형의 이름이 크기를 반영하도록 <inttypes.h>하려면 다음 매크로를 사용할 수 있는 header 를 볼 수 있습니다.

int8_t
int16_t
int32_t
int64_t

int8_t8 비트, int16_t16 비트 등을 보장합니다.


8
사소한 nitpick : 표준 sizeof(long) < sizeof(long long)이 대칭과 반대로 어디에서 말하는가 sizeof(long) <= sizeof(long long)?
Jonathan Leffler

2
@JonathonLeffler-C99 참조 5.2.4.2.1-정수 유형의 크기. minsizeof (int) == 16- 비트, minsizeof (long) == 32 비트, minsizeof (long long) == 64 비트. 그래서 maxsizeof (type)이 지정되지 않았으므로 <=에 맞다고 생각합니다.
Jesse Chisholm

비슷하게 sizeof (float) <= sizeof (double) <= sizeof (long double). C99 7.12 단락 2에 따르면
Jesse Chisholm

38

고정 크기 유형이 필요한 경우 stdint.h에 정의 된 uint32_t (부호없는 정수 32 비트)와 같은 유형을 사용하십시오 . 그것들은 C99 에 지정되어 있습니다.


10
지정되었지만 필수는 아닙니다.
드림 락스

2
@dreamlax 어떤 플랫폼에 포함되지 않습니까?
레위 모리슨

3
@LeviMorrison : 필요한 양식이없는 플랫폼. 예를 들어을 가진 플랫폼 CHAR_BIT == 16은을 갖지 않습니다 int8_t. 모든 플랫폼은 2의 보수가 필요가 없습니다 사용하지 않는 모든 (2의 보수가 표준에서 요구하는대로) 중입니다.
DevSolar

36

업데이트 : C ++ 11은 공식적으로 TR1의 유형을 표준으로 가져 왔습니다.

  • long long int
  • 부호없는 long long int

그리고 "크기"유형에서 <cstdint>

  • int8_t
  • int16_t
  • int32_t
  • int64_t
  • (서명되지 않은 상대방).

게다가 당신은 얻을 :

  • int_least8_t
  • int_least16_t
  • int_least32_t
  • int_least64_t
  • 또한 서명되지 않은 상대방도 있습니다.

이 타입들은 최소한 지정된 비트 수를 가진 가장 작은 정수 타입을 나타냅니다. 마찬가지로 최소한 지정된 비트 수를 가진 "가장 빠른"정수 유형이 있습니다.

  • int_fast8_t
  • int_fast16_t
  • int_fast32_t
  • int_fast64_t
  • 부호없는 버전도 있습니다.

"빠른"의 의미는 무엇이든 구현에 달려 있습니다. 모든 목적을 위해 가장 빠를 필요는 없습니다.


이것은 현재 C ++ 11 표준의 일부입니다.
자안

2
"빠른"은 하드웨어 아키텍처에 맞춘 것을 의미합니다. 레지스터가 16 비트이면 int_fast8_t는 16 비트 값입니다. 레지스터가 32 비트 인 경우 int_fast8_t 및 int_fast16_t는 모두 32 비트 값입니다. C99 섹션 7.18.1.3 단락 2를 참조하십시오.
Jesse Chisholm

19

C ++ 표준 이처럼 말한다 :

3.9.1, §2 :

"signed char", "short int", "int", "long int"및 "long long int"의 5 가지 부호있는 정수 유형이 있습니다. 이 목록에서 각 유형은 목록에서 이전 유형보다 최소한 많은 스토리지를 제공합니다. 일반 정수는 실행 환경의 아키텍처 (44)에 의해 제안 된 자연스러운 크기를 가지고 있습니다. 다른 부호있는 정수 유형은 특별한 요구를 충족시키기 위해 제공됩니다.

(44) 즉 , 헤더에 정의 된대로 INT_MIN 및 INT_MAX 범위의 값을 포함하기에 충분히 큽니다 <climits> .

결론 : 작업중인 아키텍처에 따라 다릅니다. 다른 가정은 거짓입니다.


12

아니요, 유형 크기에 대한 표준은 없습니다. 표준은 다음을 요구합니다.

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

고정 된 크기의 변수를 원하는 경우 가장 좋은 방법은 다음과 같은 매크로를 사용하는 것입니다.

#ifdef SYSTEM_X
  #define WORD int
#else
  #define WORD long int
#endif

그런 다음 WORD를 사용하여 변수를 정의 할 수 있습니다. 내가 이것을 좋아하지는 않지만 가장 휴대하기 쉬운 방법입니다.


4
문제는 WORD가 프로그램 주위에 고정 된 크기에 의존하지 않는 영역으로 확산된다는 것입니다 (일부 윈도우 코드를보십시오). 16 비트에서 32 비트 시스템으로 옮길 때 알게 된 것처럼 WORD가 해결하려는 것과 동일한 문제가 발생합니다.
lilburne

@liburne 물론 파일을 읽고 쓸 때와 같이 고정 된 크기 변수가 필요한 경우에만 WORD를 사용해야합니다. 코드 조각이 실제로 고정 된 크기에 의존하지 않으면 일반적인 "int"변수를 사용해야합니다.
Emiliano 2019

3
휴대용 크기를 얻기 위해 할 수있는 최선의 방법은 다음과 같습니다.#include <boost/cstdint.hpp>
kizzx2

11

자체 "표준"을 만들 수 있도록 유형에 대한 동의어를 정의 할 수 있습니다.

sizeof (int) == 4 인 머신에서 다음을 정의 할 수 있습니다.

typedef int int32;

int32 i;
int32 j;
...

따라서 실제로 long int의 크기가 4 인 다른 컴퓨터로 코드를 전송하면 int의 단일 발생을 재정의 할 수 있습니다.

typedef long int int32;

int32 i;
int32 j;
...

1
표준 헤더 <stdint.h>(C99 이상 및 C 라이브러리의 C99 버전을 채택한 C ++ 표준)는 필요하지 않습니다 .
Keith Thompson

8

부동 소수점 숫자 에는 표준 (IEEE754)이 있습니다. . float는 32 비트이고 double은 64입니다. 이것은 C ++ 표준이 아닌 하드웨어 표준이므로 컴파일러는 이론적으로 float 및 double을 다른 크기로 정의 할 수 있지만 실제로는 ' ve 다른 것을 사용한 아키텍처는 본 적이 없습니다.


2
그러나 C ++에서는 IEEE 754 (일명 IEC 559) 준수가 선택 사항입니다 (아마도 C이지만 확실하지는 않습니다). std :: numeric_limits :: is_iec559를 참조하십시오.
Drew Hall

1
그럼 당신은 TMS320C28xx DSP를위한 TI의 컴파일러 보지 못했다 double과 같은 크기가 float(와 int같은을 char모두 16 비트입니다). 그러나 그들은 64 비트가 long double있습니다.
starblue

7

표준이 있으며 다양한 표준 문서 (ISO, ANSI 및 기타)에 지정되어 있습니다.

Wikipedia에는 ​​다양한 유형과 이들이 저장할 수있는 최대 값을 설명하는 훌륭한 페이지가 있습니다 : Integer in Computer Science.

그러나 표준 C ++ 컴파일러를 사용하더라도 다음 코드 스 니펫을 사용하면 비교적 쉽게 찾을 수 있습니다.

#include <iostream>
#include <limits>


int main() {
    // Change the template parameter to the various different types.
    std::cout << std::numeric_limits<int>::max() << std::endl;
}

std :: numeric_limits에 대한 설명서 는 Roguewave 에서 찾을 수 있습니다. . 여기에는 다양한 한계를 찾기 위해 호출 할 수있는 다양한 명령이 포함되어 있습니다. std :: streamsize와 같이 크기를 전달하는 임의의 유형과 함께 사용할 수 있습니다.

요한의 대답에는 확실하게 설명되어 있으므로 가장 좋은 설명이 들어 있습니다. 어떤 플랫폼을 사용하든 각 유형에 반드시 포함해야하는 비트 수에 대해 자세히 설명하는 또 다른 좋은 페이지가 있습니다. int types , 표준에 정의되어 있습니다.

이게 도움이 되길 바란다!



7

당신이 사용할 수있는:

cout << "size of datatype = " << sizeof(datatype) << endl;

datatype = int, long int등 당신은 당신이 입력 중 데이터 타입의 크기를 볼 수 있습니다.


7

다른 아키텍처와 다른 컴파일러에 대한 내장 유형에 관해서는 아키텍처에서 컴파일러와 함께 다음 코드를 실행하여 출력 내용을 확인하십시오. 아래는 내 우분투 13.04를 보여줍니다. (Raring Ringtail) 64 비트 g ++ 4.7.3 출력을 . 또한 아래에 답변 된 내용을 참고하십시오. 출력이 그렇게 주문 된 이유는 다음과 같습니다.

"서명 된 char, short int, int, long int 및 long long int의 5 가지 표준 부호있는 정수 유형이 있습니다.이 목록에서 각 유형은 목록에서 앞의 것보다 많은 스토리지를 제공합니다."

#include <iostream>

int main ( int argc, char * argv[] )
{
  std::cout<< "size of char: " << sizeof (char) << std::endl;
  std::cout<< "size of short: " << sizeof (short) << std::endl;
  std::cout<< "size of int: " << sizeof (int) << std::endl;
  std::cout<< "size of long: " << sizeof (long) << std::endl;
  std::cout<< "size of long long: " << sizeof (long long) << std::endl;

  std::cout<< "size of float: " << sizeof (float) << std::endl;
  std::cout<< "size of double: " << sizeof (double) << std::endl;

  std::cout<< "size of pointer: " << sizeof (int *) << std::endl;
}


size of char: 1
size of short: 2
size of int: 4
size of long: 8
size of long long: 8
size of float: 4
size of double: 8
size of pointer: 8

sizeof(char)포함하지 않아야합니다.
Ven

3

언급 한 바와 같이 크기는 현재 아키텍처를 반영해야합니다. limits.h현재 컴파일러가 작업을 처리하는 방법을 보려면 피크를 사용할 수 있습니다 .


고맙지 만, 64 비트와 같은 나 자신이없는 achitectures의 크기를 알고 싶습니다. 이 튜토리얼은 32 비트 아키텍처에 대해서만 이야기합니다 ...
Jérôme

2

다른 사람들이 대답했듯이, "표준"은 대부분의 세부 사항을 "구현 정의"로 남겨두고 "char"유형이 "char_bis"폭이 넓고 "char <= short <= int <= long < = long long "(float 및 double은 IEEE 부동 소수점 표준과 거의 일치하며 long double은 일반적으로 double과 동일하지만 현재 구현에서는 더 클 수 있음)

매우 구체적이고 정확한 값을 갖지 않는 이유 중 하나는 C / C ++와 같은 언어가 "char"단어 크기가 4 비트 일 수있는 컴퓨터 시스템을 포함하여 많은 하드웨어 플랫폼에 이식 가능하도록 설계 되었기 때문입니다. 또는 7 비트 또는 일반 가정용 컴퓨터 사용자에게 노출되는 "8 / 16 / 32 // 64 비트"컴퓨터 이외의 다른 값일 수도 있습니다. (여기서 워드 크기는 시스템이 정상적으로 작동하는 비트 수를 의미합니다. 또한 가정용 컴퓨터 사용자가 기대할 수있는 8 비트는 아닙니다.)

특정 비트 수의 객체 (정수 값을 나타내는 일련의 비트 의미)가 실제로 필요한 경우 대부분의 컴파일러에는이를 지정하는 방법이 있습니다. 그러나 일반적으로 ame 회사가 만든 컴파일러간에 다른 플랫폼 용으로도 이식성이 없습니다. 일부 표준 및 관행 (특히 limits.h 등)은 대부분의 컴파일러가 특정 범위의 값에 대해 가장 적합한 유형을 결정하는 데 지원하지만 사용되는 비트 수는 충분하지 않을 정도로 일반적입니다. (즉, 0에서 127 사이의 값을 보유해야한다는 것을 알고 있다면, 컴파일러는 원하는 전체 범위를 보유하기에 충분히 큰 8 비트의 "int8"유형을 지원하지만 "int7"유형으로 7 비트와 정확히 일치합니다.)

참고 : 많은 Un * x 소스 패키지는 "./configure"스크립트를 사용하여 컴파일러 / 시스템 기능을 검사하고 적합한 Makefile 및 config.h를 출력합니다. 이러한 스크립트 중 일부를 검사하여 작동 방식과 이들이 컴파일러 / 시스템 기능을 조사하고 그 리드를 따르는 방법을 확인할 수 있습니다.


1

순수한 C ++ 솔루션에 관심이 있다면 템플릿과 C ++ 표준 코드 만 사용하여 비트 크기에 따라 컴파일 타임에 유형을 정의했습니다. 이 솔루션을 사용하면 컴파일러간에 솔루션을 이식 할 수 있습니다.

뒤에 아이디어는 매우 간단합니다 : char, int, short, long, long long (서명 및 부호없는 버전) 유형을 포함하는 목록을 만들고 목록을 스캔하고 numeric_limits 템플릿을 사용하여 주어진 크기의 유형을 선택하십시오.

이 헤더를 포함하면 8 가지 유형의 stdtype :: int8, stdtype :: int16, stdtype :: int32, stdtype :: int64, stdtype :: uint8, stdtype :: uint16, stdtype :: uint32, stdtype :: uint64입니다.

일부 유형을 나타낼 수없는 경우 해당 헤더에 선언 된 stdtype :: null_type으로 평가됩니다.

아래 코드는 보증없이 제공되며 두 번 확인하십시오.
나는 METAPROGRAMMING TOO에 새로운 소식입니다.이 코드를 수정하고 수정하십시오.
DevC ++로 테스트되었으므로 (3.5 gcc 버전)

#include <limits>

namespace stdtype
{
    using namespace std;


    /*
     * THIS IS THE CLASS USED TO SEMANTICALLY SPECIFY A NULL TYPE.
     * YOU CAN USE WHATEVER YOU WANT AND EVEN DRIVE A COMPILE ERROR IF IT IS 
     * DECLARED/USED.
     *
     * PLEASE NOTE that C++ std define sizeof of an empty class to be 1.
     */
    class null_type{};

    /*
     *  Template for creating lists of types
     *
     *  T is type to hold
     *  S is the next type_list<T,S> type
     *
     *  Example:
     *   Creating a list with type int and char: 
     *      typedef type_list<int, type_list<char> > test;
     *      test::value         //int
     *      test::next::value   //char
     */
    template <typename T, typename S> struct type_list
    {
        typedef T value;
        typedef S next;         

    };




    /*
     * Declaration of template struct for selecting a type from the list
     */
    template <typename list, int b, int ctl> struct select_type;


    /*
     * Find a type with specified "b" bit in list "list"
     *
     * 
     */
    template <typename list, int b> struct find_type
    {   
        private:
            //Handy name for the type at the head of the list
            typedef typename list::value cur_type;

            //Number of bits of the type at the head
            //CHANGE THIS (compile time) exp TO USE ANOTHER TYPE LEN COMPUTING
            enum {cur_type_bits = numeric_limits<cur_type>::digits};

        public:
            //Select the type at the head if b == cur_type_bits else
            //select_type call find_type with list::next
            typedef  typename select_type<list, b, cur_type_bits>::type type;
    };

    /*
     * This is the specialization for empty list, return the null_type
     * OVVERRIDE this struct to ADD CUSTOM BEHAVIOR for the TYPE NOT FOUND case
     * (ie search for type with 17 bits on common archs)
     */
    template <int b> struct find_type<null_type, b>
    {   
        typedef null_type type;

    };


    /*
     * Primary template for selecting the type at the head of the list if
     * it matches the requested bits (b == ctl)
     *
     * If b == ctl the partial specified templated is evaluated so here we have
     * b != ctl. We call find_type on the next element of the list
     */
    template <typename list, int b, int ctl> struct select_type
    {   
            typedef  typename find_type<typename list::next, b>::type type; 
    };

    /*
     * This partial specified templated is used to select top type of a list
     * it is called by find_type with the list of value (consumed at each call)
     * the bits requested (b) and the current type (top type) length in bits
     *
     * We specialice the b == ctl case
     */
    template <typename list, int b> struct select_type<list, b, b>
    {
            typedef typename list::value type;
    };


    /*
     * These are the types list, to avoid possible ambiguity (some weird archs)
     * we kept signed and unsigned separated
     */

    #define UNSIGNED_TYPES type_list<unsigned char,         \
        type_list<unsigned short,                           \
        type_list<unsigned int,                             \
        type_list<unsigned long,                            \
        type_list<unsigned long long, null_type> > > > >

    #define SIGNED_TYPES type_list<signed char,         \
        type_list<signed short,                         \
        type_list<signed int,                           \
        type_list<signed long,                          \
        type_list<signed long long, null_type> > > > >



    /*
     * These are acutally typedef used in programs.
     * 
     * Nomenclature is [u]intN where u if present means unsigned, N is the 
     * number of bits in the integer
     *
     * find_type is used simply by giving first a type_list then the number of 
     * bits to search for.
     *
     * NB. Each type in the type list must had specified the template 
     * numeric_limits as it is used to compute the type len in (binary) digit.
     */
    typedef find_type<UNSIGNED_TYPES, 8>::type  uint8;
    typedef find_type<UNSIGNED_TYPES, 16>::type uint16;
    typedef find_type<UNSIGNED_TYPES, 32>::type uint32;
    typedef find_type<UNSIGNED_TYPES, 64>::type uint64;

    typedef find_type<SIGNED_TYPES, 7>::type    int8;
    typedef find_type<SIGNED_TYPES, 15>::type   int16;
    typedef find_type<SIGNED_TYPES, 31>::type   int32;
    typedef find_type<SIGNED_TYPES, 63>::type   int64;

}

0
unsigned char bits = sizeof(X) << 3;

여기서 XA는 char, int, long등 당신의 크기를 줄 것이다 X비트를.


1
char은 항상 8 비트는 아니므로 8 비트가 아닌 char 인 아키텍처에서는 표현식이 작동하지 않습니다 . 만 sizeof(type)*CHAR_BIT보유
phuclv

CHAR_BIT8 비트로 보장 되더라도 , 또는 << 3을 쓰는 난독 화 된 방법 일뿐 입니다. * 8* CHAR_BIT
Keith Thompson

0

Alex B에서 C ++ 표준은 정수 유형의 크기를 바이트 단위로 지정하지 않지만 보유 할 수있는 최소 범위를 지정합니다. 필요한 범위에서 최소 크기를 비트 단위로 추론 할 수 있습니다. 최소 바이트 크기를 바이트 및 바이트의 비트 수를 정의하는 CHAR_BIT 매크로의 값에서 유추 할 수 있습니다 (가장 모호한 플랫폼을 제외하고는 8이고 8보다 작을 수 없음).

char에 대한 추가 제약 조건은 크기가 항상 1 바이트 또는 CHAR_BIT 비트 (따라서 이름)라는 것입니다.

표준 (22 페이지)에 필요한 최소 범위는 다음과 같습니다.

및 MSDN의 데이터 유형 범위 :

부호가있는 char : -127 ~ 127 (참고 : -128 ~ 127이 아니라 1의 보완 플랫폼을 수용 함) 서명되지 않은 char : 0 ~ 255 "일반"char : -127 ~ 127 또는 0 ~ 255 (기본 문자 서명에 따라 다름) short : -32767 ~ 32767 unsigned short : 0 ~ 65535 signed int : -32767 ~ 32767 unsigned int : 0 ~ 65535 signed long : -2147483647 ~ 2147483647 unsigned long : 0 ~ 4294967295 long long : -9223372036854775807 ~ 9223372036854775807 unsigned long long : 0 ~ 18446744073709551615 C ++ (또는 C) 구현은 바이트의 크기를 sizeof (type) 단위의 값으로 정의 할 수 있습니다.

sizeof (type) * CHAR_BIT 표현식은 필요한 범위를 포함하기에 충분한 비트 수로 평가되며 유형 순서는 여전히 유효합니다 (예 : sizeof (int) <= sizeof (long)). 실제 구현 별 범위는 C의 헤더 또는 C ++ (또는 헤더의 템플릿 std :: numeric_limits)에서 찾을 수 있습니다.

예를 들어, 다음은 int의 최대 범위를 찾는 방법입니다.

씨:

#include <limits.h>
const int min_int = INT_MIN;
const int max_int = INT_MAX;

C ++ :

#include <limits>
const int min_int = std::numeric_limits<int>::min();
const int max_int = std::numeric_limits<int>::max();

그러나 이것은 맞습니다. char : 1 byte short : 2 bytes int : 4 bytes long : 4 bytes float : 4 bytes double : 8 bytes

32 비트 아키텍처는 여전히 기본적이고 가장 많이 사용되기 때문에 메모리를 사용할 수 없었던 32 비트 이전부터이 표준 크기를 유지했으며 이전 버전과의 호환성 및 표준화는 동일하게 유지되었습니다. 64 비트 시스템조차도 이것을 사용하는 경향이 있으며 확장 / 수정이 있습니다. 자세한 내용은 이것을 참조하십시오.

http://en.cppreference.com/w/cpp/language/types


0

여기에있는 다른 모든 대답은 정수 유형에 거의 독점적으로 초점을 맞추고 질문자는 부동 소수점에 대해서도 물었습니다.

C ++ 표준에 필요한 것은 아니지만 요즘 가장 일반적인 플랫폼의 컴파일러는 일반적으로 부동 소수점 숫자에 대한 IEEE754 표준을 따릅니다. 이 표준은 4 가지 유형의 이진 부동 소수점 (및 C ++ 컴파일러에서 지원 한 적이없는 일부 BCD 형식)을 지정합니다.

  • 반정도 (2 진 16)-11 비트 유효, 지수 범위 -14 ~ 15
  • 단정도 (2 진 32)-24 비트 유효, 지수 범위 -126 ~ 127
  • 배정도 (2 진 64)-53 비트 유효, 지수 범위 -1022 ~ 1023
  • 4 중 정밀도 (2 진 128)-113 비트 유효 및 지수 범위 -16382 ~ 16383

그렇다면 어떻게 C ++ 유형에 매핑됩니까? 일반적으로 float단 정밀도를 사용합니다. 따라서 sizeof(float) = 4. 그런 다음 double배정 밀도를 사용합니다 (이름의 출처라고 생각합니다 double).long double 두 배 또는 배 정밀도 될 수있다 (내 시스템에 그것의 배를하지만, 32 비트 시스템에 두 번 할 수있다). 나는 반 정밀도 부동 소수점을 제공하는 컴파일러를 모른다.

요약하면 다음과 같습니다.

  • sizeof(float) = 4
  • sizeof(double) = 8
  • sizeof(long double) = 8 또는 16

Jeff가 왜 필요한 것보다 많은 바이트를 사용하는지 궁금해하는 부분 으로이 질문에 도착한 것이 재미 있습니다.
Aniruddha Varma


-2

OpenGL , Qt 등과 같은 라이브러리에서 제공하는 변수를 사용할 수 있습니다 .

예를 들어, Qt qint8 (Qt가 지원하는 모든 플랫폼에서 8 비트로 보장됨), qint16, qint32, qint64, quint8, quint16, quint32, quint64 등을 제공합니다.


1
질문에 대답하지 않습니다
EvilTeach

-8

64 비트 시스템에서 :

int: 4
long: 8
long long: 8
void*: 8
size_t: 8

2
일부 64 비트 시스템 int에서는 8 바이트이지만 다른 시스템은 보장되지 않습니다. char8 비트 여야 한다는 말은 없습니다 . sizeof(void*)==464 비트이지만 가질 수 있습니다.
skyking

-10

크기에 따라 4 가지 유형의 정수가 있습니다.

  • 짧은 정수 : 2 바이트
  • 긴 정수 : 4 바이트
  • long long 정수 : 8 바이트
  • 정수 : 컴파일러에 따라 다릅니다 (16 비트, 32 비트 또는 64 비트)

11
False, 그들은 모두 다른 답변 중 하나에 설명 된 최소 범위로 아키텍처와 관련이 있습니다. 아무것도 가지고 구현 정지하지 short, int그리고 long모든 32 개 비트 정수.
Matteo Italia

유형에 올바른 이름을 사용하지 않았습니다. 이름은 int"정수"라는 단어가 아닌 키워드를 사용합니다 .
키이스 톰슨
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.