web-dev-qa-db-fra.com

Vs longs. Int C / C ++ - À quoi ça sert?

Comme je l'ai appris récemment, un long en C/C++ est de la même longueur qu'un int. Pour faire simple, pourquoi? Il semble presque inutile d'inclure même le type de données dans la langue. Y a-t-il des utilisations qui lui sont spécifiques qu'un int n'a pas? Je sais que nous pouvons déclarer un int 64 bits comme ceci:

long long x = 0;

Mais pourquoi la langue choisit-elle de le faire de cette façon, plutôt que de simplement faire un long puits ... plus long qu'un int? D'autres langages tels que C # font cela, alors pourquoi pas C/C++?

28
MGZero

Lors de l'écriture en C ou C++, chaque type de données est spécifique à l'architecture et au compilateur. Sur un système int est 32, mais vous pouvez en trouver de 16 ou 64; ce n'est pas défini, c'est donc au compilateur.

Quant à long et int, cela vient de fois, où l'entier standard était 16 bits, où long était un entier 32 bits - et en effet était plus long que int.

30
Griwes

Les garanties spécifiques sont les suivantes:

  • char est d'au moins 8 bits (1 octet par définition, quel que soit le nombre de bits)
  • short est d'au moins 16 bits
  • int est d'au moins 16 bits
  • long est au moins 32 bits
  • long long (dans les versions de la langue qui le prennent en charge) est d'au moins 64 bits
  • Chaque type dans la liste ci-dessus est au moins aussi large que le type précédent (mais peut être le même).

Ainsi, il est logique d'utiliser long si vous avez besoin d'un type d'au moins 32 bits, int si vous avez besoin d'un type raisonnablement rapide et d'au moins 16 bits.

En fait, au moins en C, ces limites inférieures sont exprimées en termes de plages, pas de tailles. Par exemple, la langue requiert que INT_MIN <= -32767, et INT_MAX >= +32767. Les exigences de 16 bits découlent de cela et de l'exigence que les entiers soient représentés en binaire.

C99 ajoute <stdint.h> et <inttypes.h>, qui définissent des types tels que uint32_t, int_least32_t, et int_fast16_t; ce sont des typedefs, généralement définis comme des alias pour les types prédéfinis.

(Il n'y a pas nécessairement une relation directe entre la taille et la plage. Une implémentation pourrait faire int 32 bits, mais avec une plage de seulement, disons, -2**23 .. +2^23-1, les 8 autres bits (appelés bits de remplissage) ne contribuent pas à la valeur. Il est théoriquement possible (mais pratiquement hautement improbable) que int puisse être plus grand que long, tant que long a au moins aussi large a plage comme int. En pratique, peu de systèmes modernes utilisent des bits de remplissage, ou même des représentations autres que le complément à 2, mais la norme autorise toujours de telles bizarreries. Vous êtes plus susceptible de rencontrer des fonctionnalités exotiques dans les systèmes embarqués.)

30
Keith Thompson

long n'est pas la même longueur qu'un int. Selon la spécification, long est au moins aussi grand que int. Par exemple, sous Linux x86_64 avec GCC, sizeof (long) = 8 et sizeof (int) = 4.

18
arsenm

long n'est pas de la même taille que int, c'est au moins la même taille que int. Pour citer la norme C++ 03 (3.9.1-2):

Il existe quatre types d'entiers signés: "char signé", "short int", "int" et "long int". Dans cette liste, chaque type fournit au moins autant de stockage que ceux qui le précèdent dans la liste. Les entiers simples ont la taille naturelle suggérée par l'architecture de l'environnement d'exécution); les autres types d'entiers signés sont fournis pour répondre à des besoins particuliers.

Mon interprétation de ceci est "utilisez simplement int, mais si pour une raison qui ne correspond pas à vos besoins et que vous avez de la chance de trouver un autre type intégral mieux adapté, soyez notre invité et utilisez-le à la place". Une façon dont long pourrait être meilleure est si vous êtes sur une architecture où elle est ... plus longue.

13
Jon

à la recherche de quelque chose de complètement indépendant et tombé sur cela et avait besoin de répondre. Oui, c'est vieux, donc pour les gens qui surfent plus tard ...

Franchement, je pense que toutes les réponses ici sont incomplètes.

La taille d'un long est la taille du nombre de bits sur lesquels votre processeur peut fonctionner en même temps. Il est également appelé "mot". Un "demi-mot" est un court métrage. Un "double mot" est un long long et est deux fois plus grand qu'un long (et à l'origine n'était implémenté que par des fournisseurs et non standard), et encore plus grand qu'un long long est un "quadword" qui est deux fois la taille d'un long long mais il n'avait pas de nom officiel (et pas vraiment standard).

Maintenant, d'où vient l'int? S'enregistre en partie sur votre processeur et en partie sur votre système d'exploitation. Vos registres définissent les tailles natives gérées par le processeur, qui définissent à leur tour la taille de choses comme le court et le long. Les processeurs sont également conçus avec une taille de données qui est la taille la plus efficace pour fonctionner. Cela devrait être un int.

Sur les machines 64 bits d'aujourd'hui, vous supposeriez, car un long est un mot et un mot sur une machine 64 bits est 64 bits, qu'un long serait 64 bits et un int quel que soit le processeur est conçu pour gérer, mais il pourrait ne pas l'être. Pourquoi? Votre système d'exploitation a choisi un modèle de données et défini ces tailles de données pour vous (à peu près par la façon dont il est construit). En fin de compte, si vous êtes sous Windows (et que vous utilisez Win64), c'est 32 bits pour un long et un entier. Solaris et Linux utilisent des définitions différentes (la longueur est de 64 bits). Ces définitions sont appelées choses comme ILP64, LP64 et LLP64. Windows utilise LLP64 et Solaris et Linux utilisent LP64:

 Modèle ILP64 LP64 LLP64 
 Int 64 32 32 
 Long 64 64 32 
 Pointeur 64 64 64 
 Long long 64 64 64 

Où, par exemple, ILP signifie int-long-pointer, et LLP signifie long-long-pointer

Pour contourner ce problème, la plupart des compilateurs semblent prendre en charge la définition de la taille d'un entier directement avec des types comme int32 ou int64.

1
bueller