57 votes

Que se passe-t-il lorsque j'assigne long int à int en C?

Dans un récent travail à la maison, j'ai été obligé d'utiliser long variable pour stocker un résultat, car il peut être un grand nombre.

J'ai décidé de vérifier il vraiment de l'importance pour moi, sur mon système (processeur intel core i5/64 bits windows 7/gnu gcc compiler) et a découvert que le code suivant:

printf("sizeof(char) => %d\n", sizeof(char));
printf("sizeof(short) => %d\n", sizeof(short));
printf("sizeof(short int) => %d\n", sizeof(short int));
printf("sizeof(int) => %d\n", sizeof(int));
printf("sizeof(long) => %d\n", sizeof(long));
printf("sizeof(long int) => %d\n", sizeof(long int));
printf("sizeof(long long) => %d\n", sizeof(long long));
printf("sizeof(long long int) => %d\n", sizeof(long long int));

produit la sortie suivante:

sizeof(char) => 1
sizeof(short) => 2
sizeof(short int) => 2
sizeof(int) => 4
sizeof(long) => 4
sizeof(long int) => 4
sizeof(long long) => 8
sizeof(long long int) => 8

En d'autres termes, sur mon système, int et long sont les mêmes, et tout sera trop grand pour int tenir, ce sera trop grand pour long pour tenir ainsi.

Le devoir à la maison elle-même n'est pas la question ici. Je me demande comment, dans un système où l' int < long, dois-je attribuer une int de temps?

Je suis conscient du fait qu' il sont nombreux étroitement liées à des questions sur ce sujet, mais j'ai l'impression que les réponses à l'intérieur de ces ne me fournissent pas de la compréhension complète de ce qui se passe dans le processus.

Fondamentalement, je suis à essayer de comprendre les éléments suivants:

  1. Dois-je cast long de int avant la cession ou, depuis long n'est pas un type de données différent, mais simplement une touche de modification, il sera considérés comme inoffensifs pour affecter directement?
  2. Ce qui se passe sur les systèmes où l' long > int? Le résultat sera non défini (ou imprévisible) ou il sera la cause de la pièce de rechange de la variable omise?
  3. Comment le casting de long de int travaille dans le C?
  4. Comment fonctionne l'attribution d' long de int travaille en C lorsque je n'ai pas utilisez un casting?

45voto

Keith Thompson Points 85120

La langue des garanties qu' int d'au moins 16 bits, long est au moins 32 bits, et long peut représenter au moins toutes les valeurs qu' int peut représenter.

Si vous affectez un long valeur int objet, c'est implicitement converti. Il n'y a pas besoin d'un cast explicite; elle serait contente de spécifier la même conversion qui va arriver de toute façon.

Sur votre système, la conversion est trivial; il copie simplement la valeur.

Sur un système où l' long est plus large que int, si la valeur ne rentre pas dans un int, alors le résultat de la conversion est mise en œuvre définies. (Ou, en commençant en C99, il peut relever d'une mise en œuvre définies par le signal, mais je ne sais pas du tout les compilateurs qui réellement le faire.) Ce qui généralement se passe est que les bits de poids fort sont mis au rebut, mais vous ne devriez pas compter sur cela. (Les règles sont différentes pour les types non signés; le résultat de la conversion d'un entier signé ou non signé pour un type non signé est bien définie.)

Si vous avez besoin en toute sécurité attribuer un long valeur int objet, vous pouvez vérifier qu'il fit avant de procéder à l'affectation:

#include <limits.h> /* for INT_MIN, INT_MAX */

/* ... */

int i;
long li = /* whatever */

if (li >= INT_MIN && li <= INT_MAX) {
    i = li;
}
else {
    /* do something else? */
}

Les détails de "quelque chose d'autre" sont va dépendre de ce que vous voulez faire.

Une correction: int et long sont toujours des types distincts, même s'ils ont la même taille et de la représentation. L'arithmétique types sont librement convertibles, de sorte que souvent, cela ne fait aucune différence, mais par exemple int* et long* sont distinctes et les types incompatibles; vous ne pouvez pas affecter un long* d'un int*, ou vice versa, sans explicites (et potentiellement dangereux) en fonte.

Et si vous vous trouvez avoir besoin de convertir un long valeur int, la première chose que vous devez faire est de reconsidérer votre code de la conception. Parfois, de telles conversions sont nécessaires, mais le plus souvent, ils sont le signe que l' int auquel vous assignez doit avoir été défini comme un long dans la première place.

4voto

Un long peut toujours représenter toutes les valeurs de int. Si la valeur à portée de main peut être représentée par le type de la variable que vous attribuez à, alors la valeur est conservée.

Si elle ne peut pas être représenté, puis signé le type de destination le résultat est formellement spécifié, tandis que pour les unsigned le type de destination il est précisé que la valeur d'origine modulo 2n, où n est le nombre de bits de la valeur de la représentation (ce qui n'est pas nécessairement tous les bits de la destination).

Dans la pratique, sur les machines modernes, vous obtenez emballage aussi pour les types signés.

C'est parce que les machines modernes utilisent en complément à deux forme pour représenter les entiers signés, sans aucune bits utilisés pour désigner une "valeur non valide" ou telle – c'est à dire, tous les bits sont utilisés pour la valeur de la représentation.

Avec n bits de la valeur de la représentation n'importe quelle valeur entière est x est mappé à x+K*2n avec la constante entière K choisie de telle sorte que le résultat est dans la plage où la moitié du possible, les valeurs sont négatives.

Ainsi, par exemple, avec 32-bit int la valeur -7 est représenté comme bitpattern nombre -7+232 = 232-7, de sorte que si vous affichez le numéro de la bitpattern signifie que entier non signé, vous obtenez un assez grand nombre.

La raison qu'il est appelé en complément à deux est parce qu'il fait sens pour le système de numération binaire, les deux de base système de numération. Pour le système de numération binaire il y a aussi un " (notez l'emplacement de l'apostrophe) en complément. De même, pour la virgule numberal système il y a dix complément et niners' complément. Avec 4 chiffres dix complément représentation vous représenter -7 comme 10000-7 = 9993. C'est tout, vraiment.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X