2011-01-07 12 views
13

A C++ pregunta,¿Qué int & media

int* foo(void) 

foo devolverá un puntero a int tipo

¿qué tal

int &foo(void) 

lo que hace que el retorno ?

¡Muchas gracias!

+0

También es bueno saber: http://stackoverflow.com/questions/2139224/how-to-pass-objects-to-functions-in-c –

Respuesta

1

Devuelve una referencia a una variable int.

+0

No necesita ser una variable (lo que implica que se llama) . Devuelve una referencia a un objeto int. –

27

Devuelve referencia a una int. Las referencias son similares a punteros pero con algunas distinciones importantes. Recomiendo que leas las diferencias entre punteros, referencias, objetos y tipos de datos primitivos.

"C++ efectivo" y "C++ más efectivo" (ambos de Scott Meyers) tienen algunas buenas descripciones de las diferencias y cuándo usar punteros contra referencias.

EDITAR: Hay una serie de respuestas que dicen cosas como "las referencias son simplemente azúcar sintáctico para un manejo más fácil de los punteros". Ciertamente son no.

Consideremos el siguiente código:

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 línea p = pointerToB cambia el valor de p, es decir, que ahora apunta a una parte diferente de la memoria.

r = referenceToB hace algo completamente diferente: asigna el valor de b a donde estaba el valor de a. Hace no cambio r en absoluto. r sigue siendo una referencia a la misma pieza de memoria.

La diferencia es sutil pero muy importante.

Si aún cree que las referencias son solo azúcar sintáctico para el manejo del puntero, entonces por favor lea los libros de Scott Meyers. Él puede explicar la diferencia mucho mejor que yo.

+1

+1 para libros de Scott Meyers. Debe tener para cualquier persona que quiera tener una buena comprensión de C++. – Matthieu

+1

Sí, ambos son libros excelentes. ¡Me enseñó todo lo que sé! –

+0

Las variables de referencia son, por lo tanto, una sintaxis alternativa para * const * punteros. – Bento

0

Esta pregunta no es C/C++ en absoluto, ya que C no tiene referencias, solo apuntadores. Un int & es una referencia a un int. Además, no es necesario void, que sólo puede ser int& foo();

+0

Esto es lo que dice el documento, intrínsecos del compilador TMS320C28x C/C++ del instrumento de Texas, http://focus.ti.com/lit/ug/spru514c/spru514c.pdf, página 122, int & __ byte (int, unsigned int), supongo que es diferente de PC –

+0

@Alfred: No, realmente no. Los lenguajes C y C++ no tienen versiones integradas especiales. El manual está mal, y eso es todo. – Puppy

+0

@Alfred Zhong. No, la documentación dice lo mismo que todos los demás aquí. –

0

simplemente jugando con las variables que le muestre el significado

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

EDITAR: Las referencias son sólo un azúcar sintáctica para los punteros uso más sencillo. en el nivel de ensamblado, el código generado por el compilador le devuelve un puntero de dirección

+0

¡Gracias! Yo se esto. Lo que me confunde es cuando se usa en la declaración de funciones, como int y foo (...), ¿qué devuelve la función? –

+0

Devuelve una referencia a lo que pone después de 'return'. –

+0

No hay retorno, creo que es lenguaje ensamblador dentro de él, MOVB array [byte_index] .LSB, src, no tengo idea de lo que significa –

3

Tenga cuidado aquí ... está caminando por la línea C/C++.Hay una distinción bastante clara, pero no siempre aparece de esa manera:

C++: esto a menudo significa una referencia. Por ejemplo, considere:

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

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

Como tal, C++ puede pasar por valor o pass by reference.

C Sin embargo, no tiene dicho paso por función de referencia. & significa "dirección de" y es una forma de formular un puntero a partir de una variable. Sin embargo, considere esto:

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

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

Deceptively similar, yet fundamentalmente different. Lo que está haciendo en C está pasando una copia del puntero. Ahora, estas cosas aún apuntan a la misma área de memoria, por lo que el efecto es como un pase por referencia en términos de la memoria apuntada, pero no es una referencia que se transmite. Es una referencia a un punto en la memoria.

Prueba esto (Compilar como 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 tenía pasan por referencia, la dirección del puntero entrante, cuando se cambió por addptr debe reflejarse en main, pero no lo es. Los punteros siguen siendo valores.

Por lo tanto, C hace no tenga cualquier pase por mecanismo de referencia. En C++, esto existe, y eso es lo que significa & en argumentos de funciones, etc.

Editar: Usted se estará preguntando por qué no puedo hacer esta demostración en C++ fácilmente. Es porque no puedo cambiar la dirección de la referencia. En absoluto. Desde t his quite good guide to references:

How can you reseat a reference to make it refer to a different object?

No way.

You can't separate the reference from the referent.

Unlike a pointer, once a reference is bound to an object, it can not be "reseated" to another object. The reference itself isn't an object (it has no identity; taking the address of a reference gives you the address of the referent; remember: the reference is its referent).

In that sense, a reference is similar to a const pointer such as int* const p (as opposed to a pointer to const such as int const* p). But please don't confuse references with pointers; they're very different from the programmer's standpoint.

Por petición, en las referencias que regresan:

#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; 
} 

Cualquier buen compilador debe le da a este mensaje de advertencia en alguna forma:

exp.cpp: 7: 11 : advertencia: referencia a la memoria de pila asociada con la variable local 'f' devuelta

¿Qué significa esto? Bueno, sabemos que los argumentos de función se insertan en la pila (nota: no en x64, van a los registros, luego a la pila, pero están en la pila literalmente en x86) y lo que esta advertencia dice es que crear una referencia a tales un objeto no es una buena idea, porque no se garantiza que quede en su lugar. El hecho es que es solo suerte.

¿Qué ofrece? Pruebe esta versión modificada:

#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; 
} 

Ejecute esto y verá que ambos valores se actualizan. ¿Qué? Bueno, ambos se refieren a lo mismo y esa cosa está siendo editada.

+1

¡Muchas gracias! Lo sé en C & foo, y si foo es un int, será la dirección de foo, y se puede pasar a int * type. Lo que estoy confundido es cuando se usa en la declaración de funciones, int & foo (...), ¿qué significa eso? –

+0

"Lo que estás haciendo en C es pasar una copia del puntero". No, no lo estás; estás pasando el * valor * de la * dirección * de la variable local 'x' a' func' como un argumento * puntero *. En ese momento, no hay otros indicadores para que no pueda copiar uno. En el ejemplo de C++ está pasando una variable 'x' a una función que toma un argumento * reference *, entonces lo que obtiene es una referencia a' x'. La implementación de estos es (probablemente) la misma: la dirección de 'x' se inserta en la pila. IOW C * does * le permite usar semántica de referencia, pero no proporciona sintaxis para admitirlos. – dajames

+0

Sí, está pasando una * copia * del valor del puntero - una * copia del puntero *. Un puntero es una dirección de memoria en sí misma (por lo tanto, una "variable") que contiene otra dirección de memoria. Adjunta 'gdb' a un proceso y podrás ver esto. Por lo tanto, el acto de copiarlo es asignar un nuevo espacio de memoria y poner el valor. Esto es lo que significa pasar por valor. –

1

De los comentarios de Alfred

This is what the document says, Texas instrument's TMS320C28x C/C++ compiler intrinsics , page 122, int&__byte(int, unsigned int), I guess it is different from PC – Alfred Zhong

Del manual:

int &__byte(int *array, unsigned int byte_index);

MOVB array[byte_index].LSB, src

The lowest adressable unit in C28x is 16 bits. Therefore, normally you cannot access 8-bit MOVB dst, array[byte_index]. LSB entities off a memory location. This intrinsic helps access an 8-bit quantity off a memory location, and can be invoked as follows:

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

Esto sólo significa que la función devuelve una referencia a un número entero que actúa como una cantidad de 8 bits. Como el valor es una modificación de referencia, modificará el objeto en el destino (al igual que la instrucción MOVB), mientras que la asignación a b se copiará (al igual que MOVB) al destino.

+0

Gracias Martin, estoy confundido porque hice exactamente lo que dice el manual, __byte (array, 5) = 10, y el compilador sigue quejándose "error: la expresión debe ser un lvalue modificable" –

Cuestiones relacionadas