O tamanho de C “int” é de 2 ou 4 bytes?

169

Uma variável inteira em C ocupa 2 bytes ou 4 bytes? Quais são os fatores de que depende?

A maioria dos livros diz que variáveis ​​inteiras ocupam 2 bytes. Mas quando executo um programa que imprime os endereços sucessivos de uma matriz de números inteiros, ele mostra a diferença de 4.

Rajiv Prathap
fonte
6
en.wikipedia.org/wiki/…
Evan Mulawski
1
inté apenas um dos vários tipos inteiros . Você perguntou sobre o tamanho de "número inteiro"; você provavelmente quis perguntar sobre o tamanho de int.
21412 Keith Thompson
3
E você deve encontrar livros melhores. Um livro que diz que inté de 2 bytes (a) provavelmente se refere a um sistema antigo e (b) falha ao deixar claro que o tamanho varia de um sistema para outro. O melhor livro sobre C é "The C Programming Language", de Kernighan e Ritchie, apesar de assumir alguma experiência em programação. Veja também questionar 18.10 do FAQ comp.lang.c .
21412 Keith Thompson
2
Tente #define int int64_tem uma plataforma de 64 bits, então também não. Apenas use sizeof. ;-)
netcoder

Respostas:

183

Eu sei que é igual a sizeof(int). O tamanho de um inté realmente dependente do compilador. Naquela época, quando os processadores tinham 16 bits, um intera 2 bytes. Atualmente, costuma ter 4 bytes em sistemas de 32 bits e de 64 bits.

Ainda assim, usar sizeof(int)é a melhor maneira de obter o tamanho de um número inteiro para o sistema específico em que o programa é executado.

EDIT: Corrigida afirmação errada de int8 bytes na maioria dos sistemas de 64 bits. Por exemplo, são 4 bytes no GCC de 64 bits.

yhyrcanus
fonte
31
@RajivPrathap: Bem, depende do compilador, mas o compilador decide se é ou não dependente da máquina. :)
user541686
2
Se você precisar do tamanho do pré-processador, poderá verificar as macros predefinidas, como INT_MAX. Se o valor não for o esperado pelo seu código, o tamanho de byte de int será diferente na combinação atual de compilador / plataforma.
Walt Sellers
3
Não depende apenas da máquina, mas também do sistema operacional em execução na máquina. Por exemplo, o comprimento no Win64 é de 4 bytes, enquanto o comprimento no Linux64 é de 8 bytes.
Cem Kalyoncu 10/01
9
errado. na maioria dos sistemas de 64 bits, o int ainda possui 4 bytes pt.wikipedia.org/wiki/64-bit_computing#64-bit_data_models
phuclv
7
sizeof(int)pode ser qualquer valor de 1. Um byte não precisa ter 8 bits e algumas máquinas não possuem uma unidade endereçável de 8 bits (que basicamente é a definição de um byte no padrão). A resposta não está correta sem mais informações.
muito honesto para este site
103

Esse é um dos pontos em C que pode ser confuso no início, mas o padrão C especifica apenas um intervalo mínimo para tipos inteiros que são garantidos como suportados. inté garantido para poder manter -32767 a 32767, o que requer 16 bits. Nesse caso int,, é de 2 bytes. No entanto, as implementações são livres para ir além desse mínimo, pois você verá que muitos compiladores modernos produzem int32 bits (o que também significa 4 bytes de maneira bastante onipresente).

O motivo pelo qual o livro diz 2 bytes provavelmente é porque é antigo. Ao mesmo tempo, essa era a norma. Em geral, você sempre deve usar o sizeofoperador se precisar descobrir quantos bytes estão na plataforma que está usando.

Para resolver isso, o C99 adicionou novos tipos onde você pode solicitar explicitamente um determinado número inteiro de tamanho, por exemplo int16_tou int32_t. Antes disso, não havia uma maneira universal de obter um número inteiro de uma largura específica (embora a maioria das plataformas fornecesse tipos semelhantes por plataforma).

Erro fatal
fonte
7
@evanking: Na máquina de complemento de dois (que é toda máquina que eu conheço ...), sim. Mas C não garante que seja o caso.
FatalError
@nevanking Eu sou completamente novo em C, mas não é 32767 porque, caso contrário, estaria usando outro bit | byte? Imagine, eu posso conter 3 dígitos (0 ou 1), para que eu possa ir de 000 a 111 (que é 7 decimal). 7 está logo antes de um expoente de 2. Se eu pudesse ir até 8 (1000), eu poderia usar esses 4 dígitos até 15! Tal como 32767 está logo antes de um expoente de 2, esgotando todos os bits | bytes disponíveis.
RGS 15/07
3
@RSerrao Também não sou especialista em C, mas AFAIK para números positivos é um a menos que o número máximo negativo. Então -8 a 7, -256 a 255 e assim por diante. Números negativos não precisam contar o zero.
Nevan king
1
"16 bits. Nesse caso, int, é 2 bytes" pode estar errado, se CHAR_BIT for 16, sizeof (int) pode ter 1 byte (ou char).
12431234123412341234123
6
@evanking: somente se você assumir a representação do complemento de 2 para assinado int. C não faz essa suposição. Os sistemas de complemento e magnitude de sinal de 1 não podem representar -32768em 16 bits; em vez disso, eles têm duas representações para zero (positivo e negativo). É por isso que o intervalo mínimo para um inté [-32767..32767].
John Bode
33

Não há resposta específica. Depende da plataforma. É definido pela implementação. Pode ser 2, 4 ou outra coisa.

A idéia por trás intdisso era que ela deveria corresponder ao tamanho natural da "palavra" na plataforma fornecida: 16 bits em plataformas de 16 bits, 32 bits em plataformas de 32 bits, 64 bits em plataformas de 64 bits, você entendeu. No entanto, para fins de compatibilidade com versões anteriores, alguns compiladores preferem manter os de 32 bits, intmesmo em plataformas de 64 bits.

O tempo de 2 bytes intjá passou muito tempo (plataformas de 16 bits?), A menos que você esteja usando alguma plataforma incorporada com tamanho de palavra de 16 bits. Seus livros didáticos provavelmente são muito antigos.

Formiga
fonte
2
The idea behind int was that it was supposed to match the natural "word" size on the given platform- Era isso que eu estava procurando. Alguma idéia de qual seja o motivo? Em um mundo livre, int poderia ocupar qualquer número de bytes consecutivos na memória, certo? 8, 16 qualquer que seja
bholagabbar
19

A resposta a esta pergunta depende de qual plataforma você está usando.
Mas, independentemente da plataforma, você pode assumir com segurança os seguintes tipos:

 [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
Priyank Arora
fonte
3
Alguém editou sua postagem para "corrigir" os intervalos, mas não tenho certeza se a sua edição reflete adequadamente sua intenção. Ele pressupõe a implementação do complemento de dois, o que será verdadeiro na maioria dos casos, mas não em todos. Como sua resposta aponta especificamente a dependência da implementação, acho que a edição provavelmente está errada. Se você concordar, revise a edição.
Cody Gray
1
@ k06a sua edição estava incorreta . Você alterou especificamente os intervalos originais para intervalos de 2 complementos - esses não são os especificados no padrão C.
Antti Haapala
O @CodyGray está flutuando de um lado para o outro, sendo compatível com o complemento de 1 nos últimos 3 anos e o OP não dizendo nada, então eu reverti uma edição que o alterou para complemento de 2 com "intervalos de correção", pois diz "você pode assumir com confiança" , o que ainda não é exatamente verdade.
Antti Haapala
13

Uma variável inteira em C ocupa 2 bytes ou 4 bytes?

Isso depende da plataforma que você está usando, bem como de como o seu compilador está configurado. A única resposta autorizada é usar o sizeofoperador para ver o tamanho de um número inteiro na sua situação específica.


Quais são os fatores de que depende?

É melhor considerar o intervalo , em vez do tamanho . Ambos variarão na prática, embora seja muito mais seguro escolher tipos de variáveis ​​por faixa do que tamanho, como veremos. Também é importante observar que o padrão nos incentiva a considerar a escolha de nossos tipos inteiros com base no intervalo e não no tamanho , mas por enquanto vamos ignorar a prática padrão e deixar nossa curiosidade explorar sizeof, bytes e CHAR_BITrepresentação de números inteiros ... a toca do coelho e ver por nós mesmos ...


sizeof, bytes e CHAR_BIT

A declaração a seguir, tirada do padrão C (vinculado acima), descreve isso em palavras que eu acho que não podem ser melhoradas.

O sizeofoperador gera o tamanho (em bytes) de seu operando, que pode ser uma expressão ou o nome entre parênteses de um tipo. O tamanho é determinado a partir do tipo do operando.

Assumir um entendimento claro nos levará a uma discussão sobre bytes . É comum presumir que um byte tem oito bits, quando na verdade CHAR_BITinforma quantos bits há em um byte . Essa é apenas mais uma daquelas nuances que não são consideradas quando se fala dos inteiros comuns de dois (ou quatro) bytes .

Vamos encerrar as coisas até agora:

  • sizeof => tamanho em bytes e
  • CHAR_BIT => número de bits em byte

Portanto, dependendo do seu sistema, sizeof (unsigned int)pode haver qualquer valor maior que zero (não apenas 2 ou 4), como se CHAR_BITfosse 16, então um único byte (dezesseis bits) possui bits suficientes para representar o número inteiro de dezesseis bits descrito pelo padrões (citados abaixo). Isso não é necessariamente uma informação útil, é? Vamos nos aprofundar mais ...


Representação inteira

O padrão C especifica a precisão / intervalo mínimo para todos os tipos de números inteiros padrão (e CHAR_BITtambém fwiw) aqui . A partir disso, podemos derivar um mínimo para quantos bits são necessários para armazenar o valor , mas também podemos escolher nossas variáveis ​​com base nos intervalos . No entanto, grande parte dos detalhes necessários para esta resposta reside aqui. Por exemplo, o seguinte unsigned intrequer que o padrão exija (pelo menos) dezesseis bits de armazenamento:

UINT_MAX                                65535 // 2¹⁶ - 1

Assim, podemos ver que unsigned intexigem ( pelo menos ) 16 bits , que é onde você obtém os dois bytes (assumindo que CHAR_BITé 8) ... e mais tarde, quando esse limite aumentou para 2³² - 1, as pessoas estavam declarando 4 bytes. Isso explica os fenômenos que você observou:

A maioria dos livros diz que variáveis ​​inteiras ocupam 2 bytes. Mas quando executo um programa que imprime os endereços sucessivos de uma matriz de números inteiros, ele mostra a diferença de 4.

Você está usando um livro antigo e um compilador que ensina C não portátil; o autor que escreveu seu livro pode nem estar ciente CHAR_BIT. Você deve atualizar seu livro (e compilador) e se esforçar para lembrar que a TI é um campo em constante evolução e que você precisa ficar à frente para competir ... Porém, basta; vamos ver quais outros segredos não portáteis esses bytes inteiros subjacentes armazenam ...

Os bits de valor são o que os equívocos comuns parecem contar. O exemplo acima usa um unsignedtipo inteiro que normalmente contém apenas bits de valor, por isso é fácil perder o diabo nos detalhes.

Assinar bits ... No exemplo acima, citei UINT_MAXcomo sendo o limite superior unsigned intporque é um exemplo trivial extrair o valor 16do comentário. Para tipos assinados, para distinguir valores positivos e negativos (esse é o sinal), precisamos incluir também o bit do sinal.

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

Preenchimento de bits ... Embora não seja comum encontrar computadores com bits de preenchimento em números inteiros, o padrão C permite que isso aconteça; algumas máquinas (isto é, esta ) implementam tipos inteiros maiores combinando dois valores inteiros menores (assinados) juntos ... e quando você combina números inteiros assinados, obtém um bit de sinal desperdiçado. Esse bit desperdiçado é considerado preenchimento em C. Outros exemplos de bits de preenchimento podem incluir bits de paridade e bits de trap .


Como você pode ver, o padrão parece encorajar a consideração de intervalos como INT_MIN... INT_MAXe outros valores mínimos / máximos do padrão ao escolher tipos inteiros e desencoraja a dependência de tamanhos, pois existem outros fatores sutis que podem ser esquecidos, como CHAR_BITbits de preenchimento que pode afetar o valor de sizeof (int)(ou seja, os equívocos comuns de números inteiros de dois e quatro bytes ignoram esses detalhes).

Flimzy
fonte
13

Rascunho padrão C99 N1256

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

O tamanho inte todos os outros tipos de números inteiros são definidos por implementação, C99 especifica apenas:

  • garantias de tamanho mínimo
  • tamanhos relativos entre os tipos

5.2.4.2.1 "Tamanhos de tipos inteiros <limits.h>" fornece os tamanhos mínimos:

1 [...] Seus valores definidos para implementação devem ser iguais ou maiores em magnitude (valor absoluto) aos mostrados [...]

  • 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 "Tipos" diz então:

8 Para quaisquer dois tipos de números inteiros com a mesma assinatura e classificação de conversão inteira diferente (consulte 6.3.1.1), o intervalo de valores do tipo com classificação de conversão inteira menor é uma subfaixa dos valores do outro tipo.

e 6.3.1.1 "Boolean, caracteres e números inteiros" determina os graus de conversão relativos:

1 Todo tipo de número inteiro tem uma classificação de conversão de número inteiro definida da seguinte forma:

  • A classificação de long long int deve ser maior que a classificação de long int, que será maior que a classificação de int, que será maior que a classificação de short int, que será maior que a classificação de char assinado.
  • A classificação de qualquer tipo inteiro não assinado deve ser igual à classificação do tipo inteiro assinado assinado, se houver.
  • Para todos os tipos inteiros T1, T2 e T3, se T1 tiver uma classificação maior que T2 e T2 tiver uma classificação maior que T3, T1 terá uma classificação maior que T3
Ciro Santilli adicionou uma nova foto
fonte
8

As únicas garantias são que chardevem ter pelo menos 8 bits de largura shorte intdevem ter pelo menos 16 bits de largura e longdevem ter pelo menos 32 bits de largura e que sizeof (char)<= sizeof (short)<= sizeof (int)<= sizeof (long)(o mesmo vale para as versões não assinadas desses tipos )

int pode ter de 16 a 64 bits de largura, dependendo da plataforma.

John Bode
fonte
6

O tamanho de C “int” é de 2 ou 4 bytes?

A resposta é "sim" / "não" / "talvez" / "talvez não".

A linguagem de programação C especifica o seguinte: a menor unidade endereçável, conhecida por chare também chamada de "byte" , possui exatamente CHAR_BITbits de largura, onde CHAR_BITé pelo menos 8.

Portanto, um byte em C não é necessariamente um octeto , ou seja, 8 bits. No passado, uma das primeiras plataformas a rodar código C (e Unix) tinha 4 bytes int- mas no total inttinha 36 bits, porque CHAR_BITera 9!

inté suposto ser o tamanho inteiro natural da plataforma que tem um alcance de pelo menos-32767 ... 32767 . Você pode obter o tamanho de intnos bytes da plataforma com sizeof(int); quando você multiplicar esse valor CHAR_BIT, saberá a largura em bits.


Enquanto as máquinas de 36 bits estão praticamente inoperantes, ainda existem plataformas com bytes que não são de 8 bits. Ainda ontem, havia uma pergunta sobre um MCU da Texas Instruments com bytes de 16 bits , que possui um compilador compatível com C99, C11.

Em TMS320C28x parece que char, shorte intsão todos os 16 bits de largura, e, portanto, um byte. long inté de 2 bytes e long long inté de 4 bytes. A beleza de C é que ainda é possível escrever um programa eficiente para uma plataforma como essa e até fazê-lo de maneira portátil!

Antti Haapala
fonte
"porque CHAR_BIT tinha 9 anos!" - Eles tinham 362880 bits de computação naquela época !? Impressionante.
Josh Desmond
5

Principalmente depende da plataforma que você está usando. Depende de compilador para compilador. Atualmente, na maioria dos compiladores, int é de 4 bytes . Se você quiser verificar o que seu compilador está usando, você pode usar sizeof(int).

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

A única coisa que a promessa do compilador c é que o tamanho de short deve ser igual ou menor que int e o tamanho de long deve ser igual ou maior que int.Portanto, se o tamanho de int for 4, o tamanho de short poderá ser 2 ou 4, mas não maior O mesmo vale por muito tempo e int. Também diz que tamanho de curto e longo prazo não pode ser o mesmo.

justpraveen
fonte
1
O uso %dde um size_tparâmetro é UB.
Paul R
3

Isso depende da implementação, mas geralmente o x86 e outras arquiteturas populares como ARMs intlevam 4 bytes. Você sempre pode verificar no momento da compilação usando sizeof(int)ou qualquer outro tipo que queira verificar.

Se quiser usar um tipo de tamanho específico, use os tipos em <stdint.h>

slartibartfast
fonte
2
#include <stdio.h>

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

Isso retorna 4, mas provavelmente depende da máquina.

as leis
fonte
1

O tamanho de C “int” é de 2 ou 4 bytes?

Uma variável inteira em C ocupa 2 bytes ou 4 bytes?

C permite que "bytes" sejam algo diferente de 8 bits por "byte".

CHAR_BIT número de bits para o menor objeto que não seja um campo de bits (byte) C11dr §5.2.4.2.1 1

Um valor de algo que 8 é cada vez mais incomum. Para máxima portabilidade, use em CHAR_BITvez de 8. O tamanho de um intem bits em C é sizeof(int) * CHAR_BIT.

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

Quais são os fatores de que depende?

O inttamanho do bit geralmente é de 32 ou 16 bits. C intervalos mínimos especificados :

valor mínimo para um objeto do tipo int INT_MIN-32767
valor máximo para um objeto do tipo int INT_MAX+32767
C11dr §5.2.4.2.1 1

O intervalo mínimo para intforça o tamanho do bit a pelo menos 16 - mesmo que o processador seja "8 bits". Um tamanho de 64 bits é visto em processadores especializados. Outros valores como 18, 24, 36 etc. ocorreram em plataformas históricas ou são pelo menos teoricamente possíveis. A codificação moderna raramente se preocupa com inttamanhos de bit sem potência de 2 .

O processador e a arquitetura do computador conduzem a intseleção de tamanho de bit.

No entanto, mesmo com processadores de 64 bits, o inttamanho do compilador pode ser de 32 bits por motivos de compatibilidade, já que grandes bases de código dependem de int32 bits (ou 32/16).

chux - Restabelecer Monica
fonte
-1

Essa é uma boa fonte para responder a essa pergunta.

Mas essa pergunta é uma espécie de resposta sempre verdadeira "Sim. Ambos".

Depende da sua arquitetura. Se você estiver trabalhando em uma máquina de 16 bits ou menos, não poderá ter 4 bytes (= 32 bits). Se você estiver trabalhando em uma máquina de 32 bits ou superior, seu comprimento será de 32 bits.

Para descobrir, prepare seu programa para produzir algo legível e use a função "sizeof". Isso retorna o tamanho em bytes do seu tipo de dados declarado. Mas tenha cuidado ao usar isso com matrizes.

Se você estiver declarando, int t[12];ele retornará 12 * 4 bytes. Para obter o comprimento dessa matriz, basta usar sizeof(t)/sizeof(t[0]). Se você for criar uma função, que calcule o tamanho de uma matriz de envio, lembre-se de que, se

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

Portanto, isso nem retornará algo diferente. Se você definir uma matriz e tentar obter o comprimento posteriormente, use sizeof. Se você enviar uma matriz para uma função, lembre-se de que o valor de envio é apenas um ponteiro no primeiro elemento. Mas no primeiro caso, você sempre sabe qual é o tamanho da sua matriz. O caso dois pode ser definido definindo duas funções e perdendo algum desempenho. Defina a função (matriz t) e defina a função2 (matriz t, int size_of_t). A chamada "function (t)" mede o comprimento de algumas cópias e envia o resultado para function2, onde você pode fazer o que quiser em tamanhos de matriz variáveis.

Shalec
fonte
O link fornecido é uma má fonte de informação porque assume coisas que nem sempre são verdadeiras (por exemplo, charé sempre signed)
Andrei Damian-Fekete