Am'm în căutarea pentru informații detaliate cu privire la dimensiunea de bază C++ tipuri. Știu că depinde de arhitectura (16 biți, 32 biți, 64 de biți) și compilator.
Dar există standarde pentru C++?
Am'm folosind Visual Studio 2008 pe o arhitectură pe 32 de biți. Aici este ceea ce am primit:
char : 1 byte
short : 2 bytes
int : 4 bytes
long : 4 bytes
float : 4 bytes
double: 8 bytes
Am încercat să găsesc, fără prea mult succes, informații fiabile care să ateste dimensiunile de char
, scurt
, int
, "lung", "dublu", "float" (și alte tipuri de am't cred că a) sub diferite arhitecturi și compilatoare.
C++ standard nu specifică dimensiunea integrantă tipuri în bytes, dar se specifică minimă variază acestea trebuie să fie în măsură să dețină. Puteți deduce dimensiunea minimă în biți din intervalul necesar. Puteți deduce dimensiunea minimă în octeți de la care și valoarea CHAR_BIT
macro care definește numărul de biți într-un octet. În toate, dar cele mai obscure platforme it's 8, și se poate't fi mai mică de 8. Ca's, deoarece acesta trebuie să fie suficient de mare pentru a organiza "opt-bit cod unități de Unicode UTF-8
formă de codificare."
O constrângere suplimentară pentru char
este că dimensiunea sa este întotdeauna de 1 octet, sau CHAR_BIT
biți (de unde și numele). Acest lucru este menționat în mod explicit în standard.
C standard este o normative de referință pentru C++ standard, astfel încât, chiar dacă nu't de stat aceste cerințe în mod explicit, C++ necesită minim de intervale cerute de standard C (pagina 22), care sunt aceleași ca și cele de Tip de Date Variază de la MSDN:
semnat char
: de la -127 până la 127 (notă, nu -128 la 127; aceasta adăpostește 1's-complement și semn și magnitudine platforme)unsigned char
: de la 0 la 255char
: același interval ca semnat char " sau " unsigned char
, de punere în aplicare-definitsemnat de scurt
: -32767 la 32767unsigned short
: 0 la 65535semnat int
: -32767 la 32767unsigned int
: 0 la 65535unsigned long
: 0 si 4294967295unsigned long long
: 0 a 18446744073709551615Un C++ (sau C) punerea în aplicare poate defini dimensiunea de un tip în octeți sizeof(tip)
pentru orice valoare, atâta timp cât
Pune totul împreună, ne sunt garantate că:
char
, semnat char și unsigned char
sunt cel puțin 8 bițisemnat scurtă
, nesemnate scurtă
, semnat int " și " unsigned int
sunt cel puțin 16 bițisemnat lung " și " unsigned long
sunt cel puțin 32 de bițisemnat de mult timp " și " unsigned long long
sunt cel puțin 64 de bițiNici o garanție este de făcut cu privire la dimensiunea de "float" sau "dubla" cu excepția faptului că "dublu" oferă cel puțin la fel de mult precizie ca "float".
Punerea în aplicare efectivă-game specifice pot fi găsite în <limitele.h>
header in C, sau <climits>
in C++ (sau chiar mai bine, templated `std::numeric_limits " în "
De exemplu, acest lucru este modul în care va găsi intervalul maxim pentru int
:
C:
#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();
Pentru sisteme pe 32 de biți, la 'de facto' standard este ILP32 — care este, int
, timp
si indicatorul sunt toate 32-bit cantități.
Pentru sistemele pe 64 de biți, primar Unix 'de facto' standard este LP64 — "lung" si indicatorul sunt pe 64-bit (dar int
este de 32-bit). Windows 64-bit standard este LLP64 — lung
și pointer sunt pe 64-bit (dar lung
și int
sunt ambele pe 32 de biți).
La un moment dat, unele sisteme Unix folosit un ILP64 organizație.
Nici unul dintre aceste standarde de facto este legiferat de C standard (ISO/IEC 9899:1999), dar toate sunt permise de acesta.
Și, prin definiție, sizeof(char)
este 1
, în pofida încercării în Perl scriptul de configurare.
Rețineți că erau mașini (Crays) unde CHAR_BITa fost mult mai mare decât 8. Asta a însemnat, IIRC, care
sizeof(int)a fost, de asemenea, 1, pentru că ambele
charși
int` a fost de 32-bit.
În practică, există mai's nici un astfel de lucru. De multe ori vă puteți aștepta std::size_t
pentru a reprezenta nesemnate nativ dimensiune număr întreg pe actuala arhitectură. adică 16-bit, 32-bit sau 64-bit, dar nu't întotdeauna cazul, astfel cum a subliniat în comentariile la acest răspuns.
Cât de departe toate celelalte built-in tipuri merge, este într-adevăr depinde de compilator. Aici's două fragmente preluate din actualul proiect de lucru de cele mai recente standard C++:
Există cinci standard întreg semnat tipuri : a semnat char, short int, int, long int și long long int. În această listă, fiecare tip oferă cel puțin la fel de mult de stocare ca și cele precedente, în listă.
Pentru fiecare standard întreg semnat tipuri, există o corespunzătoare (dar diferite) standard întreg fără semn tip: unsigned char, unsigned short int, unsigned int, unsigned long int și unsigned long long int, fiecare dintre care ocupă aceeași cantitate de depozitare și are aceleași cerințe de aliniere.
Dacă doriți să puteți static (compile-time) afirma sizeof aceste tipuri fundamentale. Acesta vă va avertiza pe oameni să gândească despre portare codul dacă sizeof ipoteze schimba.
Nu este standard.
C90 standard impune ca
sizeof(short) <= sizeof(int) <= sizeof(long)
C99 standard impune ca
sizeof(short) <= sizeof(int) <= sizeof(long) <= sizeof(long long)
Aici este C99 caietul de sarcini. Pagina 22 detalii dimensiuni diferite integrantă tipuri.
Aici este int tip dimensiuni (biți) pentru Windows platforme:
Type C99 Minimum Windows 32bit
char 8 8
short 16 16
int 16 32
long 32 32
long long 64 64
Dacă sunteți îngrijorat cu portabilitatea, sau vrei să știi numele de tip reflectă dimensiunea, poti sa te uiti la antet <inttypes.h>
, în cazul în care următoarele macro-uri sunt disponibile:
int8_t
int16_t
int32_t
int64_t
int8_t
este garantat să fie de 8 bits, și int16_t
este garantat să fie de 16 biți, etc.
Actualizat: C++11-a adus tipurile de TR1 oficial în standard:
Și "dimensiuni" tipuri de <cstdint>
Plus veți obține:
Aceste tipuri reprezintă cel mai mic număr întreg tipuri cu cel puțin numărul specificat de biți. De asemenea, există "mai" întreg tipuri cu cel puțin numărul specificat de biți:
Ce "rapid" înseamnă, dacă ceva, este de până la punerea în aplicare. Acesta nu trebuie să fie cel mai rapid pentru toate scopurile ori.
C++ Standard spune așa:
3.9.1, §2:
Există cinci întreg semnat tipuri : "semnat char", "short int", "int", "long int", și "long long int". În această listă, fiecare tip oferă cel puțin cât de mult de stocare ca și cele precedente în listă. Simplu au int mărime naturală a sugerat de către arhitectura de executie mediu (44); alte semnat întreg tipuri sunt oferite pentru a satisface nevoi speciale.
(44), care este, suficient de mare pentru a conține orice valoare în intervalul de INT_MIN și INT_MAX, astfel cum sunt definite în header
<climits>
.
Concluzia: depinde de care arhitectura te're de lucru pe. Orice altă ipoteză este falsă.
Nu, nu există nici un standard pentru dimensiuni de tip. Standard necesită doar asta:
sizeof(short int) <= sizeof(int) <= sizeof(long int)
Cel mai bun lucru care le puteți face dacă doriți variabile de dimensiuni fixe este de a utiliza macro-uri de genul asta:
#ifdef SYSTEM_X
#define WORD int
#else
#define WORD long int
#endif
Apoi, aveți posibilitatea să utilizați WORD pentru a defini variabile. L's nu că-mi place acest lucru, dar l's a cel mai portabil cale.
Ne este permis pentru a defini un sinonim pentru tipul astfel încât să putem crea propriile noastre "standard".
Pe o mașină în care sizeof(int) == 4, vom putea defini:
typedef int int32;
int32 i;
int32 j;
...
Așa că atunci când vom transfera codul pentru o altă mașină în cazul în care, de fapt, dimensiunea de long int este de 4, putem redefini singur eveniment de int.
typedef long int int32;
int32 i;
int32 j;
...
Pentru numere în virgulă mobilă nu există un standard (IEEE754): flotoare sunt pe 32 de biți și duble sunt 64. Acesta este un standard de hardware, nu C++ standard, astfel încât compilatoare ar putea, teoretic, să definească float și double la alte dimensiuni, dar, în practică, am'n-am văzut-o arhitectură care a folosit ceva diferit.
Tabelul N1 la articolul "uitate problemele de 64-bit programe de dezvoltare"
Nu există un standard și este specificată în standarde diferite documente (ISO, ANSI și altele).
Wikipedia are o mare pagină care explică diferite tipuri și max se pot stoca: Număr întreg în informatică.
Cu toate acestea, chiar și cu un standard de C++ compiler puteți afla relativ ușor folosind următorul fragment de cod:
#include <iostream>
#include <limits>
int main() {
// Change the template parameter to the various different types.
std::cout << std::numeric_limits<int>::max() << std::endl;
}
Documentația pentru std::numeric_limits pot fi găsite la Roguewave. Acesta include o serie de alte comenzi puteți suna pentru a afla diverse limite. Acest lucru poate fi folosit cu orice arbitrar tip care transmite dimensiune, de exemplu std::streamsize.
John's răspunsul conține cea mai bună descriere, așa cum acestea sunt garantate de a organiza. Indiferent de ceea ce platforma esti pe, există o altă pagină de bun, care merge în mai multe detalii cu privire la cât de mulți biți fiecare tip TREBUIE să conțină: int tipuri, care sunt definite în standard.
Sper că acest lucru vă ajută!
Când vine vorba de construit în tipuri de arhitecturi diferite și diferite compilatoare doar rula codul de mai jos pe arhitectura cu compilator pentru a vedea ce va fi afișat. De mai jos arată mea Ubuntu 13.04 (Raring Ringtail) pe 64 de biți g++4.7.3 de ieșire. De asemenea, vă rugăm să rețineți ceea ce s-a răspuns de mai jos, care este motivul pentru care ieșirea este dispus astfel:
"sunt cinci standard întreg semnat tipuri: a semnat char, short int, int, long int și long long int. În această listă, fiecare tip oferă cel puțin la fel de mult de stocare ca și cele precedente-l în lista."
#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
Ca altii au răspuns, "standarde" toate lasa de cele mai multe detalii ca "punerea în aplicare definit" și singurul stat care tip "char" este la leat "char_bis" larg, și că "char <= scurt <= int <= timp <= de mult timp" (float si double sunt destul de mult în concordanță cu IEEE plutitoare punct de standarde, și long double este de obicei același ca dublu ... dar poate fi mai mare, pe mai multe implementări curente).
O parte din motivele pentru care nu au foarte specific și exact valorile pentru limbi, cum ar fi C/C++ a fost conceput pentru a fi portabil la un număr mare de platforme hardware--Inclusiv sistemele informatice în care "char" cuvânt-dimensiunea poate fi de 4 biți sau 7-biți, sau chiar unele de valoare, altele decât "8-/16-/32-/64-pic" calculatoare mediu utilizator de computer acasă este expus. (Word-size aici sensul câți biți sistem în mod normal funcționează pe din's nu întotdeauna 8-biți ca și acasă utilizatorilor de calculatoare care se poate aștepta.)
Dacă aveți într-adevăr nevoie de un obiect (în sens de o serie de biți care reprezintă o valoare integrală) de un anumit număr de biți, cele mai multe compilatoare aveți o metodă de a preciza că; Dar's, în general, nu portabil, chiar și între compilatoare facute de ame companie, dar pentru diferite platforme. Unele standarde și practici (mai ales limitele.h și) ca sunt destul de comune pe care cele mai multe compilatoare va avea suport pentru stabilirea de la best-fit tip pentru un anumit interval de valori, dar nu numărul de biți folosit. (Asta este, dacă știți că aveți nevoie să dețină valori între 0 și 127, puteți determina că compiler acceptă o "int8" tip de 8-biți, care va fi destul de mare pentru a deține o gamă completă de dorit, dar nu ceva ca un "int7" tip care ar fi o potrivire exactă pentru 7-bits.)
Notă: Multe Onu*x sursa pachete de folosit "./configurare" script care va sonda compiler/sistem de's capacitățile și de ieșire adecvat Makefile și config.h. S-ar putea examina unele dintre aceste script-uri pentru a vedea cum funcționează și modul în care acestea sonda comiler/sistem de capacități, și să urmeze exemplul lor.
Dacă sunteți interesat într-o pură C++ soluție, am făcut uz de șabloane și doar C++ cod standard pentru a defini tipuri la compilare, pe baza lor de biți mărime. Acest lucru face soluția portabilă peste compilatoare.
Ideea din spatele este foarte simplu: a Crea o listă cu tipurile char, int, scurt, lung, lung, lung (semnate și nesemnate versiuni) și scanați lista și prin utilizarea de numeric_limits șablon selectați tipul cu anumite dimensiuni.
Inclusiv acest antet ai 8 tip stdtype::int8, stdtype::int16, stdtype::int32, stdtype::int64, stdtype::uint8, stdtype::uint16, stdtype::uint32, stdtype::uint64.
Dacă un tip nu pot fi reprezentate acesta va fi evaluat pentru a stdtype::null_type declarat, de asemenea, în antet.
CODUL DE MAI JOS ESTE DAT, FĂRĂ GARANȚIE, VĂ RUGĂM SĂ VERIFICAȚI-L. AM'M NOI DE LA METAPROGRAMARE DE ASEMENEA, SIMȚIȚI-VĂ LIBER PENTRU A EDITA ȘI DE A CORECTA ACEST COD. Testat cu DevC++ (deci o versiune gcc aproximativ 3,5)
#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;
}
Am observat că toate răspunsurile aici s-au concentrat aproape exclusiv pe integrantă tipuri, în timp ce petentul a cerut, de asemenea, despre plutitoare-puncte.
Eu nu't cred C++ standard impune, dar compilatoare pentru cele mai comune platforme aceste zile, în general, urmați IEEE754 standard pentru numere în virgulă mobilă. Acest standard specifică patru tipuri de binar în virgulă mobilă (precum și unele BCD formate, pe care am'am mai vazut de sprijin pentru în C++ compilatoare):
Cum această hartă pe C++ tipuri, atunci? În general, "float" folosește un singur precizie; astfel, sizeof(float) = 4
. Apoi "dubla" folosește dublă precizie (cred că's sursa de numele de "dublu"), și long double
pot fi duble sau cvadruple precizie (it's cvadruplă pe sistemul meu, dar pe sisteme pe 32 de biți poate fi dublu). Eu nu't știu de orice compilatoare, care oferă o jumătate de precizie plutitoare-puncte.
În rezumat, aceasta este de obicei:
sizeof(float)
= 4sizeof(double)
= 8sizeof(long double)
= 8 sau 16De la Alex B C++ standard nu specifică dimensiunea integrantă tipuri în bytes, dar se specifică minimă variază acestea trebuie să fie în măsură să dețină. Puteți deduce dimensiunea minimă în biți din intervalul necesar. Puteți deduce dimensiunea minimă în octeți de la care și valoarea CHAR_BIT macro care definește numărul de biți într-un octet (în toate, dar cele mai obscure platforme it's 8, și se poate't fi mai mică decât 8).
O constrângere suplimentară pentru char este că dimensiunea sa este întotdeauna de 1 octet, sau CHAR_BIT biți (de unde și numele).
Minim intervalele cerute de standard (pagina 22) sunt:
și Tip de Date Variază pe MSDN:
semnat char: de la -127 până la 127 (notă, nu -128 la 127; aceasta adăpostește 1's-complement platforme) unsigned char: de la 0 la 255 "simplu" char: de la -127 până la 127 sau 0 la 255 (depinde default char signedness) semnat scurt: -32767 la 32767 nesemnat scurt: de la 0 la 65535 semnat int: -32767 la 32767 unsigned int: 0 la 65535 semnat lung: -2147483647 la 2147483647 unsigned long: 0 si 4294967295 a semnat de mult timp: -9223372036854775807 să 9223372036854775807 unsigned long long: de la 0 la 18446744073709551615 Un C++ (sau C) punerea în aplicare poate defini dimensiunea de un tip în bytes sizeof(tip) pentru nici o valoare, atâta timp cât
expresia sizeof(tip) * CHAR_BIT evaluează la numărul de biți suficient să conțină necesare variază, și
ordonarea de tip este încă valabil (de exemplu, sizeof(int) <= sizeof(long)).
Punerea în aplicare efectivă-game specifice pot fi găsite în <limitele.h> header in C, sau
De exemplu, acest lucru este modul în care va găsi distanța maximă pentru int:
C:
#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();
Acest lucru este corect, cu toate acestea, ai avut dreptate în a spune că: char : 1 octet pe scurt : 2 bytes int : 4 bytes timp : 4 bytes float : 4 bytes dublu : 8 bytes
Pentru 32 de biți arhitecturi sunt încă implicit și cel mai utilizat, și ei au păstrat aceste dimensiuni standard de pre-32 bit zile atunci când memoria a fost mai puțin disponibile, și pentru compatibilitate și standardizare a rămas același. Chiar și 64 de biți sisteme au tendința de a folosi aceste și extinderi/modificări. Vă rugăm să referință pentru mai multe informații: