web-dev-qa-db-fra.com

Que signifie int &

Une question C++,

Je connais 

int* foo(void)

toto retournera un pointeur sur type int

que diriez-vous 

int &foo(void)

qu'est-ce qu'il retourne?

Merci beaucoup!

16
Alfred Zhong

Il retourne un reference à un int. Les références sont similaires aux pointeurs mais avec quelques distinctions importantes. Je vous recommande de lire les différences entre les pointeurs, les références, les objets et les types de données primitifs.

"Effective C++" et "More Effective C++" (tous deux de Scott Meyers) décrivent bien les différences et indiquent quand utiliser les pointeurs par rapport aux références.

EDIT: Il y a un certain nombre de réponses disant "les références ne sont que du sucre syntaxique pour faciliter le traitement des pointeurs". Ils sont très certainement non.

Considérons le code suivant:

int a = 3;
int b = 4;
int* pointerToA = &a;
int* pointerToB = &b;
int* p = pointerToA;
p = pointerToB;
printf("%d %d %d\n", a, b, *p); // Prints 3 4 4
int& referenceToA = a;
int& referenceToB = b;
int& r = referenceToA;
r = referenceToB;
printf("%d %d %d\n", a, b, r); // Prints 4 4 4

La ligne p = pointerToB change la valeur de p, c’est-à-dire qu’elle pointe maintenant sur un autre morceau de mémoire. 

r = referenceToB fait quelque chose de complètement différent: il attribue la valeur de b à l'emplacement où se trouvait la valeur de a. Cela ne change pas _ r du tout. r est toujours une référence au même morceau de mémoire.

La différence est subtile mais très importante.

Si vous pensez toujours que les références ne sont que du sucre syntaxique pour la manipulation du pointeur, alors please lisez les livres de Scott Meyers. Il peut expliquer la différence beaucoup mieux que moi.

34
Cameron Skinner

Soyez prudent ici ... vous parcourez la ligne C/C++. Il y a une distinction assez claire mais elle n'apparaît pas toujours ainsi:

C++ : cela signifie souvent une référence. Par exemple, considérons:

void func(int &x)
{
   x = 4;
}

void callfunc()
{
    int x = 7;
    func(x);
}

En tant que tel, C++ peut passer par valeur ou passer par référence .

Cn'a cependant pas cette fonctionnalité passe par référence. & signifie "adresse de" et est un moyen de formuler un pointeur à partir d'une variable. Cependant, considérez ceci:

void func(int* x)
{
   *x = 4;
}

void callfunc()
{
    int x = 7;
    func(&x);
}

Faussement similaire, mais fondamentalement différent. Ce que vous faites dansCpasse un copy du pointeur. Maintenant, ces choses pointent toujours vers la même zone de mémoire, ainsi l’effet est semblable à un passage par référence en termes de mémoire pointée, mais ce n’est pas une référence en cours de passage. C'est une référence à un point en mémoire.

Essayez ceci (Compiler en C):

#include <stdio.h>

void addptr(int* x)
{
    printf("Add-ptr scope 1:\n");
    printf("Addr: %p\n", x);
    printf("Pointed-to-memory: %d\n", *x);
    *x = *x + 7;
    x++;
    printf("Add-ptr scope 2:\n");
    printf("Addr: %p\n", x);
    printf("Pointed-to-memory: %d\n", *x);
}

int main(int argc, char** argv)
{
    int a = 7;
    int *y = &a;
    printf("Main-Scope 2:\n");
    printf("Addr: %p\n", y);
    printf("Pointed-to-memory: %d\n", *y);
    addptr(y);
    printf("Main-Scope 2:\n");
    printf("Addr: %p\n", y);
    printf("Pointed-to-memory: %d\n", *y);
    return 0;

}

Si C avait passé par référence, l'adresse du pointeur entrant, une fois modifiée par addptr, devrait être reflétée dans main, mais ce n'est pas le cas. Les pointeurs sont toujours des valeurs.

Donc,C_ non n'a pas de mécanisme passe par référence. En C++, cela existe, et c’est ce que & signifie dans les arguments de fonction, etc.

Edit: Vous vous demandez peut-être pourquoi je ne peux pas faire cette démonstration en C++ facilement. C'est parce que je ne peux pas changer l'adresse de la référence. Du tout. De t son très bon guide de références :

Comment pouvez-vous réinsérer une référence pour que Fasse référence à un objet différent?  

En aucune façon.

Vous ne pouvez pas séparer la référence de Le référent.

Contrairement à un pointeur, une fois qu'une référence est Liée à un objet, elle ne peut pas être "Replacée" vers un autre objet. La référence Elle-même n'est pas un objet (elle n'a pas d'identité. En prenant l'adresse de Une référence vous donne l'adresse de Le référent; rappelez-vous: la référence est son référent).

En ce sens, une référence est similaire À un pointeur const tel que int * const P (par opposition à un pointeur sur const Tel que int const * p). Mais s'il vous plaît , Ne confondez pas les références avec Des pointeurs; ils sont très différents de le point de vue du programmeur.

Sur demande, sur renvoi de références:

#include <iostream>

using namespace std;

int& function(int f)
{
   f=f+3;
   return f;
}

int main(int argc, char** argv)
{
    int x = 7;
    int y;
    y = function(x);
    cout << "Input: " << x << endl;
    cout << "Output:" << y << endl;
    return 0;
}

Tout bon compilateur devrait vous donner ce message d’avertissement sous une forme:

exp.cpp: 7: 11: avertissement: référence à la mémoire de pile associée à la variable locale 'f' renvoyé

Qu'est-ce que ça veut dire? Eh bien, nous savons que les arguments de la fonction sont placés dans la pile (remarque: pas réellement sur x64, ils sont placés dans des registres puis sur la pile, mais ils sont littéralement sur la pile sous x86) et ce que cet avertissement dit, c’est que la création d’une référence à une telle un objet n'est pas une bonne idée, car il n'est pas garanti d'être laissé en place. Le fait est que c'est juste de la chance.

Alors qu'est-ce qui donne? Essayez cette version modifiée:

#include <iostream>

using namespace std;

int& function(int& f)
{
    f=f+3;
    return f;
}

int main(int argc, char** argv)
{
    int x = 7;
    int y;
    y = function(x);
    cout << "Input: " << x << endl;
    cout << "Output:" << y << endl;
    return 0;
}

Exécutez ceci et vous verrez que les deux valeurs sont mises à jour. Quoi? Eh bien, les deux font référence à la même chose et cette chose est en cours de modification. 

4
user257111

Il renvoie une référence à une variable int.

1
trojanfoe

Des commentaires d'Alfred

C’est ce que dit le document, Les intrinsèques du compilateur C/C++ TMS320C28x de l’instrument Texas , page 122, int & __ octet (int, unsigned int), je suppose qu’il est différent de PC - Alfred Zhong

Du manuel:

int & __ byte (int * tableau, unsigned int byte_index); 

Tableau MOVB [byte_index] .LSB, src

L'unité adressable la plus basse en C28x est de 16 bits. Par conséquent, vous ne pouvez normalement pas accéder à MOVB dst 8 bits, array [byte_index]. Les entités LSB se trouvant hors d'un emplacement de mémoire. Cet élément intrinsèque permet d'accéder à une quantité de 8 bits à partir d'un emplacement de mémoire et peut être appelé comme suit:

__byte (array, 5) = 10;
b = __byte (array, 20);

Cela signifie simplement que la fonction renvoie une référence à un entier qui agit comme une quantité de 8 bits. Parce que la valeur est une référence, modifier modifiera l’objet à la destination (tout comme le MOVB), tandis que l’assignation à b le copiera (comme le MOVB) dans le destinataire.

1
Martin York

Cette question n’est pas du tout C/C++, car C n’a pas de références, seulement des pointeurs. Un int & est une référence à un int. De plus, vous n'avez pas besoin de void, cela peut simplement être int& foo();

0
Puppy

juste jouer avec des variables pour vous montrer le sens

int i = 5;
int * pI = &i;
int & referenceToI = * pI;
referenceToI = 4; // now i == 4

EDIT: Les références ne sont qu'un sucre syntaxique pour faciliter la gestion des pointeurs. au niveau de l'assembly, le code généré par le compilateur renvoie à vous un pointeur d'adresse

0
Stephane Rolland