La plupart des développeurs d'applications utilisent-ils des entiers signés là où ils veulent vraiment utiliser des entiers non signés? Je le fais tout le temps, mes collègues aussi. Je n'ai pas vu beaucoup d'autres bases de code étendues (autres que Delphi VCL) et des exemples sur Internet utilisent généralement des entiers. Alors que les développeurs VCL utilisent leurs propres types de données (ce qui serait la façon la plus simple de déclarer des variables).
Quelque chose semble un peu terrible à propos de ce code
TStuffRec = record
recordID : Integer;
thingID : Integer;
otherThingID : Integer;
end;
quand il pourrait être écrit comme
TStuffRec = record
recordID : Cardinal;
thingID : Cardinal;
otherThingID : Cardinal;
end;
Fonctionnellement, ces enregistrements fonctionnent presque toujours de la même manière (et, espérons-le, continueront de fonctionner de la même manière dans Delphi 64 bits). Mais un très grand nombre aura des problèmes de conversion.
Mais il y a aussi des inconvénients à utiliser des entrées non signées. Principalement dû au fait qu'il est ennuyeux de mélanger les deux.
La vraie question est, est-ce une chose qui est réellement réfléchie ou incluse dans les meilleures pratiques? Est-ce généralement uniquement au développeur?
la source
Réponses:
L'une des raisons pour lesquelles je n'utilise pas autant de types entiers non signés dans Delphi est qu'ils peuvent créer des problèmes lorsqu'ils sont mélangés avec des entiers signés. En voici un qui m'a mordu une fois:
J'avais
i
déclaré comme un entier non signé, (après tout, c'est un index dans une liste qui commence à 0, il ne doit jamais être négatif, non?), Mais quandList.Count
était 0, il ne court-circuiterait pas la boucle comme prévu car0 - 1
évalue à un nombre positif très élevé. Oops!Entre les problèmes de sécurité potentiels inhérents au mélange d'entiers signés et non signés et les problèmes de plage (si vous avez besoin de nombres positifs plus grands que
high(signed whatever)
, il est fort probable que vous finirez également par avoir besoin de nombres positifs plus grands quehigh(unsigned whatever)
trop, donc jusqu'à la prochaine taille plus grande au lieu de passer de signé à non signé de la même taille est généralement la bonne action,) Je n'ai vraiment pas trouvé trop d'utilisations pour les entiers non signés lors de la représentation de la plupart des données.la source
Pour être honnête, j'ai tendance à utiliser des entiers par habitude. Je me suis habitué au fait qu'ils offrent des plages suffisamment grandes pour la plupart des situations et autorisent des valeurs négatives (telles que -1). En effet, beaucoup de fois en utilisant octets / mot / raccourci serait plus approprié. En y réfléchissant, je peux me concentrer sur ces points:
Perspective. La taille de Tilemap est limitée à 192x192 tuiles, donc je pourrais utiliser l'octet pour adresser les tuiles et les boucles. Mais si la taille de la carte doit être augmentée, je devrai passer par chaque utilisation et la remplacer par exemple par word. Lorsque je dois autoriser des objets hors carte, je dois recommencer pour passer à smallint.
Boucles. C'est souvent que j'écris une boucle "de i: = 0 à Count-1", que se passe-t-il si "i" est octet et Count = 0 est que la boucle va de 0 à 255. Pas que je le veuille.
Uniforme. Il est plus facile de se souvenir et d'appliquer "var i: integer;" que d'arrêter dans chaque cas et de penser "Hm .. ici, nous avons affaire à une plage de 0..120 .. octet .. non, attendez, nous pourrions avoir besoin de -1 pour non initialisé .. raccourci .. attendez .. et si 128 est pas assez .. Arrgh! " ou "Pourquoi est-ce petit dans cet endroit, pas un shortint?"
Combiner. Lorsque j'ai besoin de combiner deux ou plusieurs classes ensemble, elles peuvent utiliser différents types de données à leurs fins, l'utilisation de types plus larges permet d'ignorer les conversions inutiles.
-1. Même lorsque les valeurs sont sur la plage 0..n-1, j'ai souvent besoin de définir une valeur "aucune valeur / inconnue / non initialisée / vide", ce qui est la pratique courante -1.
L'utilisation d'Integers permet d'ignorer tous ces problèmes, d'oublier l'optimisation de bas niveau là où elle n'est pas nécessaire, d'aller plus haut et de se concentrer sur des problèmes plus réels.
PS Quand dois-je utiliser d'autres types?
la source
La meilleure pratique consiste à utiliser un type de données qui correspond aux besoins des données utilisées (données attendues).
Exemples C #: si je n'avais besoin que de 0 à 255, j'utiliserais un octet.
Si j'avais besoin de supporter 1 000 000 de négatifs et de positifs, alors int.
Plus grand que 4,2 milliards, alors utilisez un long.
En choisissant le type correct, le programme utilisera la quantité optimale de mémoire ainsi que différents types utilisent différentes quantités de mémoire.
Voici une référence C # int de MSDN.
la source
Integer
type de données est 32 bits sur une machine 32 bits et sera apparemment 64 bits sur une machine 64 bits.int
est juste un raccourci pourSystem.Int32
, quelle que soit la machine sur laquelle le code fonctionne.type int System.Int32
ou quelque chose dans ce sens? Pourrait-il être modifié aussi facilement dans une future version du framework?uint
est l'un de ces types non conformes, ce qui signifie qu'il ne doit pas être utilisé dans une API exposée publiquement pour éviter de casser la capacité à utiliser cette API dans des langages .NET autres que celui dans lequel la bibliothèque est écrite. C'est également la raison pour laquelle le framework .NET L'API elle-même utiliseint
où leuint
ferait.Les types entiers non signés ne doivent être utilisés que pour représenter des nombres cardinaux dans les langues où ils représentent des nombres cardinaux. En raison de la façon dont les ordinateurs qui exécutaient C fonctionnaient, les types entiers non signés se comportaient comme des membres des anneaux algébriques mod-2 ^ n (ce qui signifie que les calculs qui débordaient seraient "enveloppés" de manière prévisible), et le langage spécifie que dans de nombreux cas, ces types sont tenus de se comporter comme des anneaux algébriques abstraits même lorsque ce comportement serait incompatible avec le comportement des nombres cardinaux ou des entiers mathématiques.
Si une plate-forme prend entièrement en charge des types distincts pour les nombres cardinaux et les anneaux algébriques, je suggère que les nombres cardinaux soient traités à l'aide de types de nombres cardinaux (et de choses qui doivent être enveloppées à l'aide des types d'anneaux). Non seulement ces types pouvaient stocker des nombres deux fois plus grands que les types signés, mais une méthode recevant un paramètre d'un tel type n'aurait pas à vérifier s'il était négatif.
Étant donné le manque relatif de types de nombres cardinaux, cependant, il est généralement préférable d'utiliser simplement des entiers pour représenter à la fois des nombres mathématiques et des nombres cardinaux.
la source