82 votes

Quelle est la différence entre une Référence C# et un Pointeur?

Désolé pour ces une question de newbie, mais il y a quelque chose que je ne comprends pas très bien la différence entre une référence C# et un pointeur. Ils pointent tous deux vers un endroit de la mémoire n'est-ce pas? La seule différence, je peux comprendre, c'est que les pointeurs ne sont pas aussi intelligente, ne peut point à quoi que ce soit sur le tas, sont exonérés de la collecte des ordures, et peuvent uniquement faire référence à des entretoises ou des types de base.

L'une des raisons pour laquelle je demande, c'est que il ya une perception que les gens ont besoin de comprendre les pointeurs (à partir de C je crois) eh bien, pour être un bon programmeur. Que beaucoup de gens qui penchait de plus haut niveau langues manquer cela et ont donc cette faiblesse.

Je ne vois pas en quoi c'est si complexe sur un pointeur? Il est fondamentalement juste une référence à un endroit de la mémoire n'est-il pas? La possibilité de restituer l'emplacement, ou il peut être utilisé pour interagir que l'objet dans l'emplacement directement?

Donc manqué une énorme point?

126voto

JaredPar Points 333733

Il y a une légère, mais extrêmement important, la distinction entre un pointeur et référence. Un pointeur pointe vers un endroit de la mémoire tout en un des points de référence à un objet en mémoire. Les pointeurs ne sont pas de type "coffre-fort" dans le sens que vous ne pouvez pas garantir l'exactitude de la mémoire qu'ils pointent.

Prenons par exemple le code suivant

int* p1 = GetAPointer();

C'est le type de coffre-fort dans le sens que GetAPointer doit retourner un type compatible avec int*. Pourtant, il n'y a toujours pas de garantie qu' *p1 va en fait montrer un int. Il pourrait être un char, double, ou simplement un pointeur dans la mémoire vive.

Une référence cependant des points à un objet spécifique. Les objets peuvent être déplacés autour de la mémoire mais la référence ne peut pas être invalidé (sauf si vous utilisez le code unsafe). Les références sont beaucoup plus sûrs à cet égard que des pointeurs.

string str = GetAString();

Dans ce cas, str a l'un des deux l'état 1) il pointe vers aucun objet, et donc la valeur est nulle ou 2), il pointe sur une chaîne valide. C'est tout. Le CLR garantit que cela soit le cas. Il ne peut pas et ne sera pas pour un pointeur.

44voto

Mehrdad Afshari Points 204872

C# références peuvent être déplacés par le garbage collector mais normal, les pointeurs sont statiques. C'est pourquoi nous utilisons fixed mot-clé lors de l'acquisition d'un pointeur vers un élément de tableau, pour l'empêcher de se déplacer.

EDIT: sur le plan Conceptuel, oui. Ils sont plus ou moins les mêmes.

13voto

Chris Conway Points 24671

Une référence est un "abstract" pointeur: vous ne pouvez pas faire de l'arithmétique avec une référence et vous ne pouvez pas jouer tout bas niveau des tours avec sa valeur.

6voto

ctacke Points 53946

D'abord je pense que vous avez besoin de définir un "Pointeur" dans votre sematics. Entendez-vous le pointeur que vous pouvez créer dans le code unsafe avec fixe? Voulez-vous dire un IntPtr que vous obtenez à partir peut-être un appel des indigènes ou Maréchal.AllocHGlobal? Voulez-vous dire un GCHandle? Le sont tous essentiellement la même chose - une représentation d'une adresse en mémoire où quelque chose est stocké - être une classe, un nombre, une structure, quelle que soit. Et pour l'enregistrement, ils peuvent certainement être sur le tas.

Un pointeur (toutes les versions ci-dessus) est un point fixe. Le GC n'a aucune idée de ce qui est à cette adresse, et n'a donc pas la capacité de gérer la mémoire ou de la vie de l'objet. Cela signifie que vous perdez tous les avantages de l'une de ces ordures système. Vous devez gérer manuellement l'objet de la mémoire et vous avez le potentiel pour des fuites.

Une référence sur l'autre main est assez bien une "géré" pointeur que le GC connaît. C'est encore une adresse d'un objet, mais maintenant, le GC ne connaît les détails de la cible, alors il peut le déplacer, le faire compactions, de finaliser, d'en disposer et de tous les autres trucs sympa un environnement géré.

La différence majeure, vraiment, c'est comment et pourquoi vous devez les utiliser. Pour une grande majorité des cas, dans un langage managé, vous allez utiliser une référence d'objet. Les pointeurs être utile pour faire de l'interopérabilité et les rares besoin pour un travail rapide.

Edit: En fait, voici un bon exemple de quand vous pouvez utiliser un "pointeur" dans le code managé - dans ce cas, c'est un GCHandle, mais exactement la même chose aurait pu être fait avec AllocHGlobal ou en utilisant fixé sur un tableau d'octets ou de struct. J'ai tendance à préférer le GCHandle car il se sent plus ".NET" pour moi.

5voto

Tamas Czinege Points 49277

Les pointeurs pointent vers un emplacement dans l'espace d'adressage de mémoire. Point de références d'une structure de données. Les structures de données de tous les déplacés tout le temps (enfin, pas souvent, mais chaque maintenant et puis) par le garbage collector (pour le compactage de la mémoire de l'espace). Aussi, comme vous l'avez dit, les structures de données sans références obtiendrez d'ordures collectées après un certain temps.

Aussi, les pointeurs ne sont utilisables que dans le contexte dangereux.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X