2010-06-17 11 views
8

Quelle est la justification de l'utilisation de nombres signés comme index dans .Net?Numéros non signés ou signés en tant qu'index

En Python, vous pouvez indexer à partir de la fin d'un tableau en envoyant des nombres négatifs, mais ce n'est pas le cas dans .Net. Il n'est pas facile pour .Net d'ajouter une telle fonctionnalité plus tard car elle pourrait casser d'autres codes en utilisant peut-être des règles spéciales (ouais, une mauvaise idée, mais j'imagine que ça arrive) sur l'indexation.

Je n'ai jamais eu besoin d'indexer des tableaux de plus de 2 147 483 647, mais je ne comprends vraiment pas pourquoi ils choisissent des nombres signés. Peut-il être parce qu'il est plus normal d'utiliser des chiffres signés dans le code?

Edit: Je viens de trouver ces liens:

The perils of unsigned iteration in C/C++

Signed word lengths and indexes

Edit2: Ok, deux autres bonnes raisons du fil Matthew Flaschen posté:

  • historique raisons car c'est un langage de type c
  • Interop avec c
+0

+1, excellente question. – Blindy

+1

Voir [Pourquoi est Array.Length un int, et non un uint] (http://stackoverflow.com/questions/6301/why-is-array-length-an-int-and-not-an-uint). –

+0

duplicata possible de [Pourquoi est-ce que .NET utilise int au lieu de uint dans certaines classes?] (Http://stackoverflow.com/questions/782629/why-does-net-use-int-instead-of-uint-in- certaines-classes) – nawfal

Répondre

3

Pour la simplicité bien sûr. Aimez-vous trouble faire arithmétique de taille avec ints non signés?

+1

Un très bon point valide – simendsjo

+0

L'exemple que vous avez posté représente un parfait exemple d'une mauvaise pratique de la programmation. Si quelqu'un est un tel codeur amateur, même les entiers signés ne le sauveront pas du buffer under/overruns. –

2

Non signé non conforme à la norme CLS.

+0

Mais Microsoft a fait les spécifications CLS non? Ils ont eu le dernier mot dans cette affaire et ils ont choisi d'utiliser des numéros signés. – Blindy

+1

@Blindy: Je pense qu'ils voulaient rendre les spécifications CLS aussi inclusives que possible, et toutes les langues ne supportent pas les nombres non signés (par exemple VB6 et même si VB6 n'est pas un langage CLS je suppose qu'ils auraient voulu augmenter les chances de interopérabilité). –

+0

@Blindy: Java n'a même pas signé. – kizzx2

4

Il se peut que ce soit dans la longue tradition d'utiliser une valeur inférieure à 0 comme index invalide. Des méthodes telles que String.IndexOf renvoient -1 si l'élément est introuvable. Par conséquent, la valeur de retour doit être signée. Si les consommateurs d'index nécessitent des valeurs non signées, vous devez a) vérifier et b) convertir la valeur pour l'utiliser. Avec des indices signés, vous avez juste besoin de la vérification.

+0

Cela semble plausible, mais c'est le seul exemple auquel je peux penser. L'utilisation d'un nombre négatif en tant qu'index est une erreur d'exécution. IndexOf aurait pu être implémenté d'une autre manière. – simendsjo

+0

Un autre exemple est [Liste .BinarySearch] (http://msdn.microsoft.com/en-us/library/w4e7fxsh.aspx) où le retour est "L'index de base zéro de l'élément dans la liste triée , si item est trouvé, sinon, un nombre négatif qui est le complément binaire de l'index de l'élément suivant qui est plus grand que item ou, s'il n'y a pas d'élément plus grand, le complément binaire de Count. " –

0

L'utilité principale des nombres non signés survient lorsque l'on compose des nombres plus grands à partir de plus petits nombres et vice versa. Par exemple, si l'on reçoit quatre octets non signés d'une connexion et souhaite considérer que leur valeur, dans son ensemble, comme un entier de 32 bits, en utilisant des types non signés signifie, on peut dire simplement:

 
    value = byte0 | (byte1*256) | (byte2*65536) | (byte3*16777216); 

En revanche, si les octets étaient signés, une expression comme celle-ci serait plus compliquée. Je ne suis pas sûr que je vois vraiment une raison pour un langage conçu de nos jours de ne pas inclure les versions non signées de tous les types plus courts que le plus long type entier signé, avec la sémantique entière (signifiant discrete-quantity-numerics, plutôt que tout type particulier) opérations qui s'inséreront entièrement dans le plus grand type signé sera par défaut exécuté comme si ils fonctionnaient sur ce type. Inclure une version non signée du plus grand type signé compliquerait la spécification de la langue (puisqu'il faudrait spécifier quelles opérations doivent se situer dans la portée du type signé, et quelles opérations doivent se situer dans la portée du type non signé), sinon il devrait y avoir pas de problème de conception d'un langage pour que if (unsigned1 - unsigned2 > unsigned3) donne un résultat "numériquement correct" même lorsque unsigned2 est supérieur à unsigned1 [si l'on veut un wraparound non signé, on spécifierait explicitement if ((Uint32)(unsigned1 - unsigned2) > unsigned3)].Un langage qui spécifiait un tel comportement serait certainement une grande amélioration par rapport au désordre qui existe en C (justifiable, compte tenu de son histoire), C#, ou vb.net.