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 sizeof
operador 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_BIT
representaçã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 sizeof
operador 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_BIT
informa 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_BIT
fosse 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_BIT
també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 int
requer que o padrão exija (pelo menos) dezesseis bits de armazenamento:
UINT_MAX 65535 // 2¹⁶ - 1
Assim, podemos ver que unsigned int
exigem ( 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 unsigned
tipo 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_MAX
como sendo o limite superior unsigned int
porque é um exemplo trivial extrair o valor 16
do 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_MAX
e 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_BIT
bits 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).