Uso entradas não assinadas em todos os lugares e não tenho certeza se devo. Pode ser das colunas de identificação da chave primária do banco de dados aos contadores, etc. Se um número nunca deve ser negativo, sempre utilizarei um int não assinado.
No entanto, percebo pelo código de outros que mais ninguém parece fazer isso. Existe algo crucial que eu estou ignorando?
Edit: Desde essa pergunta, eu também notei que em C, retornar valores negativos para erros é comum em vez de gerar exceções, como em C ++.
c++
c
programming-practices
wting
fonte
fonte
for(unsigned int n = 10; n >= 0; n --)
(laços infinitamente)Respostas:
Quando os cálculos envolvem tipos assinados e não assinados, além de tamanhos diferentes, as regras para promoção de tipos podem ser complexas e levar a um comportamento inesperado .
Acredito que essa seja a principal razão pela qual o Java omitiu tipos int não assinados.
fonte
int
não apresentariam tal dificuldade, no entanto (uma vez que qualquer cálculo promoverá aint
); Não tenho nada de bom a dizer sobre a falta de um tipo de byte não assinado.Eu acho que Michael tem um ponto válido, mas na IMO a razão pela qual todo mundo usa int o tempo todo (especialmente em
for (int i = 0; i < max, i++
) é que nós aprendemos dessa maneira. Quando todos os exemplos de um livro de ' como aprender programação ' são usadosint
emfor
loop, muito poucos questionam essa prática.A outra razão é que
int
é 25% menor queuint
, e somos todos preguiçosos ... ;-)fonte
++
ao incrementar, apesar do fato de que seu comportamento específico raramente é necessário e pode até levar a agitar as cópias sem sentido se o índice do loop for um iterador ou outro tipo não fundamental (ou o compilador for realmente denso) .A codificação das informações do intervalo em tipos é uma coisa boa. Impõe o uso de números razoáveis no momento da compilação.
Muitas arquiteturas parecem ter instruções especializadas para lidar com
int
->float
conversões. A conversão deunsigned
pode ser mais lenta (um pouquinho) .fonte
A mistura de tipos assinados e não assinados pode levar você a um mundo de dor. E você não pode usar todos os tipos não assinados porque encontrará itens que possuem um intervalo válido que inclui números negativos ou precisam de um valor para indicar um erro e -1 é o mais natural. Portanto, o resultado final é que muitos programadores usam todos os tipos de números inteiros assinados.
fonte
Para mim, os tipos são muito sobre comunicação. Usando explicitamente um int não assinado, você me diz que os valores assinados não são válidos. Isso me permite adicionar algumas informações ao ler seu código, além do nome da variável. Idealmente, um tipo não anônimo me diria mais, mas isso me dá mais informações do que se você tivesse usado ints em todos os lugares.
Infelizmente, nem todo mundo está muito consciente sobre o que o código comunica, e essa é provavelmente a razão pela qual você vê ints em todos os lugares, mesmo que os valores sejam pelo menos sem sinal.
fonte
Eu uso
unsigned int
em C ++ para índices de matriz, principalmente, e para qualquer contador que comece a partir de 0. Eu acho bom dizer explicitamente "essa variável não pode ser negativa".fonte
Você deve se preocupar com isso quando estiver lidando com um número inteiro que possa realmente se aproximar ou exceder os limites de um int assinado. Como o máximo positivo de um número inteiro de 32 bits é 2.147.483.647, você deve usar um int sem sinal se souber que a) nunca será negativo eb) poderá atingir 2.147.483.648. Na maioria dos casos, incluindo chaves e contadores de banco de dados, nunca abordarei esses tipos de números, para não me preocupar em me preocupar se o bit de sinal é usado para um valor numérico ou para indicar o sinal.
Eu diria: use int, a menos que você saiba que precisa de um int não assinado.
fonte
É uma troca entre simplicidade e confiabilidade. Quanto mais erros puderem ser detectados em tempo de compilação, mais confiável será o software. Diferentes pessoas e organizações estão em pontos diferentes ao longo desse espectro.
Se você faz alguma programação de alta confiabilidade no Ada, você ainda usa tipos diferentes para variáveis como distância em pés x distância em metros, e o compilador o sinaliza se você atribuir acidentalmente um ao outro. Isso é perfeito para programar um míssil guiado, mas é um exagero se você estiver validando um formulário da web. Não há necessariamente nada de errado com os dois, desde que atenda aos requisitos.
fonte
Estou inclinado a concordar com o raciocínio de Joel Etherton, mas chego à conclusão oposta. Do meu ponto de vista, mesmo que você saiba que é improvável que os números se aproximem dos limites de um tipo assinado, se você sabe que números negativos não acontecerão, há muito pouco motivo para usar a variante assinada de um tipo.
Pelo mesmo motivo, em algumas instâncias selecionadas, usei
BIGINT
(número inteiro de 64 bits) em vez deINTEGER
(número inteiro de 32 bits) nas tabelas do SQL Server. A probabilidade de os dados atingirem o limite de 32 bits dentro de um período de tempo razoável é minúscula, mas se isso acontecer, as consequências em algumas situações poderão ser bastante devastadoras. Apenas certifique-se de mapear os tipos entre os idiomas corretamente, ou você vai acabar com uma estranheza interessante muito abaixo da estrada ...Dito isto, para algumas coisas, como valores de chave primária de banco de dados, assinados ou não assinados, realmente não importa, porque, a menos que você esteja reparando manualmente dados quebrados ou algo nesse sentido, nunca estará lidando com o valor diretamente; é um identificador, nada mais. Nesses casos, a consistência é provavelmente mais importante que a escolha exata da assinatura. Caso contrário, você terá algumas colunas de chave estrangeira assinadas e outras não assinadas, sem um padrão aparente - ou com essa estranheza interessante novamente.
fonte
Eu recomendaria que, fora dos contextos de armazenamento e intercâmbio de dados com restrição de espaço, usássemos tipos assinados. Na maioria dos casos, em que um número inteiro assinado de 32 bits seria muito pequeno, mas um valor não assinado de 32 bits seria suficiente para hoje, não demorará muito para que o valor não assinado de 32 bits também não seja grande o suficiente.
O principal momento em que se deve usar tipos não assinados é quando se está montando vários valores em um valor maior (por exemplo, convertendo quatro bytes em um número de 32 bits) ou decompondo valores maiores em valores menores (por exemplo, armazenando um número de 32 bits em quatro bytes ), ou quando se tem uma quantidade que se espera "rolar" periodicamente e é preciso lidar com isso (pense em um medidor de utilidade residencial; a maioria deles tem dígitos suficientes para garantir que não possam rolar entre as leituras se forem lidos três vezes por ano, mas não o suficiente para garantir que não rolem durante a vida útil do medidor). Tipos não assinados geralmente têm 'estranheza' suficiente para serem usados apenas nos casos em que sua semântica é necessária.
fonte
size_t
não está assinado eptrdiff_t
está assinado.Uso ints não assinados para tornar meu código e sua intenção mais claros. Uma coisa que faço para me proteger contra conversões implícitas inesperadas ao fazer aritmética com os tipos assinado e não assinado é usar um atalho não assinado (normalmente 2 bytes) para minhas variáveis não assinadas. Isso é eficaz por alguns motivos:
O princípio geral é que o tipo de suas variáveis não assinadas deve ter uma classificação inferior ao tipo das variáveis assinadas para garantir a promoção para o tipo assinado. Então você não terá nenhum comportamento inesperado de estouro. Obviamente, você não pode garantir isso o tempo todo, mas (na maioria das vezes) é possível garantir isso.
Por exemplo, recentemente tive alguns para o loop algo parecido com isto:
O literal '2' é do tipo int. Se eu fosse um int sem sinal em vez de um curto sem sinal, na sub-expressão (i-2), 2 seria promovido a um int sem sinal (já que o int sem sinal tem uma prioridade mais alta que o sinal assinado). Se i = 0, a sub-expressão é igual a (0u-2u) = algum valor massivo devido ao estouro. A mesma idéia com i = 1. No entanto, como i é um curto não assinado, ele é promovido para o mesmo tipo que o literal '2', que é assinado int, e tudo funciona bem.
Para maior segurança: no caso raro em que a arquitetura que você está implementando causa 2 int, isso pode fazer com que os dois operandos na expressão aritmética sejam promovidos a int sem sinal no caso em que a variável curta não assinada não se encaixa no int de 2 bytes assinado, este último com um valor máximo de 32.767 <65.535. (Consulte https://stackoverflow.com/questions/17832815/c-implicit-conversion-signed-unsigned para obter mais detalhes). Para se proteger, você pode simplesmente adicionar um static_assert ao seu programa da seguinte maneira:
e não será compilado em arquiteturas onde int é 2 bytes.
fonte