web-dev-qa-db-fra.com

La taille de C "int" est-elle 2 octets ou 4 octets?

Une variable entière en C occupe-t-elle 2 octets ou 4 octets? De quels facteurs dépend-il?

La plupart des manuels indiquent que les variables entières occupent 2 octets . Mais lorsque je lance un programme imprimant les adresses successives d'un tableau d'entiers, il montre la différence de 4.

124
Rajiv Prathap

Je sais que c'est égal à sizeof(int). La taille de int dépend vraiment du compilateur. À l'époque, lorsque les processeurs étaient en 16 bits, une int était de 2 octets. De nos jours, il s'agit le plus souvent de 4 octets sur un système 32 bits ainsi que sur un système 64 bits. 

Néanmoins, utiliser sizeof(int) est le meilleur moyen d’obtenir la taille d’un entier pour le système spécifique sur lequel le programme est exécuté.

EDIT: Correction d'une instruction incorrecte qui int est 8 octets sur la plupart des systèmes 64 bits. Par exemple, il s'agit de 4 octets sur un GCC 64 bits.

144
yhyrcanus

C’est l’un des points de C qui peut prêter à confusion au premier abord, mais le standard C ne spécifie qu’une plage/ minimum pour les types entiers dont la compatibilité est garantie. Il est garanti que int peut contenir -32767 à 32767, ce qui nécessite 16 bits. Dans ce cas, int, correspond à 2 octets. Cependant, les implémentations sont libres d’aller au-delà de ce minimum, car vous verrez que de nombreux compilateurs modernes font int 32-bit (ce qui signifie également 4 octets plutôt universels).

La raison pour laquelle votre livre dit 2 octets est probablement parce qu'elle est ancienne. À une époque, c'était la norme. En général, vous devez toujours utiliser l'opérateur sizeof si vous devez savoir combien d'octets il se trouve sur la plate-forme que vous utilisez.

Pour remédier à cela, C99 a ajouté de nouveaux types dans lesquels vous pouvez explicitement demander un entier de taille déterminée, par exemple int16_t ou int32_t. Auparavant, il n'existait aucun moyen universel d'obtenir un entier d'une largeur spécifique (bien que la plupart des plates-formes fournissaient des types similaires plateforme par plateforme).

91
FatalError

Il n'y a pas de réponse spécifique. Cela dépend de la plate-forme. C'est défini par l'implémentation. Cela peut être 2, 4 ou autre chose.

L’idée de int était qu’elle était supposée correspondre à la taille naturelle de "Word" sur la plate-forme donnée: 16 bits sur les plates-formes 16 bits, 32 bits sur les plates-formes 32 bits, 64 bits sur les plates-formes 64 bits, vous avez l’idée . Cependant, pour des raisons de compatibilité ascendante, certains compilateurs préfèrent s'en tenir à int 32 bits, même sur des plates-formes 64 bits.

Le temps de la variable int sur deux octets est cependant révolu depuis longtemps (plates-formes 16 bits?), Sauf si vous utilisez une plate-forme intégrée avec une taille de mot 16 bits. Vos manuels sont probablement très vieux.

26
AnT

La réponse à cette question dépend de la plate-forme que vous utilisez.
Mais quelle que soit la plate-forme, vous pouvez supposer de manière fiable les types suivants:

 [8-bit] signed char: -127 to 127
 [8-bit] unsigned char: 0 to 255
 [16-bit]signed short: -32767 to 32767
 [16-bit]unsigned short: 0 to 65535
 [32-bit]signed long: -2147483647 to 2147483647
 [32-bit]unsigned long: 0 to 4294967295
 [64-bit]signed long long: -9223372036854775807 to 9223372036854775807
 [64-bit]unsigned long long: 0 to 18446744073709551615
17
Priyank Arora

Une variable entière en C occupe-t-elle 2 octets ou 4 octets?

Cela dépend de la plate-forme utilisée et de la configuration de votre compilateur. La seule réponse autorisée est d'utiliser l'opérateur sizeof pour voir la taille d'un entier dans votre situation spécifique.


De quels facteurs dépend-il?

Il est préférable de considérer Range plutôt que size. Les deux vont varier dans la pratique, bien qu'il soit beaucoup plus simple de choisir des types variables par plage plutôt que par taille, comme nous le verrons. Il est également important de noter que la norme nous encourage à envisager de choisir nos types entiers basés sur range plutôt que size, mais pour le moment, ignorons la pratique standard et laissez notre curiosité explorer sizeof , octets et CHAR_BIT, et la représentation entière ... creusons le terrier du lapin et voyons-le nous-mêmes ...


sizeof, OCTETS ET CHAR_BIT

La déclaration suivante, tirée du standard C (lié au précédent), décrit cela dans des mots que je ne pense pas pouvoir améliorer.

L'opérateur sizeof donne la taille (en octets) de son opérande, qui peut être une expression ou le nom entre parenthèses d'un type. La taille est déterminée par le type de l'opérande.

En supposant qu’une compréhension claire nous amène à une discussion sur bytes. On suppose généralement qu'un octet a huit bits, alors que CHAR_BIT indique le nombre de bits dans un octet . C'est juste une autre de ces nuances qui n'est pas prise en compte quand on parle de les entiers communs à deux (ou quatre) octets.

Terminons les choses jusqu'à présent:

  • sizeof> taille en octets, et
  • CHAR_BIT => nombre de bits dans l'octet

Ainsi, en fonction de votre système, sizeof (unsigned int) pourrait être _ = toute valeur supérieure à zéro (pas seulement 2 ou 4), comme si CHAR_BIT était 16, alors un seul octet (seize bits) contient suffisamment de bits dans il représente le nombre entier de seize bits décrit par les normes (cité ci-dessous). Ce n'est pas nécessairement une information utile, n'est-ce pas? Approfondissons ...


Représentation entière

La norme C spécifie la précision/la plage minimale pour tous les types d'entiers standard (et CHAR_BIT, également, fwiw) ici . Nous pouvons en déduire un minimum pour combien de bits sont nécessaires pour stocker la valeur, mais nous pouvons également choisir nos variables en fonction de plages. Néanmoins, une grande partie des détails requis pour cette réponse réside ici. Par exemple, ce qui suit montre que le unsigned int standard nécessite (au moins) 16 bits de stockage:

UINT_MAX                                65535 // 2¹⁶ - 1

Ainsi, nous pouvons voir que unsigned int require (au moins) 16 bits, où vous obtenez le deux octets (en supposant que CHAR_BIT est 8) ... et plus tard lorsque cette limite est passée à 2³² - 1, les gens déclaraient 4 octets à la place. Ceci explique les phénomènes que vous avez observés:

La plupart des manuels disent que les variables entières occupent 2 octets. Mais lorsque je lance un programme imprimant les adresses successives d’un tableau d’entiers, il montre la différence de 4.

Vous utilisez un ancien manuel et compilateur qui vous enseigne le C non portable; l'auteur qui a écrit votre manuel pourrait même ne pas être au courant de CHAR_BIT. Vous devriez mettre à jour votre manuel (et votre compilateur) et vous efforcer de vous rappeler que I.T. C’est un domaine en constante évolution que vous devez garder en avance sur pour rivaliser… Assez, cependant; Voyons quels autres secrets non-portables ces sous-titres entiers sous-jacents stockent ...

Les bits de valeur sont ce que les idées fausses courantes semblent compter. L'exemple ci-dessus utilise un type entier unsigned qui ne contient généralement que des bits de valeur. Il est donc facile de rater le diable dans les détails.

Sign bits ... Dans l'exemple ci-dessus, j'ai cité UINT_MAX comme étant la limite supérieure de unsigned int car il s'agit d'un exemple trivial permettant d'extraire la valeur 16 du commentaire. Pour les types signés, afin de distinguer les valeurs positives des valeurs négatives (c'est le signe), nous devons également inclure le bit de signe.

INT_MIN                                -32768 // -(2¹⁵)
INT_MAX                                +32767 // 2¹⁵ - 1

Bits de remplissage ... Bien qu'il ne soit pas courant de rencontrer des ordinateurs qui ont des bits de remplissage dans les entiers, la norme C permet cela. certaines machines (c'est-à-dire celle-ci ) implémentent des types entiers plus grands en combinant deux valeurs entières plus petites (signées) ... et lorsque vous combinez des entiers signés, vous obtenez un bit de signe perdu. Ce bit gaspillé est considéré comme padding en C. D'autres exemples de bits de padding pourraient inclure bits de parité et bits de piège .


Comme vous pouvez le constater, le standard semble vous inciter à considérer des plages telles que INT_MIN..INT_MAX et autres valeurs minimum/maximum du standard lorsque vous choisissez des types entiers, et décourage l'utilisation de la taille, car il existe d'autres des facteurs subtils susceptibles d'être oubliés tels que CHAR_BIT et des bits de remplissage qui peuvent affecter la valeur de sizeof (int) (c'est-à-dire les idées fausses courantes de entiers à deux octets et à quatre octets négligent ces détails).

11
Flimzy

Projet de norme C99 N1256

http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf

La taille de int et de tous les autres types entiers est définie par l'implémentation. C99 spécifie uniquement:

  • taille minimum garantie
  • tailles relatives entre les types

5.2.4.2.1 "Tailles des types entiers <limits.h>" donne les tailles minimales:

1 [...] Leurs valeurs définies pour la mise en œuvre doivent être égales ou supérieures en magnitude (valeur absolue) à celles indiquées [...]

  • UCHAR_MAX 255 // 2 8 - 1
  • USHRT_MAX 65535 // 2 16 - 1
  • UINT_MAX 65535 // 2 16 - 1
  • ULONG_MAX 4294967295 // 2 32 - 1
  • ULLONG_MAX 18446744073709551615 // 2 64 - 1

6.2.5 "Types" dit alors:

8 Pour deux types entiers avec la même signature et un rang de conversion entier différent (voir 6.3.1.1), la plage de valeurs du type avec un rang de conversion entier plus petit est un sous-gamme des valeurs de l'autre type.

et 6.3.1.1 "Booléen, caractères et nombres entiers" détermine les rangs de conversion relatifs:

1 Chaque type d’entier a un rang de conversion d’entier défini comme suit:

  • Le rang de long long int doit être supérieur au rang de long int, qui doit être supérieur au rang d'int, qui doit être supérieur au rang de short int, qui doit être supérieur au rang du caractère signé.
  • Le rang de tout type entier non signé doit être égal au rang du .__ correspondant. type entier signé, le cas échéant.
  • Pour tous les types entiers T1, T2 et T3, si T1 a un rang supérieur à T2 et T2 a rang supérieur à T3, alors T1 a un rang supérieur à T3

Les seules garanties sont que char doit avoir au moins 8 bits de large, short et int doit avoir au moins 16 bits de large et long doit avoir au moins 32 bits de large et que sizeof (char) <= sizeof (short) <= sizeof (int) <= sizeof (long) (il en va de même pour les versions non signées de ces types). 

int peut avoir une largeur comprise entre 16 et 64 bits, selon la plate-forme. 

6
John Bode

Cela dépend principalement de la plate-forme que vous utilisez. Cela dépend du compilateur au compilateur. Aujourd'hui, dans la plupart des compilateurs int est de 4 octets . Si vous voulez vérifier ce que votre compilateur utilise peut utiliser sizeof(int).

main()
{
    printf("%d",sizeof(int));
    printf("%d",sizeof(short));
    printf("%d",sizeof(long));
}

La seule promesse du compilateur est que la taille de short doit être égale ou inférieure à int et que la taille de long doit être égale ou supérieure à int.So, si la taille de int est 4, la taille de short peut être 2 ou 4 mais pas plus grande que cela soit vrai pour longtemps et int. Il dit aussi que la taille du court et du long ne peut pas être la même.

5
justpraveen

La taille de C “int” est-elle 2 octets ou 4 octets?

La réponse est "oui"/"non"/"peut-être"/"peut-être pas".

Le langage de programmation C spécifie ce qui suit: la plus petite unité adressable, connue par char et aussi appelée "byte", a exactement CHAR_BIT bits de large, où CHAR_BIT est au moins de 8.

Ainsi, un octet dans C n'est pas nécessairement un octet, c'est-à-dire 8 bits. Dans le passé, l'une des premières plates-formes à exécuter du code C (et Unix) avait une variable int sur 4 octets - mais au total, int avait 36 ​​bits, car CHAR_BIT était de 9!

int est censé être la taille naturelle de la plate-forme dont la plage est égale à au moins -32767 ... 32767. Vous pouvez obtenir la taille de int dans les octets de la plate-forme avec sizeof(int); en multipliant cette valeur par CHAR_BIT, vous saurez à quel point elle est large en bits.


Bien que les machines 36 bits soient presque toutes mortes, il existe encore des plates-formes avec des octets non-8 bits. Hier encore, il y avait une question sur un MCU Texas Instruments avec 16 octets , avec un compilateur conforme C99, conforme à C11.

Sur TMS320C28x , il semble que char, short et int aient all 16 bits de large, et donc un octet. long int est 2 octets et long long int est 4 octets. La beauté de C est qu’il est encore possible d’écrire un programme efficace pour une plate-forme comme celle-ci, et même de le faire de manière portable!

4
Antti Haapala

Cela dépend de l'implémentation, mais généralement sur x86 et d'autres architectures populaires comme ARM ints prennent 4 octets. Vous pouvez toujours vérifier au moment de la compilation en utilisant sizeof(int) ou tout autre type à vérifier.

Si vous voulez vous assurer que vous utilisez un type d'une taille spécifique, utilisez les types dans <stdint.h>

3
slartibartfast
#include <stdio.h>

int main(void) {
    printf("size of int: %d", (int)sizeof(int));
    return 0;
}

Cela retourne 4, mais cela dépend probablement de la machine.

2
thelaws

La taille de C “int” est-elle 2 octets ou 4 octets? 

Une variable entière en C occupe-t-elle 2 octets ou 4 octets?

C permet aux "octets" d’être autre chose que 8 bits par "octet". 

CHAR_BIT nombre de bits pour le plus petit objet qui n'est pas un champ de bits (octet) C11dr §5.2.4.2.1 1

Une valeur de quelque chose que 8 est de plus en plus rare. Pour une portabilité maximale, utilisez CHAR_BIT plutôt que 8. La taille de int dans bits dans C est sizeof(int) * CHAR_BIT

#include <limits.h>
printf("(int) Bit size %zu\n", sizeof(int) * CHAR_BIT);

De quels facteurs dépend-il?

La taille de bit int est généralement de 32 ou 16 bits. C minimum spécifié gammes:

valeur minimale pour un objet de type intINT_MIN -32767
valeur maximale pour un objet de type intINT_MAX +32767
C11dr §5.2.4.2.1 1

La plage minimum pour int force la taille du bit à être au moins au moins 16, même si le processeur était à "8 bits". Une taille comme 64 bits est vue dans les processeurs spécialisés. D'autres valeurs telles que 18, 24, 36, etc. se sont produites sur des plateformes historiques ou sont au moins théoriquement possibles. Le codage moderne s'inquiète rarement des tailles de bits int non puissantes.

Le processeur et l'architecture de l'ordinateur déterminent la sélection de la taille de bit int

Cependant, même avec les processeurs 64 bits, la taille int du compilateur peut être 32 bits pour des raisons de compatibilité, car les bases de code volumineuses dépendent de int étant 32 bits (ou 32/16).

1
chux

Ceci est une bonne source pour répondre à cette question.

Mais cette question est une sorte de réponse toujours vraie: "Oui. Les deux."

Cela dépend de votre architecture. Si vous travaillez sur une machine 16 bits ou moins, vous ne pouvez pas utiliser 4 octets (= 32 bits). Si vous travaillez sur une machine 32 bits ou supérieure, sa longueur est de 32 bits. 

Pour comprendre, préparez votre programme pour obtenir quelque chose de lisible et utilisez la fonction "sizeof". Cela renvoie la taille en octets de votre type de données déclaré. Mais soyez prudent en utilisant ceci avec des tableaux. 

Si vous déclarez int t[12];, il retournera 12 * 4 octets. Pour obtenir la longueur de ce tableau, utilisez simplement sizeof(t)/sizeof(t[0]). Si vous allez construire une fonction, cela devrait calculer la taille d'un tableau d'envoi, rappelez-vous que si

typedef int array[12];
int function(array t){
    int size_of_t = sizeof(t)/sizeof(t[0]);
    return size_of_t;
}
void main(){
    array t = {1,1,1};  //remember: t= [1,1,1,0,...,0]
    int a = function(t);    //remember: sending t is just a pointer and equal to int* t
   print(a);   // output will be 1, since t will be interpreted as an int itselve. 
}

Donc, cela ne retournera même pas quelque chose de différent. Si vous définissez un tableau et essayez d’obtenir la longueur par la suite, utilisez sizeof. Si vous envoyez un tableau à une fonction, rappelez-vous que la valeur d'envoi est simplement un pointeur sur le premier élément. Mais au cas où, vous savez toujours quelle taille a votre tableau. Le cas deux peut être déterminé en définissant deux fonctions et manque certaines performances. Définissez la fonction (tableau t) et définissez la fonction2 (tableau t, int size_of_t). Appelez "function (t)" pour mesurer la longueur par un travail de copie et envoyer le résultat à function2, où vous pouvez faire ce que vous voulez avec des tailles de tableau variables 

0
Shalec