Qual é a vantagem de usar uint8_t
mais unsigned char
em C?
Eu sei que em quase todos os sistemas uint8_t
é apenas um typedef unsigned char
, então por que usá-lo?
Ele documenta sua intenção - você armazenará pequenos números, em vez de um personagem.
Também parece melhor se você estiver usando outros typedefs como uint16_t
ou int32_t
.
unsigned char
ousigned char
documentar explicitamente a intenção também, uma vez que sem adornoschar
é o que mostra que você está trabalhando com personagens.unsigned
eraunsigned int
por definição?char
parece implicar um caractere, enquanto que no contexto de uma string UTF8, pode ser apenas um byte de um caractere multibyte. O uso de uint8_t pode deixar claro que não se deve esperar um caractere em todas as posições - em outras palavras, que cada elemento da string / array é um número inteiro arbitrário sobre o qual não se deve fazer suposições semânticas. É claro que todos os programadores C sabem disso, mas pode ser necessário que os iniciantes façam as perguntas certas.Apenas para ser pedante, alguns sistemas podem não ter um tipo de 8 bits. De acordo com a Wikipedia :
Portanto,
uint8_t
não existe garantia de existência, embora exista para todas as plataformas em que 8 bits = 1 byte. Algumas plataformas incorporadas podem ser diferentes, mas isso está ficando muito raro. Alguns sistemas podem definirchar
tipos como 16 bits; nesse caso, provavelmente não haverá um tipo de 8 bits de qualquer tipo.Fora essa questão (menor), a resposta de @Mark Ransom é a melhor na minha opinião. Use o que mostra mais claramente para o que você está usando os dados.
Além disso, suponho que você quis dizer
uint8_t
(o typedef padrão do C99 fornecido nostdint.h
cabeçalho) e nãouint_8
(não faz parte de nenhum padrão).fonte
uint8_t
(ou digitar para isso). Isso ocorre porque o tipo de 8 bits teria bits não utilizados na representação de armazenamento, o queuint8_t
não deve ter.typedef unsigned integer type uint8_t; // optional
Portanto, em essência, uma biblioteca em conformidade com o padrão C ++ não é necessária para definir o uint8_t (consulte o comentário // opcional )O ponto principal é escrever código independente de implementação.
unsigned char
não é garantido que seja do tipo 8 bits.uint8_t
é (se disponível).fonte
sizeof(unsigned char)
retornará1
por 1 byte. mas se um char int sistema e são do mesmo tamanho de, por exemplo, 16 bits, entãosizeof(int)
irá também retornar1
Como você disse, " quase todos os sistemas".
char
provavelmente é um dos menos propensos a mudar, mas assim que você começar a usar osuint16_t
amigos, ouint8_t
melhor será usar as combinações e até fazer parte de um padrão de codificação.fonte
Na minha experiência, existem dois lugares em que queremos usar uint8_t para significar 8 bits (e uint16_t, etc) e onde podemos ter campos menores que 8 bits. Ambos os locais são onde o espaço é importante e, muitas vezes, precisamos examinar um despejo bruto dos dados durante a depuração e precisamos determinar rapidamente o que eles representam.
O primeiro está nos protocolos de RF, especialmente em sistemas de banda estreita. Nesse ambiente, talvez seja necessário agrupar o máximo de informações possível em uma única mensagem. O segundo é no armazenamento flash, onde podemos ter espaço muito limitado (como em sistemas embarcados). Nos dois casos, podemos usar uma estrutura de dados compactada na qual o compilador cuidará da embalagem e descompactação para nós:
Qual método você usa depende do seu compilador. Você também pode precisar oferecer suporte a vários compiladores diferentes com os mesmos arquivos de cabeçalho. Isso acontece em sistemas incorporados nos quais dispositivos e servidores podem ser completamente diferentes - por exemplo, você pode ter um dispositivo ARM que se comunica com um servidor Linux x86.
Existem algumas ressalvas no uso de estruturas compactadas. O maior problema é que você deve evitar a exclusão do endereço de um membro. Em sistemas com palavras alinhadas por mutibytes, isso pode resultar em uma exceção desalinhada - e em um coredump.
Algumas pessoas também se preocupam com o desempenho e argumentam que o uso dessas estruturas compactadas tornará o sistema mais lento. É verdade que, nos bastidores, o compilador adiciona código para acessar os membros de dados não alinhados. Você pode ver isso observando o código de montagem no seu IDE.
Porém, como as estruturas compactadas são mais úteis para comunicação e armazenamento de dados, os dados podem ser extraídos para uma representação não compactada ao trabalhar com eles na memória. Normalmente, não precisamos trabalhar com todo o pacote de dados na memória.
Aqui está uma discussão relevante:
pacote pragma (1) nem __attribute__ ((alinhado (1))) funciona
O __attribute __ ((empacotado)) / #pragma do gcc não é seguro?
http://solidsmoke.blogspot.ca/2010/07/woes-of-structure-packing-pragma-pack.html
fonte
Há pouco. Do ponto de vista da portabilidade,
char
não pode ser menor que 8 bits e nada pode ser menor quechar
, portanto, se uma determinada implementação C tiver um tipo inteiro de 8 bits não assinado, seráchar
. Como alternativa, ele pode não ter um, nesse ponto qualquertypedef
truque é discutível.Poderia ser usado para documentar melhor seu código, no sentido de que é claro que você precisa de bytes de 8 bits e nada mais. Mas, na prática, já é uma expectativa razoável em praticamente qualquer lugar (existem plataformas DSP nas quais isso não é verdade, mas as chances de seu código ser executado lá são reduzidas e você também pode errar usando uma declaração estática na parte superior do programa em tal plataforma).
fonte
unsigned char
que seja possível manter valores entre 0 e 255. Se você puder fazer isso em 4 bits, meu chapéu está para você.uint8_t
à implementação. Gostaria de saber, compiladores para DSPs com caracteres de 16 bits normalmente implementamuint8_t
, ou não?#include <stdint.h>
e usaruint8_t
. Se a plataforma possuir, ela será entregue a você. Se a plataforma não a possuir, seu programa não será compilado e o motivo será claro e direto.Isso é realmente importante, por exemplo, quando você está escrevendo um analisador de rede. os cabeçalhos de pacotes são definidos pela especificação do protocolo, não pela maneira como o compilador C de uma determinada plataforma funciona.
fonte
Em quase todos os sistemas, encontrei uint8_t == char não assinado, mas isso não é garantido pelo padrão C. Se você está tentando escrever um código portátil e importa exatamente qual o tamanho da memória, use uint8_t. Caso contrário, use char não assinado.
fonte
uint8_t
sempre corresponde ao intervalo, tamanhounsigned char
e preenchimento (nenhum) quandounsigned char
é de 8 bits. Quandounsigned char
não é de 8 bits,uint8_t
não existe.unsigned char
é de 8 bits, éuint8_t
garantida a ser umtypedef
dos mesmos e não umatypedef
de um tipo inteiro não assinado prolongado ?unsigned char/signed char/char
o menor tipo - não inferior a 8 bits.unsigned char
não tem preenchimento. Parauint8_t
ser, ele deve ter 8 bits, sem preenchimento, devido a um tipo inteiro fornecido pela implementação: correspondendo aos requisitos mínimos deunsigned char
. Quanto a "... garantido ser um typedef ...", parece uma boa pergunta para postar.