Pergunta

Em C/C++, que unsigned char é usado para?Como é diferente de um normal char?

Foi útil?

Solução

Em C++, existem três distinto tipos de caracteres:

  • char
  • signed char
  • unsigned char

Se você estiver usando tipos de caracteres para texto, use o não qualificado char:

  • é o tipo de literais de caracteres como 'a' ou '0'.
  • é o tipo que compõe strings C como "abcde"

Também funciona como um valor numérico, mas não é especificado se esse valor é tratado como assinado ou não.Cuidado com as comparações de caracteres por meio de desigualdades - embora se você se limitar ao ASCII (0-127), você estará quase seguro.

Se você estiver usando tipos de caracteres como números, usar:

  • signed char, o que lhe dá pelo menos a faixa de -127 a 127.(-128 a 127 é comum)
  • unsigned char, o que lhe dá pelo menos faixa de 0 a 255.

"Pelo menos", porque o padrão C++ fornece apenas o intervalo mínimo de valores que cada tipo numérico deve cobrir. sizeof (char) é necessário que seja 1 (ou seja,um byte), mas um byte poderia, em teoria, ter, por exemplo, 32 bits. sizeof ainda seria relatar seu tamanho como 1 - significando que você poderia ter sizeof (char) == sizeof (long) == 1.

Outras dicas

Isso depende da implementação, pois o padrão C NÃO define a assinatura de char.Dependendo da plataforma, char pode ser signed ou unsigned, então você precisa pedir explicitamente signed char ou unsigned char se sua implementação depender disso.Apenas use char se você pretende representar caracteres de strings, pois isso corresponderá ao que sua plataforma coloca na string.

A diferença entre signed char e unsigned char é como você esperaria.Na maioria das plataformas, signed char será um número em complemento de dois de 8 bits variando de -128 para 127, e unsigned char será um número inteiro sem sinal de 8 bits (0 para 255).Observe que o padrão NÃO exige que char tipos têm 8 bits, só isso sizeof(char) retornar 1.Você pode obter o número de bits em um caractere com CHAR_BIT em limits.h.Existem poucas plataformas hoje em dia onde isso será algo diferente de 8, no entanto.

Há um bom resumo deste problema aqui.

Como outros mencionaram desde que postei isso, é melhor usar int8_t e uint8_t se você realmente deseja representar números inteiros pequenos.

Como sinto que é realmente necessário, só quero declarar algumas regras de C e C++ (elas são iguais nesse aspecto).Primeiro, todos os bits de unsigned char participe na determinação do valor se houver algum objeto char não assinado.Segundo, unsigned char é explicitamente declarado como não assinado.

Agora, conversei com alguém sobre o que acontece quando você converte o valor -1 do tipo int para unsigned char.Ele recusou a ideia de que o resultado unsigned char tem todos os seus bits definidos como 1, porque ele estava preocupado com a representação do sinal.Mas ele não precisa.É imediatamente de acordo com esta regra que a conversão faz o que se pretende:

Se o novo tipo não for assinado, o valor será convertido adicionando ou subtraindo repetidamente um a mais que o valor máximo que pode ser representado no novo tipo até que o valor esteja no intervalo do novo tipo.(6.3.1.3p2 em um rascunho C99)

Essa é uma descrição matemática.C++ descreve-o em termos de cálculo de módulo, que resulta na mesma regra.De qualquer forma, o que é não garantido é que todos os bits no inteiro -1 são um antes da conversão.Então, o que temos para que possamos afirmar que o resultado unsigned char tem todo o seu CHAR_BIT bits virou 1?

  1. Todos os bits participam na determinação de seu valor - ou seja, nenhum bit de preenchimento ocorre no objeto.
  2. Adicionando apenas uma vez UCHAR_MAX+1 para -1 produzirá um valor no intervalo, ou seja, UCHAR_MAX

Isso é o suficiente, na verdade!Então, sempre que você quiser ter um unsigned char tendo todos os seus bits um, você faz

unsigned char c = (unsigned char)-1;

Segue-se também que uma conversão é não apenas truncando bits de ordem superior.O evento feliz para complemento de dois é que há apenas um truncamento, mas o mesmo não é necessariamente verdadeiro para outras representações de signos.

Como por exemplo usos de caracter não identifcado:

caracter não identifcado é frequentemente usado em computação gráfica, que muitas vezes (embora nem sempre) atribui um único byte a cada componente de cor.É comum ver uma cor RGB (ou RGBA) representada como 24 (ou 32) bits, cada um caracter não identifcado.Desde caracter não identifcado os valores estão no intervalo [0,255], os valores são normalmente interpretados como:

  • 0 significa falta total de um determinado componente de cor.
  • 255 significando 100% de um determinado pigmento de cor.

Então você acabaria com RGB vermelho como (255,0,0) -> (100% vermelho, 0% verde, 0% azul).

Por que não usar um caractere assinado?A aritmética e a mudança de bits tornam-se problemáticas.Como já explicado, um caractere assinadoo intervalo de é essencialmente alterado em -128.Um método muito simples e ingênuo (na maioria das vezes não utilizado) para converter RGB em tons de cinza é calcular a média de todos os três componentes de cores, mas isso apresenta problemas quando os valores dos componentes de cores são negativos.Vermelho (255, 0, 0) tem média de (85, 85, 85) ao usar caracter não identifcado aritmética.Contudo, se os valores fossem caractere assinados (127,-128,-128), terminaríamos com (-99, -99, -99), que seria (29, 29, 29) em nosso caracter não identifcado espaço, o que está incorreto.

Se você quiser usar um caractere como um número inteiro pequeno, a maneira mais segura de fazer isso é com o int8_te uint8_t tipos.

signed char tem intervalo de -128 a 127; unsigned char tem intervalo de 0 a 255.

char será equivalente a char assinado ou char não assinado, dependendo do compilador, mas é um tipo distinto.

Se você estiver usando strings no estilo C, basta usar char.Se você precisar usar caracteres para aritmética (muito raro), especifique explicitamente assinado ou não assinado para portabilidade.

char e unsigned char não é garantido que sejam do tipo de 8 bits em todas as plataformas - é garantido que sejam do tipo de 8 bits ou maior.Algumas plataformas têm Bytes de 9 bits, 32 bits ou 64 bits.Porém, as plataformas mais comuns hoje (Windows, Mac, Linux x86, etc.) possuem bytes de 8 bits.

Em termos de valores diretos, um caractere regular é usado quando se sabe que os valores estão entre CHAR_MIN e CHAR_MAX enquanto um caractere não assinado fornece o dobro do intervalo na extremidade positiva.Por exemplo, se CHAR_BIT é 8, o intervalo de regular char só é garantido que seja [0, 127] (porque pode ser assinado ou não assinado) enquanto unsigned char será [0, 255] e signed char será [-127, 127].

Em termos de sua utilização, os padrões permitem que objetos de POD (dados simples e antigos) sejam convertidos diretamente em uma matriz de caracteres não assinados.Isso permite examinar a representação e os padrões de bits do objeto.A mesma garantia de trocadilhos de tipo seguro não existe para char ou char assinado.

unsigned char leva apenas valores positivos... como 0 para 255

enquanto

signed char assume valores positivos e negativos....como -128 para +127

Um caractere não assinado é um valor de byte (não assinado) (0 a 255).Você pode estar pensando em "char" como um "caractere", mas na verdade é um valor numérico.O "char" regular é assinado, então você tem 128 valores, e esses valores são mapeados para caracteres usando codificação ASCII.Mas em ambos os casos, o que você está armazenando na memória é um valor de byte.

Se você gosta de usar vários tipos de comprimento e assinatura específicos, provavelmente será melhor usar uint8_t, int8_t, uint16_t, etc., simplesmente porque eles fazem exatamente o que dizem.

Um caractere não assinado usa o bit reservado para o sinal de um caractere regular como outro número.Isso altera o intervalo para [0 - 255] em oposição a [-128 - 127].

Geralmente caracteres não assinados são usados ​​quando você não deseja um sinal.Isso fará diferença ao fazer coisas como mudar bits (shift estende o sinal) e outras coisas ao lidar com um caractere como um byte em vez de usá-lo como um número.

unsigned char é o coração de todos os truques.Em quase TODOS os compiladores para TODAS as plataformas, um caractere não assinado é simplesmente um BYTE.Um número inteiro não assinado de (geralmente) 8 bits.que pode ser tratado como um pequeno número inteiro ou um pacote de bits.

Além disso, como alguém disse, o padrão não define o sinal de um caractere.então você tem 3 tipos distintos de "char":char, char assinado, char não assinado.

Algumas pesquisas no Google encontradas esse, onde as pessoas discutiram sobre isso.

Um caractere não assinado é basicamente um único byte.Portanto, você usaria isso se precisar de um byte de dados (por exemplo, talvez você queira usá-lo para ativar e desativar sinalizadores a serem passados ​​para uma função, como geralmente é feito na API do Windows).

citado no livro "the c programming laugage":

O qualificador signed ou unsigned pode ser aplicado a char ou qualquer número inteiro.Os números não assinados são sempre positivos ou zero e obedecem às leis do módulo aritmético 2^n, onde n é o número de bits no tipo.Assim, por exemplo, se os chars são 8 bits, as variáveis ​​de char não assinadas têm valores entre 0 e 255, enquanto os chars assinados têm valores entre -128 e 127 (em uma máquina de complemento de dois anos) se os carrus simples são assinados ou não assinados é a máquina - -dependentes, mas os caracteres imprimíveis são sempre positivos.

unsigned char assume apenas valores positivos:0 a 255 Char assinado leva valores positivos e negativos:-128 a +127

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top