La dimensione di C "int" è 2 byte o 4 byte?


169

Una variabile Integer in C occupa 2 byte o 4 byte? Quali sono i fattori da cui dipende?

La maggior parte dei libri di testo afferma che le variabili intere occupano 2 byte. Ma quando eseguo un programma che stampa gli indirizzi successivi di una matrice di numeri interi mostra la differenza di 4.



1
intè solo uno dei numerosi tipi interi . Hai chiesto informazioni sulla dimensione di "numero intero"; probabilmente intendevi chiedere le dimensioni di int.
Keith Thompson,

3
E dovresti trovare libri di testo migliori. Un libro di testo che dice che intè 2 byte (a) probabilmente fa riferimento a un vecchio sistema e (b) non riesce a chiarire che la dimensione varierà da un sistema all'altro. Il miglior libro su C è "Il linguaggio di programmazione C" di Kernighan e Ritchie, sebbene presupponga una certa esperienza di programmazione. Vedere anche domanda 18.10 del comp.lang.c FAQ .
Keith Thompson,

2
Prova #define int int64_tsu una piattaforma a 64 bit, quindi nessuno dei due. Basta usare sizeof. ;-)
netcoder

Risposte:


183

So che è uguale a sizeof(int). La dimensione di an intdipende dal compilatore. In passato, quando i processori erano a 16 bit, un tempo intera di 2 byte. Al giorno d'oggi, è spesso 4 byte su sistemi a 32 e 64 bit.

Tuttavia, l'utilizzo sizeof(int)è il modo migliore per ottenere la dimensione di un numero intero per il sistema specifico su cui viene eseguito il programma.

EDIT: corretta l'istruzione errata di int8 byte sulla maggior parte dei sistemi a 64 bit. Ad esempio, sono 4 byte su GCC a 64 bit.


31
@RajivPrathap: Beh, dipende dal compilatore, ma il compilatore decide se dipende anche dalla macchina. :)
user541686

2
Se hai bisogno delle dimensioni per il preproccesor, puoi controllare le macro predefinite come INT_MAX. Se il valore non è quello atteso dal tuo codice, la dimensione in byte di int è diversa sulla combinazione compilatore / piattaforma corrente.
Walt Sellers,

3
Non solo dipendente dalla macchina, dipende anche dal sistema operativo in esecuzione sulla macchina. Ad esempio, long in Win64 è 4 byte mentre long in Linux64 è 8 byte.
Cem Kalyoncu,

9
sbagliato. sulla maggior parte dei sistemi a 64 bit int è ancora 4 byte en.wikipedia.org/wiki/64-bit_computing#64-bit_data_models
phuclv

7
sizeof(int)può essere qualsiasi valore da 1. Non è necessario che un byte sia 8 bit e alcune macchine non hanno un'unità indirizzabile a 8 bit (che sostanzialmente è la definizione di un byte nello standard). La risposta non è corretta senza ulteriori informazioni.
troppo onesto per questo sito il

103

Questo è uno dei punti in C che può inizialmente essere fonte di confusione, ma lo standard C specifica solo un intervallo minimo per i tipi interi che è garantito essere supportato. intè garantito per essere in grado di contenere da -32767 a 32767, che richiede 16 bit. In tal caso int, è di 2 byte. Tuttavia, le implementazioni sono libere di andare oltre questo minimo, poiché vedrai che molti compilatori moderni effettuano int32 bit (il che significa anche 4 byte in modo abbastanza diffuso).

Il motivo per cui il tuo libro dice 2 byte è molto probabilmente perché è vecchio. Un tempo, questa era la norma. In generale, dovresti sempre usare l' sizeofoperatore se devi scoprire quanti byte è sulla piattaforma che stai utilizzando.

Per risolvere questo problema, C99 ha aggiunto nuovi tipi in cui è possibile richiedere esplicitamente un numero intero di determinate dimensioni, ad esempio int16_to int32_t. Prima di ciò, non esisteva un modo universale per ottenere un numero intero di una larghezza specifica (sebbene la maggior parte delle piattaforme fornisse tipi simili su una base per piattaforma).


7
@nevanking: su una macchina per complementi a due (che è ogni macchina che conosco ...), sì. Ma C non garantisce che sia così.
Errore fatale

@nevanking Sono completamente nuovo in C, ma non è 32767 perché altrimenti userebbe un altro bit | byte? Immagina, posso contenere 3 cifre (0 o 1), quindi posso passare da 000 a 111 (che è il decimale 7). 7 è giusto prima di un esponente di 2. Se potessi andare fino a 8 (1000), allora potrei usare quelle 4 cifre fino a 15! Come 32767 è giusto prima di un esponente di 2, esaurendo tutti i bit | byte che ha a disposizione.
RGS,

3
@RSerrao Non sono neanche un esperto in C ma AFAIK per i numeri positivi è uno in meno del numero massimo negativo. Quindi da -8 a 7, da -256 a 255 e così via. I numeri negativi non devono contare lo zero.
re nevan,

1
"16 bit. In tal caso, int, è 2 byte" può essere errato, se CHAR_BIT è 16, sizeof (int) può essere 1 byte (o char).
12431234123412341234123

6
@nevanking: solo se si assume la rappresentazione del complemento di 2 per firmata int. C non fa questa ipotesi. I sistemi di complemento e grandezza dei segni di 1 non possono rappresentare -32768in 16 bit; piuttosto, hanno due rappresentazioni per zero (positivo e negativo). Ecco perché l'intervallo minimo per un intè [-32767..32767].
John Bode,

33

Non esiste una risposta specifica. Dipende dalla piattaforma. È definito dall'implementazione. Può essere 2, 4 o qualcos'altro.

L'idea alla base intera che doveva corrispondere alla dimensione naturale della "parola" sulla piattaforma data: 16 bit su piattaforme a 16 bit, 32 bit su piattaforme a 32 bit, 64 bit su piattaforme a 64 bit, si ottiene l'idea. Tuttavia, ai fini della compatibilità con le versioni precedenti alcuni compilatori preferiscono attenersi a 32 bit intanche su piattaforme a 64 bit.

Il tempo di 2 byte int è passato da tempo (piattaforme a 16 bit?) A meno che non si stia utilizzando una piattaforma incorporata con dimensioni delle parole a 16 bit. I tuoi libri di testo sono probabilmente molto vecchi.


2
The idea behind int was that it was supposed to match the natural "word" size on the given platform- Questo è quello che stavo cercando. Qualche idea su quale possa essere la ragione? In un mondo libero, int potrebbe occupare un numero qualsiasi di byte consecutivi nella memoria, giusto? 8, 16 qualunque cosa
bholagabbar

19

La risposta a questa domanda dipende dalla piattaforma che stai utilizzando.
Ma indipendentemente dalla piattaforma, puoi assumere in modo affidabile i seguenti tipi:

 [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

3
Qualcuno ha modificato il tuo post per "correggere" gli intervalli, ma non sono sicuro che la tua modifica rifletta adeguatamente le tue intenzioni. Presuppone un'implementazione del complemento a due, che sarà vera nella maggior parte dei casi, ma non in tutti. Poiché la tua risposta indica in modo specifico la dipendenza dall'implementazione, penso che la modifica sia probabilmente sbagliata. Se sei d'accordo, assicurati di ripristinare la modifica.
Cody Grey

1
@ k06a la modifica non è corretta . Hai modificato in modo specifico gli intervalli originali in intervalli a 2 complementi: questi non sono quelli specificati nello standard C.
Antti Haapala,

@CodyGray questo ha fluttuato avanti e indietro, essendo stato il complemento di 1 conforme per gli ultimi 3 anni e OP non ha detto nulla, quindi ho ripristinato una modifica che l'ha cambiata in complemento di 2 con "intervalli di correzione", poiché dice "puoi assumere in modo affidabile" , che non è ancora esattamente vero.
Antti Haapala,

13

Una variabile Integer in C occupa 2 byte o 4 byte?

Dipende dalla piattaforma che stai utilizzando e dalla configurazione del tuo compilatore. L'unica risposta autorevole è usare l' sizeofoperatore per vedere quanto è grande un numero intero nella tua situazione specifica.


Quali sono i fattori da cui dipende?

L'intervallo potrebbe essere considerato meglio, piuttosto che la dimensione . Entrambi varieranno in pratica, anche se è molto più semplice scegliere tipi variabili per intervallo rispetto alle dimensioni, come vedremo. È anche importante notare che lo standard ci incoraggia a considerare la scelta dei nostri tipi di numeri interi in base all'intervallo piuttosto che alle dimensioni , ma per ora ignoriamo la pratica standard e lasciamo che la nostra curiosità esplori sizeof, byte e CHAR_BITe rappresentazione di interi ... scaviamo la tana del coniglio e vederlo da soli ...


sizeof, byte e CHAR_BIT

La seguente dichiarazione, presa dallo standard C (collegato sopra), descrive questo in parole che non credo possano essere migliorate.

L' sizeofoperatore fornisce la dimensione (in byte) del suo operando, che può essere un'espressione o il nome tra parentesi di un tipo. La dimensione è determinata dal tipo di operando.

Supponendo una chiara comprensione ci condurrà a una discussione sui byte . Si presume comunemente che un byte sia di otto bit, quando in realtà CHAR_BITindica quanti bit sono in un byte . Questa è solo un'altra di quelle sfumature che non vengono prese in considerazione quando si parla dei numeri interi a due (o quattro) byte comuni .

Finiamo le cose finora:

  • sizeof => dimensione in byte e
  • CHAR_BIT => numero di bit in byte

Pertanto, a seconda del sistema in uso, sizeof (unsigned int)potrebbe essere qualsiasi valore maggiore di zero (non solo 2 o 4), come se CHAR_BITfosse 16, quindi un singolo byte (sedici bit) contiene abbastanza bit per rappresentare il numero intero a sedici bit descritto dal standard (citati di seguito). Non sono necessariamente informazioni utili, vero? Analizziamo più a fondo ...


Rappresentazione intera

Previsto dalla norma C minimo precisione / gamma per tutti i tipi standard interi (e CHAR_BIT, anche, FWIW) qui . Da questo, possiamo ricavare un minimo per quanti bit sono necessari per memorizzare il valore , ma possiamo anche semplicemente scegliere le nostre variabili in base agli intervalli . Tuttavia, gran parte dei dettagli richiesti per questa risposta risiede qui. Ad esempio, quanto segue che lo standard unsigned intrichiede (almeno) sedici bit di memoria:

UINT_MAX                                65535 // 2¹⁶ - 1

Quindi possiamo vedere che unsigned intrichiedono ( almeno ) 16 bit , che è dove si ottengono i due byte (supponendo che CHAR_BITsia 8) ... e in seguito quando il limite è aumentato a 2³² - 1, le persone hanno invece dichiarato 4 byte. Questo spiega i fenomeni che hai osservato:

La maggior parte dei libri di testo afferma che le variabili intere occupano 2 byte. Ma quando eseguo un programma che stampa gli indirizzi successivi di una matrice di numeri interi mostra la differenza di 4.

Stai usando un antico libro di testo e un compilatore che ti insegna C non portatile; l'autore che ha scritto il tuo libro di testo potrebbe non esserne nemmeno a conoscenza CHAR_BIT. Si consiglia di aggiornare il proprio libro di testo (e compilatore), e si sforzano di ricordare che si tratta di un campo in continua evoluzione che è necessario rimanere davanti a competere ... Basta parlare di questo, però; vediamo quali altri segreti non portatili memorizzano quei byte interi sottostanti ...

I bit di valore sono ciò che le idee sbagliate comuni sembrano contare. L'esempio sopra usa un unsignedtipo intero che in genere contiene solo bit di valore, quindi è facile perdere il diavolo nei dettagli.

Bit di segno ... Nell'esempio sopra ho citato UINT_MAXcome limite massimo unsigned intperché è un esempio banale estrarre il valore 16dal commento. Per i tipi con segno, al fine di distinguere tra valori positivi e negativi (questo è il segno), dobbiamo includere anche il bit del segno.

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

Bit di riempimento ... Sebbene non sia comune incontrare computer con bit di riempimento in numeri interi, lo standard C consente che ciò accada; alcune macchine (cioè questa ) implementano tipi di numeri interi più grandi combinando insieme due valori di numeri interi (con segno) più piccoli ... e quando si combinano numeri interi con segno, si ottiene un bit di segno sprecato. Quel bit sprecato è considerato riempimento in C. Altri esempi di bit di riempimento potrebbero includere bit di parità e bit trap .


Come puoi vedere, lo standard sembra incoraggiare a considerare intervalli come INT_MIN... INT_MAXe altri valori minimi / massimi rispetto allo standard quando si scelgono tipi interi e scoraggia il ricorso alle dimensioni in quanto vi sono altri fattori sottili che potrebbero essere dimenticati come CHAR_BITe bit di riempimento che potrebbe influire sul valore di sizeof (int)(ovvero le idee sbagliate comuni degli interi a due e quattro byte trascurano questi dettagli).


13

Tiraggio standard C99 N1256

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

Le dimensioni di inte tutti gli altri tipi di numeri interi sono definiti dall'implementazione, C99 specifica solo:

  • garanzie di dimensioni minime
  • dimensioni relative tra i tipi

5.2.4.2.1 "Dimensioni dei tipi interi <limits.h>" indica le dimensioni minime:

1 [...] I loro valori definiti dall'implementazione devono essere uguali o maggiori in grandezza (valore assoluto) a quelli mostrati [...]

  • 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 "Tipi" quindi dice:

8 Per due tipi di numeri interi con lo stesso segno e diverso rango di conversione di numeri interi (vedere 6.3.1.1), l'intervallo di valori del tipo con rango di conversione di numeri interi più piccoli è una sottorange dei valori dell'altro tipo.

e 6.3.1.1 "Booleani, caratteri e numeri interi" determinano i gradi di conversione relativi:

1 Ogni tipo intero ha un rango di conversione intero definito come segue:

  • Il rango di long long int deve essere maggiore del rango di long int, che deve essere maggiore del rango di int, che deve essere maggiore del rango di short int, che deve essere maggiore del rango di char firmato.
  • Il rango di qualsiasi tipo intero senza segno deve essere uguale al rango del tipo intero con segno corrispondente, se presente.
  • Per tutti i tipi interi T1, T2 e T3, se T1 ha un rango maggiore di T2 e T2 ha un rango maggiore di T3, allora T1 ha un rango maggiore di T3

8

Le uniche garanzie sono che chardeve essere almeno di 8 bits, shorte intdeve essere almeno a 16 bit, e longdeve essere almeno larghe 32 bit, e che sizeof (char)<= sizeof (short)<= sizeof (int)<= sizeof (long)(lo stesso vale per le versioni non firmate di questi tipi ).

int può essere largo da 16 a 64 bit in base alla piattaforma.


6

La dimensione di C "int" è 2 byte o 4 byte?

La risposta è "sì" / "no" / "forse" / "forse no".

Il linguaggio di programmazione C specifica quanto segue: l'unità indirizzabile più piccola, conosciuta chare chiamata anche "byte" , è esattamente CHAR_BITlarga bit, doveCHAR_BIT sono almeno 8.

Quindi, un byte in C non è necessariamente un ottetto , cioè 8 bit. In passato una delle prime piattaforme per eseguire il codice C (e Unix) aveva 4 byte int- ma in totale intaveva 36 bit, perché CHAR_BITera 9!

intdovrebbe essere la dimensione intera naturale per la piattaforma che ha un intervallo di almeno-32767 ... 32767 . È possibile ottenere la dimensione di intnei byte della piattaforma con sizeof(int); quando moltiplichi questo valore per CHAR_BITsaprai quanto è largo in bit.


Mentre le macchine a 36 bit sono per lo più morte, ci sono ancora piattaforme con byte non a 8 bit. Proprio ieri c'era una domanda su un MCU Texas Instruments con byte a 16 bit , che ha un compilatore C99, conforme a C11.

Su TMS320C28x sembra che char, shorte intsono tutti 16 bit di larghezza, e quindi un byte. long intè 2 byte ed long long intè 4 byte. Il bello di C è che si può ancora scrivere un programma efficiente per una piattaforma come questa, e persino farlo in modo portatile!


"perché CHAR_BIT aveva 9 anni!" - All'epoca avevano un calcolo a 362880 bit !? Degno di nota.
Josh Desmond,

5

Principalmente dipende dalla piattaforma che stai usando. Dipende da compilatore a compilatore. Oggi nella maggior parte dei compilatori int è di 4 byte . Se vuoi controllare cosa sta usando il tuo compilatore, puoi usarlo sizeof(int).

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

L'unica cosa che promette il compilatore è che la dimensione di short deve essere uguale o inferiore a int e la dimensione di long deve essere uguale o maggiore di int. Quindi se la dimensione di int è 4, la dimensione di short può essere 2 o 4 ma non più grande di quello. Lo stesso è vero per lungo e int. Dice anche che la dimensione di corto e lungo non può essere la stessa.


1
L'utilizzo %dper un size_tparametro è UB.
Paul R,

3

Questo dipende dall'implementazione, ma di solito su x86 e altre architetture popolari come ARM ints occupano 4 byte. Puoi sempre controllare in fase di compilazione usando sizeof(int)o qualunque altro tipo tu voglia controllare.

Se vuoi assicurarti di usare un tipo di una dimensione specifica, usa i tipi in <stdint.h>


2
#include <stdio.h>

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

Questo restituisce 4, ma probabilmente dipende dalla macchina.


1

La dimensione di C "int" è 2 byte o 4 byte?

Una variabile Integer in C occupa 2 byte o 4 byte?

C consente a "byte" di essere qualcosa di diverso da 8 bit per "byte".

CHAR_BIT numero di bit per l'oggetto più piccolo che non è un campo di bit (byte) C11dr §5.2.4.2.1 1

Un valore di qualcosa di 8 è sempre più raro. Per la massima portabilità, utilizzare CHAR_BITanziché 8. La dimensione di un intin bit in C è sizeof(int) * CHAR_BIT.

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

Quali sono i fattori da cui dipende?

La intdimensione dei bit è generalmente di 32 o 16 bit. C intervalli minimi specificati :

valore minimo per un oggetto di tipo int INT_MIN-32767
valore massimo per un oggetto di tipo int INT_MAX+32767
C11dr §5.2.4.2.1 1

L' intervallo minimo per intimpone che la dimensione del bit sia almeno 16, anche se il processore era "8 bit". Una dimensione come 64 bit è vista in processori specializzati. Altri valori come 18, 24, 36, ecc. Si sono verificati su piattaforme storiche o sono almeno teoricamente possibili. La codifica moderna raramente si preoccupa della non potenza di 2int bit.

Il processore e l'architettura del computer guidano la intselezione della dimensione dei bit.

Tuttavia, anche con processori a 64 bit, la intdimensione del compilatore può essere a 32 bit per motivi di compatibilità poiché le basi di codice di grandi dimensioni dipendono intdall'essere a 32 bit (o 32/16).


-1

Questa è una buona fonte per rispondere a questa domanda.

Ma questa domanda è una specie di verità sempre rispondente "Sì. Entrambi".

Dipende dalla tua architettura. Se hai intenzione di lavorare su una macchina a 16 bit o inferiore, non può essere di 4 byte (= 32 bit). Se stai lavorando su una macchina a 32 bit o migliore, la sua lunghezza è di 32 bit.

Per capire, prepara il programma per produrre qualcosa di leggibile e usa la funzione "sizeof". Ciò restituisce la dimensione in byte del tipo di dati dichiarato. Ma stai attento usando questo con array.

Se lo stai dichiarando int t[12];, restituirà 12 * 4 byte. Per ottenere la lunghezza di questo array, basta usare sizeof(t)/sizeof(t[0]). Se hai intenzione di creare una funzione, che dovrebbe calcolare la dimensione di un array di invio, ricorda che if

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. 
}

Quindi questo non restituirà nemmeno qualcosa di diverso. Se si definisce un array e si cerca di ottenere la lunghezza in seguito, utilizzare sizeof. Se si invia un array a una funzione, ricordare che il valore di invio è solo un puntatore sul primo elemento. Ma nel primo caso, sai sempre, che dimensione ha il tuo array. Il secondo caso può essere capito definendo due funzioni e perdendo alcune prestazioni. Definire la funzione (matrice t) e definire la funzione2 (matrice t, int size_of_t). Chiamare "function (t)" misura la lunghezza di un lavoro di copiatura e invia il risultato a function2, dove puoi fare quello che vuoi su array di dimensioni variabili.


Il link fornito è una cattiva fonte di informazioni perché presuppone cose che non sono sempre vere (ad es. Lo charè sempre signed)
Andrei Damian-Fekete,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.