La connexion et la différence entre référence et pointeur en C / C ++
Pourquoi les pointeurs devraient-ils être utilisés en C / C ++?
1. Chaque langage de programmation utilise des pointeurs. C ++ expose des pointeurs aux utilisateurs (programmeurs), tandis que des langages tels que JAVA et C # masquent les pointeurs.
2. Le pointeur peut représenter efficacement la structure de données
3. Peut allouer dynamiquement de la mémoire pour réaliser la gestion libre de la mémoire
4. Pratique pour utiliser la chaîne et une utilisation efficace du tableau
5. Le pointeur est directement lié à l'adresse de stockage des données, comme: le transfert de valeur n'est pas aussi bon que le transfert d'adresse Efficace, car le transfert de valeur prend d'abord la valeur de l'adresse du paramètre réel, puis attribue la valeur au paramètre formel dans le calcul de la fonction; et le pointeur pointe directement l'adresse du paramètre formel vers l'adresse réelle du paramètre, et récupère directement les données lorsqu'il est utilisé, l'efficacité est améliorée, en particulier lors d'affectations fréquentes Dans d'autres cas (remarque: le changement des paramètres formels affectera les paramètres réels!)
La différence entre référence et pointeur?
D' abord avec les mots simples d'introduction:
pointeur - pour un type T, T est un type de pointeur T, qui est un T variable de type peut contenir l'adresse d'un objet T et T est le type que vous pouvez ajouter des qualificatifs, Tels que const, volatile, etc. Voir la figure ci-dessous, la signification du pointeur indiqué:
Référence - La référence est un alias d'un objet, principalement utilisé pour les paramètres de fonction et les types de valeur de retour, le symbole X & indique une référence de type X. Voir la figure ci-dessous, la signification des citations affichées:
- Le pointeur peut modifier la valeur pointée par l'adresse, il peut également pointer vers d'autres adresses; et la référence pointe toujours vers l'objet spécifié lors de l'initialisation , mais peut modifier la valeur de l'objet
- Du point de vue de l'allocation de mémoire, le programme alloue la zone mémoire pour la variable pointeur, mais pas pour la référence , car la référence doit être initialisée lors de sa déclaration, pour pointer vers un objet existant. Les références ne peuvent pas pointer vers des valeurs nulles.
- Du point de vue de la compilation, le programme ajoute des pointeurs et des références à la table des symboles pendant la compilation, et la table des symboles enregistre le nom de la variable et l'adresse correspondant à la variable. La valeur d'adresse correspondante de la variable de pointeur sur la table de symboles est la valeur d'adresse de la variable de pointeur , et la valeur d'adresse correspondante de la référence sur la table de symboles est la valeur d'adresse de l' objet de référence . Une fois la table des symboles générée, elle ne sera pas modifiée, le pointeur peut donc modifier l'objet pointé (la valeur de la variable de pointeur peut être modifiée) et l'objet référencé ne peut pas être modifié. C'est la principale raison pour laquelle l'utilisation de pointeurs n'est pas sûre et l'utilisation de la sécurité de référence. Dans un sens, une référence peut être considérée comme un pointeur qui ne peut pas changer l'adresse.
- Le fait qu'il n'y ait aucune référence à des valeurs nulles signifie que le code utilisant des références est plus efficace que l'utilisation de pointeurs. Parce que vous n'avez pas besoin de tester la validité de la référence avant de l'utiliser. Au lieu de cela, les pointeurs doivent toujours être testés pour les empêcher d'être vides.
- En théorie, il n'y a pas de limite au nombre de niveaux de pointeur, mais la référence ne peut être que d'un niveau . Comme suit:
int ** p1; // legal. Pointeur vers le pointeur
int * & p2; // legal. Référence au pointeur
int & * p3; // Illégal. Le pointeur vers la référence est illégal dans
&& p4; // illégal. Les références aux références sont illégales.
Notez que la lecture ci-dessus est de gauche à droite .
En bref, on peut conclure que "un pointeur pointe vers un morceau de mémoire, et son contenu est l'adresse de la mémoire pointée; et une référence est un alias d'un certain morceau de mémoire, et la référence ne change pas le pointage ."
Const spécial
int main()
{
int i= 0;
int j=1;
//常量引用,指向的地址的内容是个常量,不可以修改,即i的值不可以修改
const int &r = i ;
//常量指针,p指针的地址可修改,但无法修改指向地址的内容,*p不可修改,即p指针不可以修改j的值,但可以指向i的地址
const int* p=&j;
p = &i;
//指针常量,q指向的地址不可修改,可以修改指向地址的内容,*q可以修改,即q指针只能指向j的地址,但可以修改j的值
int* const q = &j;
*q=5;
//常量指针常量,w指向的地址和内容都不可修改,即w和*w均不可修改
const int* const w = &j;
cout<<j<<endl;
cout<<i<<endl;
return 0;
}
Pointer passant et référence passant
- Le paramètre de transfert de pointeur est essentiellement un moyen de transfert de valeur, ce qu'il passe est une valeur d'adresse. Dans le processus de transfert de valeur, les paramètres formels de la fonction appelée sont traités comme des variables locales de la fonction appelée, c'est-à-dire que l'espace mémoire est ouvert sur la pile pour stocker la valeur du paramètre réel inséré par la fonction appelante principale, devenant ainsi une copie du paramètre réel . La caractéristique du transfert de valeur est que toute opération de la fonction appelée sur les paramètres formels est effectuée en tant que variable locale , ce qui n'affecte pas la valeur de la variable de paramètre réelle de la fonction appelante.
- Dans le processus de passage de référence, les paramètres formels de la fonction appelée ouvrent également de l'espace mémoire sur la pile en tant que variables locales, mais à ce moment, l'adresse de la variable de paramètre réelle introduite par la fonction appelante est stockée. Toute opération de la fonction appelée sur le paramètre formel est traitée en adressage indirect , c'est-à-dire que la variable de paramètre réelle dans la fonction appelante est accessible via l'adresse stockée dans la pile . De ce fait, toute opération de la fonction appelée sur les paramètres formels affecte les variables de paramètres réelles dans la fonction appelante .
Le passage de référence et le passage de pointeur sont différents. Bien qu'ils soient tous des variables locales sur l'espace de pile de la fonction appelée, tout traitement des paramètres de référence opère sur les variables liées dans la fonction appelante via une méthode d'adressage indirect. Pour les paramètres passés par le pointeur, si l'adresse du pointeur dans la fonction appelée est modifiée, cela n'affectera pas les variables associées de la fonction appelante. Si vous souhaitez modifier les variables pertinentes dans la fonction appelante en passant des paramètres de pointeur, vous devez utiliser un pointeur vers un pointeur ou une référence de pointeur .
Résumé
Enfin, résumez les similitudes et les différences entre les pointeurs et les références:
★ Similitudes:
- Tous sont des concepts d'adresses; un
pointeur pointe vers un morceau de mémoire, et son contenu est l'adresse de la mémoire pointée; et une référence est un alias d'un morceau de mémoire.
★ Différences: - Le pointeur est une entité et la référence n'est qu'un nom individuel;
- Les références ne peuvent être initialisées qu'une seule fois au moment de la définition, puis immuables; les pointeurs sont variables; les références "de l'un à l'autre", les pointeurs peuvent "penser différemment";
- Les références n'ont pas const, les pointeurs ont const et les pointeurs const sont immuables; en
particulier, il n'existe pas de forme telle que int & const a, et const int & a existe. Sous cette forme, la valeur de cette dernière ligne directrice ne peut pas être modifiée) - La référence ne peut pas être nulle, le pointeur peut être nul;
- "Sizeof reference" est la taille de la variable (objet) pointée et "sizeof pointer" est la taille du pointeur lui-même 4
- La signification de l'opération de pointeur et d'incrément de référence (++) est différente;
- Les références sont de type sécurisé, et les pointeurs ne le sont pas (les références ont plus de vérifications de type que de pointeurs)