web-dev-qa-db-fra.com

signification de "référencement" et "déréférencement"

J'ai lu différentes choses sur Internet et je suis devenu confus, car chaque site Web dit des choses différentes.

En parlant de C.

Je lis à propos de * opérateur de référence et & opérateur de déréférencement; ou que référencer signifie faire pointer un pointeur sur une variable et que le déréférencement accède à la valeur de la variable pointée par le pointeur. Alors je me suis perdu.

Puis-je obtenir une explication simple mais complète sur le "référencement et le dé-référencement"?

56
Milkncookiez

Référencement signifie prendre l'adresse d'une variable existante (en utilisant &) pour définir une variable de pointeur. Pour être valide, un pointeur doit être défini sur l'adresse d'une variable du même type que le pointeur, sans l'astérisque:

int  c1;
int* p1;
c1 = 5;
p1 = &c1;
//p1 references c1

Déréférencement un pointeur signifie que vous utilisez l'opérateur * (caractère astérisque) pour extraire la valeur de l'adresse de la mémoire indiquée par le pointeur: REMARQUE: la valeur stockée à l'adresse du pointeur doit être une valeur OF THE SAME TYPE comme type de variable. le pointeur "pointe" sur, mais il y a aucune garantie c'est le cas sauf si le pointeur a été correctement défini. Le type de variable pointé par le pointeur est le type moins l'astérisque le plus à l'extérieur.

int n1;
n1 = *p1;

Déréférencement invalide peut causer ou non des collisions:

  • Le déréférencement d'un pointeur non initialisé peut provoquer un crash
  • Le déréférencement avec une conversion de type non valide risque de provoquer un crash.
  • Déréférencer un pointeur sur une variable allouée dynamiquement puis désaffectée peut provoquer un crash
  • Le déréférencement d'un pointeur sur une variable qui est depuis tombée hors de portée peut également provoquer un blocage.

Référencement invalide est plus susceptible de provoquer des erreurs de compilateur que des plantages, mais ce n’est pas une bonne idée de s’appuyer sur le compilateur pour cela.

Les références:

http://www.codingunit.com/cplusplus-tutorial-pointers-reference-and-dereference-operators

& is the reference operator and can be read as “address of”.
* is the dereference operator and can be read as “value pointed by”.

http://www.cplusplus.com/doc/tutorial/pointers/

& is the reference operator    
* is the dereference operator

http://en.wikipedia.org/wiki/Dereference_operator

The dereference operator * is also called the indirection operator.
78
A B

Je les ai toujours entendues utilisées dans le sens opposé:

  • & est l'opérateur de référence - il vous donne une référence (pointeur) à un objet

  • * est l'opérateur de déréférence - il prend une référence (pointeur) et vous renvoie l'objet référencé;

16
Chris Dodd

Pour commencer, vous les avez à l'envers: & est la référence et * est déréférencé.

Référencer une variable signifie accéder à l'adresse mémoire de la variable:

int i = 5;
int * p;
p = &i; //&i returns the memory address of the variable i.

Déréférencer une variable signifie accéder à la variable stockée à une adresse mémoire:

int i = 5;
int * p;
p = &i;
*p = 7; //*p returns the variable stored at the memory address stored in p, which is i.
//i is now 7
11

trouvez l'explication ci-dessous:

int main()
{
    int a = 10;// say address of 'a' is 2000;
    int *p = &a; //it means 'p' is pointing[referencing] to 'a'. i.e p->2000
    int c = *p; //*p means dereferncing. it will give the content of the address pointed by 'p'. in this case 'p' is pointing to 2000[address of 'a' variable], content of 2000 is 10. so *p will give 10. 
}

conclusion :

  1. & [adresse opérateur] est utilisé pour le référencement.
  2. * [opérateur étoile] est utilisé pour le dé-référencement.
9
nagaradderKantesh

Référencement

& est l'opérateur de référence. Il fera référence à l'adresse mémoire à la variable de pointeur.

Exemple:

int *p;
int a=5;
p=&a; // Here Pointer variable p refers to the address of integer variable a.

Déréférencement

Opérateur de déréférence * est utilisé par la variable de pointeur pour accéder directement à la valeur de la variable au lieu de son adresse mémoire.

Exemple:

int *p;
int a=5;
p=&a;
int value=*p; // Value variable will get the value of variable a that pointer variable p pointing to.
3
zaursh

Le contexte dans lequel se trouve * confond parfois le sens.

  // when declaring a function
int function(int*); // This function is being declared as a function that takes in an 'address' that holds a number (so int*), it's asking for a 'reference', interchangeably called 'address'. When I 'call'(use) this function later, I better give it a variable-address! So instead of var, or q, or w, or p, I give it the address of var so &var, or &q, or &w, or &p.   

//even though the symbol ' * ' is typically used to mean 'dereferenced variable'(meaning: to use the value at the address of a variable)--despite it's common use, in this case, the symbol means a 'reference', again, in THIS context. (context here being the declaration of a 'prototype'.) 


    //when calling a function
int main(){ 
    function(&var);  // we are giving the function a 'reference', we are giving it an 'address'
  }

Ainsi, dans le contexte de , déclarant un type tel que int ou char , nous utiliserions le déréférenceur '*' pour désigner la référence (l'adresse) , ce qui rend les choses confuses si vous voyez un message d'erreur du compilateur disant: 'expecting char *' qui demande une adresse.

Dans ce cas, lorsque le * est après un type (int, char, etc.), le compilateur attend l'adresse d'une variable. Nous lui donnons cela en utilisant un opérateur de référence, également appelé l'opérateur address-of '&' avant une variable. Encore plus loin, dans le cas que je viens de décrire ci-dessus, le compilateur s'attend à ce que l'adresse contienne une valeur de caractère, pas un nombre. (tapez char * == adresse d'une valeur qui a un caractère)

int* p;
int *a;   // both are 'pointer' declarations. We are telling the compiler that we will soon give these variables an address (with &).

int c = 10;  //declare and initialize a random variable
//assign the variable to a pointer, we do this so that we can modify the value of c from a different function regardless of the scope of that function (elaboration in a second)

p = c; //ERROR, we assigned a 'value' to this 'pointer'. We need to assign an 'address', a 'reference'.
p = &c; // instead of a value such as: 'q',5,'t', or 2.1 we gave the pointer an 'address', which we could actually print with printf(), and would be something like
//so
p = 0xab33d111; //the address of c, (not specifically this value for the address, it'll look like this though, with the 0x in the beggining, the computer treats these different from regular numbers)
*p = 10; // the value of c

a = &c; // I can still give c another pointer, even though it already has the pointer variable "p"

*a = 10;
 a = 0xab33d111;

Pensez à chaque variable comme ayant une position (ou une valeur d’index si vous êtes familier avec les tableaux) et une valeur. Il faut parfois s’habituer à penser que chaque variable a deux valeurs, l’une étant sa position, physiquement stockée avec de l’électricité dans votre ordinateur, et une valeur représentant la quantité ou les lettres que le programmeur souhaite stocker.

//Why it's used
int function(b){
    b = b + 1; // we just want to add one to any variable that this function operates on.
} 

int main(){

    int c = 1;  // I want this variable to be 3.

    function(c); 
    function(c);// I call the function I made above twice, because I want c to be 3.

     // this will return c as 1. Even though I called it twice.
     // when you call a function it makes a copy of the variable.
     // so the function that I call "function", made a copy of c, and that function is only changing the "copy" of c, so it doesn't affect the original
}
  //let's redo this whole thing, and use pointers

int function(int* b){ // this time, the function is 'asking' (won't run without) for a variable that 'points' to a number-value (int). So it wants an integer pointer--an address that holds a number.
*b = *b + 1; //grab the value of the address, and add one to the value stored at that address
}

int main(){
    int c = 1; //again, I want this to be three at the end of the program
    int *p = &c; // on the left, I'm declaring a pointer, I'm telling the compiler that I'm about to have this letter point to an certain spot in my computer. Immediately after I used the assignment operator (the ' = ') to assign the address of c to this variable (pointer in this case) p. I do this using the address-of operator (referencer)' & '.
    function(p); // not *p, because that will dereference. which would give an integer, not an integer pointer ( function wants a reference to an int called int*, we aren't going to use *p because that will give the function an int instead of an address that stores an int.

    function(&c); // this is giving the same thing as above, p = the address of c, so we can pass the 'pointer' or we can pass the 'address' that the pointer(variable) is 'pointing','referencing' to. Which is &c. 0xaabbcc1122...


      //now, the function is making a copy of c's address, but it doesn't matter if it's a copy or not, because it's going to point the computer to the exact same spot (hence, The Address), and it will be changed for main's version of c as well.

}

À l'intérieur de chaque bloc, il copie les variables (le cas échéant) qui sont passées (via des paramètres dans "()" s). Au sein de ces blocs, les modifications apportées à une variable sont apportées à un copie de cette variable. La variable utilise les mêmes lettres mais se trouve à une adresse différente (de l'original). En utilisant l'adresse "référence" de l'original, nous pouvons changer une variable en utilisant un bloc en dehors de main ou à l'intérieur d'un enfant en main.

1
Tyler Curtis Jowers