Quelle est la différence entre «long», «long long», «long int» et «long long int» en C ++?

210

Je passe de Java à C ++ et j'ai des questions sur le longtype de données. En Java, pour contenir un entier supérieur à 2 32 , vous écririez simplement long x;. Cependant, en C ++, il semble que ce longsoit à la fois un type de données et un modificateur.

Il semble y avoir plusieurs façons d'utiliser long:

long x;
long long x;
long int x;
long long int x;

En outre, il semble qu'il existe des éléments tels que:

long double x;

etc.

Quelle est la différence entre tous ces différents types de données et ont-ils tous le même objectif?

1110101001
la source
2
@ user2612743 - pour être sûr, réfléchissez à vos besoins et utilisez le type approprié. long longpourrait être plus lent que long, ce qui pourrait être plus lent que int.
Pete Becker
1
Non, "pour être en sécurité, utiliser longtemps" revient à dire "pour être en sécurité, il suffit de donner à chacun un sida de la terre, afin que nous n'ayons pas à nous soucier des rapports sexuels protégés, nous l'avons tous déjà de toute façon!" Idiot, non? Pensez aux données et aux valeurs possibles qu'elles peuvent avoir, et utilisez le type le mieux adapté. Cela aide également le compilateur à effectuer des optimisations supplémentaires sans casser l'intention du code d'origine, comme s'il devait charger des bibliothèques supplémentaires pour gérer des nombres supérieurs à la largeur de bits naturelle de la plate-forme cible.
CM
Utiliser long long avec les listbox win32 et autres n'a pas l'habitude de faire des ravages avec votre mémoire et d'autres variables, même si les limites ne sont pas dépassées. Même avec les avertissements inoffensifs du C4244, il n'est pas facile à détecter.
Laurie Stearn

Réponses:

182

longet long intsont identiques. Il en va de même long longpour long long int. Dans les deux cas, l' intoption est facultative.

Quant à la différence entre les deux ensembles, la norme C ++ impose des plages minimales pour chacun, et c'est long longau moins aussi large que long.

Les parties contrôlantes de la norme (C ++ 11, mais cela existe depuis longtemps) sont, d'une part 3.9.1 Fundamental types, la section 2 (une section ultérieure donne des règles similaires pour les types intégraux non signés):

Il existe cinq types d'entiers signés standard: char signé, int court, int, long int et long long int. Dans cette liste, chaque type fournit au moins autant de stockage que ceux qui le précèdent dans la liste.

Il y a aussi un tableau 9 dans 7.1.6.2 Simple type specifiers, qui montre les "mappages" des spécificateurs aux types réels (montrant que le intest facultatif), dont une section est montrée ci-dessous:

Specifier(s)         Type
-------------    -------------
long long int    long long int
long long        long long int
long int         long int
long             long int

Notez la distinction entre le spécificateur et le type. Le spécificateur est la façon dont vous dites au compilateur quel est le type, mais vous pouvez utiliser différents spécificateurs pour aboutir au même type.

Par conséquent, longen soi, ce n'est ni un type ni un modificateur comme le pose votre question, c'est simplement un spécificateur pour le long inttype. Idem pour long longêtre un spécificateur pour le long long inttype.

Bien que la norme C ++ elle-même ne spécifie pas les plages minimales de types intégraux, elle cite C99, in 1.2 Normative references, comme s'appliquant. Par conséquent, les plages minimales définies dans C99 5.2.4.2.1 Sizes of integer types <limits.h>sont applicables.


En termes de long double, c'est en fait une valeur à virgule flottante plutôt qu'un entier. Comme pour les types intégraux, il est nécessaire d'avoir au moins autant de précision que a doubleet de fournir un surensemble de valeurs sur ce type (c'est- à- dire au moins ces valeurs, pas nécessairement plus de valeurs).

paxdiablo
la source
4
même chose avec unsignedetunsigned int
Kal
2
Je suis sûr que longc'est au moins 32 bits (2 ^ 31-1 de chaque côté de zéro) et long longau moins 64 (2 ^ 63-1 de chaque côté).
chris
2
Et long doubleest garanti d'avoir au moins la plage de double, mais il peut être le même. Cela dépend de l'ordinateur. Certaines FPU ont une précision étendue; les puces x87 avaient une précision simple de 32 bits, une double précision de 64 bits et une précision étendue de 80 bits.
Eric Jablow
Quant aux exigences de plage, la norme C ++ 11 fait référence à la norme C11, qui a des plages réelles.
chris
La partie "int" fait simplement la différence entre un type entier et une virgule flottante, un caractère ou un autre type non entier. Dans de nombreux cas, cela peut être déduit par le compilateur, donc il peut être supprimé - C'est pourquoi "unsigned" est le même que "unsigned int", par exemple. La partie "int" est simplement supposée sauf si le programmeur spécifie autre chose, comme "char" ou "double". Quant aux tailles réelles utilisées .. selon la norme que vous lisez, chaque taille peut avoir un nombre minimum de bits, mais elles sont toutes définies de telle sorte que chacune est au moins aussi grande que le type précédent.
CM
64

Long et long int sont au moins 32 bits.

long long et long long int font au moins 64 bits. Vous devez utiliser un compilateur c99 ou mieux.

les longs doubles sont un peu bizarres. Recherchez-les sur Wikipedia pour plus de détails.

Eric Lippert
la source
17

longest équivalent à long int, tout comme shortest équivalent à short int. A long intest un type intégral signé d' au moins 32 bits, tandis que a long longou long long intest un type intégral signé d' au moins 64 bits.

Cela ne signifie pas nécessairement que a long longest plus large que a long. De nombreuses plates-formes / ABI utilisent le LP64modèle - où long(et les pointeurs) ont une largeur de 64 bits. Win64 utilise le LLP64, où longest toujours 32 bits et long long(et les pointeurs) ont une largeur de 64 bits.

Il y a un bon résumé des modèles de données 64 bits ici .

long doublene garantit pas grand-chose d'autre qu'il sera au moins aussi large qu'un double.

Brett Hale
la source
7

Cela semble déroutant car vous prenez longlui-même un type de données.

longn'est rien d'autre qu'un raccourci long intlorsque vous l'utilisez seul.

longest un modificateur, vous pouvez l'utiliser doubleaussi avec long double.

long== long int.

Les deux prennent 4 octets.

Siraj Alam
la source
La prise longue de 4 octets n'est valable que sur Win64, elle dépend de la plateforme
Prodigle
1
Oui évidemment ... pas seulement longtemps ... int prend 4 octets et 2 octets dépendent de la plate-forme, sans aucun doute.
Siraj Alam
3

Historiquement, au début du temps C, lorsque les processeurs avaient une longueur de mot de 8 ou 16 bits, intc'était identique à aujourd'hui short(16 bits). Dans un certain sens, int est un type de données plus abstraites que char, short, longou long long, comme vous ne pouvez pas être sûr de la largeur de bit.

Lors de la définition, int n;vous pouvez traduire cela par "donnez-moi le meilleur compromis de largeur de bit et de vitesse sur cette machine pour n". Peut-être qu'à l'avenir, vous devriez vous attendre à ce que les compilateurs traduisent inten 64 bits. Donc, lorsque vous voulez que votre variable ait 32 bits et pas plus, mieux vaut utiliser un longtype de données explicite .

[Modifier: #include <stdint.h>semble être le bon moyen de garantir les largeurs de bit en utilisant les types int ## _ t, bien qu'il ne fasse pas encore partie de la norme.]

thomiel
la source
2
Cette dernière partie, en utilisant un "long" pour obtenir 32 bits lorsque int est 64 bits, est incorrecte. Si int est de 64 bits, alors long sera également d' au moins 64 bits. Long est garanti d'être au moins aussi grand que int, bien qu'il puisse être plus grand, mais jamais plus petit. La plupart des compilateurs ont différentes méthodes qui permettent au programmeur d'être plus spécifique, comme un type __int32 (non portable) qui est exactement 32 bits, et ainsi de suite.
CM
1
Comme défini dans la norme C, a longest garanti d'avoir au moins 32 bits. (Les normes peuvent changer dur.) Le projet actuel de C ++ 14 dit simplement: @CM "Les entiers simples ont la taille naturelle suggérée par l'architecture de l'environnement d'exécution, les autres types entiers signés sont fournis pour répondre à des besoins spéciaux" (section 3.9.1 ). Je n'ai trouvé aucun mot sur les relations de longueur des différents pouces en elle. __int32 ne fait pas vraiment partie de la norme, mais depuis C ++ 11, il existe des typedefs disponibles comme int_fast32_t ou int_least32_t disponibles pour vous obtenir exactement ce que vous voulez.
thomiel
Je dirais que sur les implémentations du XXe siècle pour les micro-ordinateurs reprogrammables à usage général, charétait presque unanimement 8 bits, short16 et long32; intpourrait être 16 ou 32. Remarque pour certaines plates-formes (en particulier le 68000), les deux 16 bits et 32 ​​bits intétaient assez communs, et en effet certains compilateurs avaient des options pour prendre en charge les deux. On s'attendait donc à ce que le code qui devait être portable soit utilisé shortou longde préférence int.
supercat
0

Alors qu'en Java a longest toujours 64 bits, en C ++ cela dépend de l'architecture de l'ordinateur et du système d'exploitation . Par exemple, un longest de 64 bits sur Linux et 32 bits sous Windows (ce qui a été fait pour maintenir en arrière-compatibilité, ce qui permet de compiler sans aucune modification sur Windows 64 bits programmes 32 bits).

Il est considéré comme un bon style C ++ à éviter short int long ... et à utiliser à la place:

std::int8_t   # exactly  8 bits
std::int16_t  # exactly 16 bits
std::int32_t  # exactly 32 bits
std::int64_t  # exactly 64 bits

std::size_t   # can hold all possible object sizes, used for indexing

Ceux-ci ( int*_t) peuvent être utilisés après avoir inclus l'en- <cstdint>tête. size_test dedans <stdlib.h>.

xjcl
la source