Une variable Integer en C occupe-t-elle 2 octets ou 4 octets? De quels facteurs cela dépend-il?
La plupart des manuels disent que les variables entières occupent 2 octets. Mais lorsque j'exécute un programme imprimant les adresses successives d'un tableau d'entiers, il montre la différence de 4.
int
n'est qu'un des nombreux types d' entiers . Vous avez posé des questions sur la taille de "integer"; vous vouliez probablement poser des questions sur la taille deint
.int
vaut 2 octets (a) fait probablement référence à un ancien système, et (b) ne parvient pas à préciser que la taille variera d'un système à l'autre. Le meilleur livre sur C est "The C Programming Language" de Kernighan et Ritchie, bien qu'il suppose une certaine expérience en programmation. Voir aussi la question 18.10 de la FAQ comp.lang.c .#define int int64_t
sur une plate-forme 64 bits, donc ni l'un ni l'autre. Utilisez simplementsizeof
. ;-)Réponses:
Je sais que c'est égal à
sizeof(int)
. La taille d'unint
dépend vraiment du compilateur. À l'époque, lorsque les processeurs étaient 16 bits, unint
était de 2 octets. De nos jours, c'est le plus souvent 4 octets sur un système 32 bits ainsi que 64 bits.Pourtant, l'utilisation
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 déclaration erronée de
int
8 octets sur la plupart des systèmes 64 bits. Par exemple, il est de 4 octets sur GCC 64 bits.la source
sizeof(int)
peut être n'importe quelle valeur de1
. Il n'est pas nécessaire qu'un octet soit 8 bits et certaines machines n'ont pas d'unité adressable 8 bits (ce qui est fondamentalement la définition d'un octet dans la norme). La réponse n'est pas correcte sans plus d'informations.C'est l'un des points de C qui peut prêter à confusion au début, mais la norme C ne spécifie qu'une plage minimale pour les types entiers dont la prise en charge est garantie.
int
est garanti de pouvoir contenir -32767 à 32767, ce qui nécessite 16 bits. Dans ce casint
,, vaut 2 octets. Cependant, les implémentations sont libres d'aller au-delà de ce minimum, car vous verrez que de nombreux compilateurs modernes font duint
32 bits (ce qui signifie également 4 octets de manière omniprésente).La raison pour laquelle votre livre dit 2 octets est probablement parce qu'il est vieux. À une certaine époque, c'était la norme. En général, vous devez toujours utiliser l'
sizeof
opérateur si vous avez besoin de savoir combien d'octets il se trouve sur la plate-forme que vous utilisez.Pour résoudre ce problème, C99 a ajouté de nouveaux types dans lesquels vous pouvez demander explicitement un certain entier de taille, par exemple
int16_t
ouint32_t
. Avant cela, il n'existait pas de moyen universel d'obtenir un entier d'une largeur spécifique (bien que la plupart des plates-formes fournissaient des types similaires sur une base par plate-forme).la source
int
. C ne fait pas cette hypothèse. Les systèmes de complément et de grandeur de signe de 1 ne peuvent pas représenter-32768
en 16 bits; ils ont plutôt deux représentations pour zéro (positive et négative). C'est pourquoi la plage minimale pour unint
est[-32767..32767]
.Il n'y a pas de réponse précise. Cela dépend de la plateforme. Il est défini par la mise en œuvre. Cela peut être 2, 4 ou autre chose.
L'idée derrière
int
était qu'il était censé correspondre à la taille naturelle du "mot" 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 voyez l'idée. Cependant, à des fins de compatibilité descendante, certains compilateurs préfèrent s'en tenir au 32 bitsint
même sur les plates-formes 64 bits.Le temps de 2 octets
int
est révolu depuis longtemps (plates-formes 16 bits?) À moins que vous n'utilisiez une plate-forme intégrée avec une taille de mot de 16 bits. Vos manuels sont probablement très vieux.la source
The idea behind int was that it was supposed to match the natural "word" size on the given platform
- C'est ce que je cherchais. Une idée de la raison? Dans un monde libre, int pourrait occuper n'importe quel nombre d'octets consécutifs dans la mémoire, n'est-ce pas? 8, 16 peu importeLa réponse à cette question dépend de la plate-forme que vous utilisez.
Mais quelle que soit la plate-forme, vous pouvez assumer de manière fiable les types suivants:
la source
Cela dépend de la plate-forme que vous utilisez, ainsi que de la configuration de votre compilateur. La seule réponse qui fait autorité est d'utiliser l'
sizeof
opérateur pour voir la taille d'un entier dans votre situation spécifique.La gamme pourrait être mieux considérée, plutôt que la taille . Les deux varient en pratique, bien qu'il soit beaucoup plus infaillible de choisir des types de variables par plage que par taille, comme nous le verrons. Il est également important de noter que la norme nous encourage à envisager de choisir nos types d'entiers en fonction de la plage plutôt que de la taille , mais pour l'instant ignorons la pratique standard , et laissons notre curiosité explorer
sizeof
, octets etCHAR_BIT
, et représentation entière ... le terrier du lapin et le voir par nous-mêmes ...sizeof
, octets etCHAR_BIT
La déclaration suivante, tirée de la norme C (liée à ci-dessus), décrit cela avec des mots que je ne pense pas pouvoir être améliorés.
En supposant qu'une compréhension claire nous mènera à une discussion sur les octets . Il est communément admis qu'un octet est de huit bits, alors qu'en fait,
CHAR_BIT
vous indique combien de bits il y a dans un octet . C'est juste une autre de ces nuances qui n'est pas prise en compte lorsque l'on parle des entiers communs à deux (ou quatre) octets .Concluons les choses jusqu'à présent:
sizeof
=> taille en octets, etCHAR_BIT
=> nombre de bits dans l'octetAinsi, selon votre système,
sizeof (unsigned int)
peut être n'importe quelle valeur supérieure à zéro (pas seulement 2 ou 4), comme siCHAR_BIT
était 16, alors un seul octet (seize bits) contient suffisamment de bits pour représenter l'entier de seize bits décrit par le normes (citées ci-dessous). Ce n'est pas nécessairement une information utile, n'est-ce pas? Allons plus loin ...Représentation entière
Les C norme spécifie la précision / gamme minimum pour tous les types entiers standard (et
CHAR_BIT
, aussi, FWIW) ici . À partir de là, nous pouvons déduire un minimum pour le nombre de bits requis pour stocker la valeur , mais nous pouvons tout aussi bien 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 que la normeunsigned int
nécessite (au moins) seize bits de stockage:Ainsi, nous pouvons voir qu'il
unsigned int
faut ( au moins ) 16 bits , c'est là que vous obtenez les deux octets (en supposant queCHAR_BIT
c'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: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
CHAR_BIT
. Vous devriez mettre à jour votre manuel (et votre compilateur) et vous efforcer de vous rappeler que l'informatique est un domaine en constante évolution sur lequel vous devez garder une longueur d'avance pour rivaliser ... Assez parlé de cela, cependant; voyons quels autres secrets non portables stockent ces octets entiers sous-jacents ...Les bits de valeur sont ce que les idées fausses courantes semblent compter. L'exemple ci-dessus utilise un
unsigned
type entier qui ne contient généralement que des bits de valeur, il est donc facile de rater le diable dans les détails.Bits de signe ... Dans l'exemple ci-dessus, j'ai cité
UINT_MAX
la limite supérieureunsigned int
car c'est un exemple trivial pour extraire la valeur16
du commentaire. Pour les types signés, afin de faire la distinction entre les valeurs positives et négatives (c'est le signe), nous devons également inclure le bit de signe.Bits de remplissage ... Bien qu'il soit rare de rencontrer des ordinateurs qui ont des bits de remplissage en nombres entiers, la norme C permet que cela se produise; certaines machines (c'est-à - dire celle-ci ) implémentent des types d'entiers plus grands en combinant deux valeurs entières plus petites (signées) ensemble ... et lorsque vous combinez des entiers signés, vous obtenez un bit de signe perdu. Ce bit gaspillé est considéré comme du remplissage en C. D'autres exemples de bits de remplissage peuvent inclure des bits de parité et des bits d'interruption .
Comme vous pouvez le voir, la norme semble encourager la prise en compte de plages telles que
INT_MIN
..INT_MAX
et d' autres valeurs minimales / maximales de la norme lors du choix des types d'entiers, et déconseille de s'appuyer sur les tailles car il y a d'autres facteurs subtils susceptibles d'être oubliés tels que lesCHAR_BIT
bits de remplissage qui pourrait affecter la valeur desizeof (int)
(c'est-à-dire que les idées fausses courantes sur les entiers à deux et quatre octets négligent ces détails).la source
Projet standard C99 N1256
http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf
La taille de
int
et tous les autres types d'entiers sont définis par l'implémentation, C99 spécifie uniquement:5.2.4.2.1 "Tailles des types entiers
<limits.h>
" donne les tailles minimales:6.2.5 "Types" dit alors:
et 6.3.1.1 "Booléen, caractères et entiers" détermine les rangs de conversion relatifs:
la source
Les seules garanties sont que
char
doivent être au moins 8 bits de large,short
etint
doit être au moins 16 bits de large etlong
doit être au moins 32 bits de large, et quesizeof (char)
<=sizeof (short)
<=sizeof (int)
<=sizeof (long)
(est 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.la source
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
char
et également appelée "octet" , a exactement uneCHAR_BIT
largeur de bits, oùCHAR_BIT
est au moins 8.Ainsi, un octet en C n'est pas forcément 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 4 octets
int
- mais au totalint
avait 36 bits, carCHAR_BIT
c'était 9!int
est censé être la taille entière naturelle de la plate-forme dont la plage est d' au moins-32767 ... 32767
. Vous pouvez obtenir la taille desint
octets de la plate-forme avecsizeof(int)
; lorsque vous multipliez cette valeur parCHAR_BIT
vous saurez quelle est sa largeur en bits.Alors que les machines 36 bits sont pour la plupart 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 des octets 16 bits , qui a un compilateur compatible C99, C11.
Sur TMS320C28x, il semble que
char
,short
etint
sont tous de 16 bits de large, et donc un octet.long int
est de 2 octets et delong long int
4 octets. La beauté de C est que l'on peut toujours écrire un programme efficace pour une plate-forme comme celle-ci, et même le faire de manière portable!la source
Cela dépend principalement de la plate-forme que vous utilisez. Cela dépend d'un compilateur à l'autre. De nos jours, dans la plupart des compilateurs, int est de 4 octets . Si vous voulez vérifier ce que votre compilateur utilise, vous pouvez utiliser
sizeof(int)
.La seule chose promis par le compilateur c 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.Si la taille de int est 4, alors la taille de short peut être 2 ou 4 mais pas plus que cela est vrai pour long et int. Il dit également que la taille du court et du long ne peut pas être la même.
la source
%d
pour unsize_t
paramètre est UB.Cela dépend de l'implémentation, mais généralement sur x86 et d'autres architectures populaires comme les ARM
int
prennent 4 octets. Vous pouvez toujours vérifier au moment de la compilation en utilisantsizeof(int)
ou tout autre type que vous souhaitez vérifier.Si vous voulez vous assurer d'utiliser un type d'une taille spécifique, utilisez les types dans
<stdint.h>
la source
Cela renvoie 4, mais cela dépend probablement de la machine.
la source
C permet aux "octets" d'être autre chose que 8 bits par "octet".
Une valeur supérieure à 8 est de plus en plus rare. Pour une portabilité maximale, utilisez
CHAR_BIT
plutôt que 8. La taille d'unint
en bits en C estsizeof(int) * CHAR_BIT
.La
int
taille en bits est généralement de 32 ou 16 bits. C plages minimales spécifiées :La plage minimale pour
int
force la taille de bits à 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 comme 18, 24, 36, etc. se sont produites sur des plates-formes historiques ou sont au moins théoriquement possibles. Le codage moderne s'inquiète rarementint
des tailles de bits autres que la puissance de 2 .Le processeur et l'architecture de l'
int
ordinateur déterminent la sélection de la taille en bits.Pourtant, même avec des processeurs 64 bits, la
int
taille du compilateur peut être de 32 bits pour des raisons de compatibilité car les bases de code volumineuses dépendent du formatint
32 bits (ou 32/16).la source
C'est une bonne source pour répondre à cette question.
Mais cette question est une sorte de toujours vérité répondant «Oui. Les deux».
Cela dépend de votre architecture. Si vous comptez travailler sur une machine 16 bits ou moins, cela ne peut pas être 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 à produire 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 cela avec des tableaux.
Si vous déclarez,
int t[12];
il renverra 12 * 4 octets. Pour obtenir la longueur de ce tableau, utilisez simplementsizeof(t)/sizeof(t[0])
. Si vous allez créer une fonction, qui devrait calculer la taille d'un tableau d'envoi, rappelez-vous que siDonc, 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 n'est qu'un pointeur sur le premier élément. Mais dans le cas un, vous savez toujours quelle taille votre tableau a. Le cas deux peut être résolu en définissant deux fonctions et en manquant certaines performances. Définissez la fonction (tableau t) et définissez la fonction2 (tableau t, int size_of_t). Appelez "function (t)", mesurez la longueur par un travail de copie et envoyez le résultat à function2, où vous pouvez faire ce que vous voulez sur des tableaux de tailles variables.
la source
char
toujourssigned
)