Estoy empezando con punteros y estoy un poco confundido. Sé que &
significa la dirección de una variable y que *
se puede usar frente a una variable de puntero para obtener el valor del objeto al que apunta el puntero. Pero las cosas funcionan de manera diferente cuando trabaja con matrices, cadenas o cuando llama a funciones con una copia de puntero de una variable. Es difícil ver un patrón de lógica dentro de todo esto.
¿Cuándo debo usar &
y *
?
RTFM
es inútil y, francamente, muy grosero. Si no tiene tiempo para responder, sea respetuoso con quienes se toman el tiempo para responder estas preguntas. Desearía poder @ esto para "anon", pero obviamente él / ella no tiene el tiempo para contribuir de manera significativa.Respuestas:
Tienes punteros y valores:
Convierte un puntero en un valor con
*
:Convierte un valor en un puntero con
&
:Editar: en el caso de las matrices, se tratan mucho como punteros. Si los considera punteros, los usará
*
para obtener los valores dentro de ellos como se explicó anteriormente, pero también hay otra forma más común de usar el[]
operador:Para obtener el segundo elemento:
Entonces, el
[]
operador de indexación es una forma especial del*
operador, y funciona así:fuente
int aX[] = {3, 4}; int *bX = &aX;
int *bX = &aX;
no funciona porqueaX
ya devuelve la dirección deaX[0]
(es decir&aX[0]
), por&aX
lo que obtendría la dirección de una dirección que no tiene sentido. ¿Es esto correcto?int aX[] = {3,4};
,int **bX = &aX;
es un error.&aX
es de tipo "puntero a matriz [2] deint
", no "puntero a puntero aint
". Específicamente, el nombre de una matriz no se trata como un puntero a su primer elemento para unario&
. Puedes hacer:int (*bX)[2] = &aX;
Hay un patrón cuando se trata de matrices y funciones; Es un poco difícil de ver al principio.
Cuando se trata de matrices, es útil recordar lo siguiente: cuando una expresión de matriz aparece en la mayoría de los contextos, el tipo de la expresión se convierte implícitamente de "matriz de elementos N de T" a "puntero a T", y su valor se establece para apuntar al primer elemento en la matriz. Las excepciones a esta regla son cuando la expresión de matriz aparece como un operando ya sea del
&
o desizeof
los operadores, o cuando se trata de una cadena literal de ser utilizado como un inicializador en una declaración.Por lo tanto, cuando llama a una función con una expresión de matriz como argumento, la función recibirá un puntero, no una matriz:
Es por eso que no utiliza el
&
operador para argumentos correspondientes a "% s" enscanf()
:Debido a la conversión implícita,
scanf()
recibe unchar *
valor que apunta al comienzo de lastr
matriz. Esto es válido para cualquier función llamada con una expresión de matriz como argumento (casi cualquiera de lasstr*
funciones*scanf
y*printf
funciones, etc.).En la práctica, probablemente nunca invocará una función con una expresión de matriz utilizando el
&
operador, como en:Tal código no es muy común; debe conocer el tamaño de la matriz en la declaración de la función, y la función solo funciona con punteros a matrices de tamaños específicos (un puntero a una matriz de 10 elementos de T es un tipo diferente que un puntero a una matriz de 11 elementos de T).
Cuando una expresión de matriz aparece como un operando para el
&
operador, el tipo de la expresión resultante es "puntero a la matriz de elementos N de T", oT (*)[N]
, que es diferente de una matriz de punteros (T *[N]
) y un puntero al tipo base (T *
)Cuando se trata de funciones y punteros, la regla a recordar es: si desea cambiar el valor de un argumento y hacer que se refleje en el código de llamada, debe pasar un puntero a lo que desea modificar. Una vez más, las matrices arrojan un poco de una llave inglesa en las obras, pero primero nos ocuparemos de los casos normales.
Recuerde que C pasa todos los argumentos de función por valor; el parámetro formal recibe una copia del valor en el parámetro real, y cualquier cambio en el parámetro formal no se refleja en el parámetro real. El ejemplo común es una función de intercambio:
Obtendrá el siguiente resultado:
Los parámetros formales
x
yy
son objetos distintos dea
yb
, por lo que cambiax
yy
no se refleja ena
yb
. Como queremos modificar los valores dea
yb
, debemos pasarles punteros a la función de intercambio:Ahora su salida será
Tenga en cuenta que, en la función de intercambio, no cambiamos los valores de
x
yy
, sino los valores de whatx
yy
point to . Escribir en*x
es diferente de escribir enx
; no estamos actualizando el valor enx
sí mismo, obtenemos una ubicaciónx
y lo actualizamos en esa ubicación.Esto es igualmente cierto si queremos modificar un valor de puntero; si escribimos
entonces estamos modificando el valor del parámetro de entrada
stream
, no lo questream
apunta , por lo que cambiarstream
no tiene efecto sobre el valor dein
; Para que esto funcione, debemos pasar un puntero al puntero:Una vez más, las matrices arrojan un poco de una llave inglesa en las obras. Cuando pasa una expresión de matriz a una función, lo que recibe la función es un puntero. Debido a cómo se define la suscripción de matriz, puede usar un operador de subíndice en un puntero de la misma manera que puede usarlo en una matriz:
Tenga en cuenta que los objetos de matriz pueden no asignarse; es decir, no puedes hacer algo como
por lo tanto, debe tener cuidado cuando trabaje con punteros a matrices; algo como
no funciona
fuente
En pocas palabras
&
significa la dirección de , verá que en los marcadores de posición para que las funciones modifiquen la variable del parámetro como en C, las variables de parámetro se pasan por valor, utilizando los medios y los medios para pasar por referencia.*
significa la desreferencia de una variable de puntero, lo que significa obtener el valor de esa variable de puntero.El ejemplo anterior ilustra cómo llamar a una función
foo
mediante el uso de paso por referencia, compárelo con estoAquí hay una ilustración del uso de una desreferencia
Lo anterior ilustra cómo obtuvimos la dirección
y
y la asignamos a la variable de punterop
. Luego, desreferenciamosp
uniendo el*
frente al mismo para obtener el valor dep
, es decir*p
.fuente
Sí, eso puede ser bastante complicado ya que
*
se usa para muchos propósitos diferentes en C / C ++.Si
*
aparece delante de una variable / función ya declarada, significa que:*
da acceso al valor de esa variable (si el tipo de esa variable es un tipo de puntero o sobrecargado al*
operador).*
tiene el significado del operador de multiplicación, en ese caso, tiene que haber otra variable a la izquierda del*
Si
*
aparece en una declaración de variable o función, significa que esa variable es un puntero:Si
&
aparece en una declaración de variable o función, generalmente significa que esa variable es una referencia a una variable de ese tipo.Si
&
aparece delante de una variable ya declarada, devuelve la dirección de esa variableAdemás, debe saber que al pasar una matriz a una función, siempre tendrá que pasar el tamaño de la matriz también, excepto cuando la matriz sea algo así como una cadena de caracteres terminada en 0 (matriz de caracteres).
fuente
Cuando declare una variable de puntero o parámetro de función, use *:
NB: cada variable declarada necesita su propia *.
Cuando desee tomar la dirección de un valor, use &. Cuando desee leer o escribir el valor en un puntero, use *.
Las matrices generalmente solo se tratan como punteros. Cuando declara un parámetro de matriz en una función, puede declarar con la misma facilidad que es un puntero (significa lo mismo). Cuando pasa una matriz a una función, en realidad está pasando un puntero al primer elemento.
Los punteros de función son las únicas cosas que no siguen las reglas. Puede tomar la dirección de una función sin usar &, y puede llamar a un puntero de función sin usar *.
fuente
Estaba revisando todas las explicaciones profundas, así que en su lugar recurrí a un video de la Universidad de Nueva Gales del Sur para que me rescataran. Aquí está la explicación simple: si tenemos una celda que tiene dirección
x
y valor7
, la forma indirecta de pedir una dirección de valor7
es&7
y la forma indirecta de pedir valor en la direcciónx
es*x
.(cell: x , value: 7) == (cell: &7 , value: *x)
Entonces . Otra forma de verlo: seJohn
sienta en7th seat
. El*7th seat
apuntaráJohn
y&John
daráaddress
/ ubicación del7th seat
. Esta simple explicación me ayudó y espero que también ayude a otros. Aquí está el enlace para el excelente video: haga clic aquí.Aquí hay otro ejemplo:
Complemento: siempre inicialice el puntero antes de usarlos; de lo contrario, el puntero apuntará a cualquier cosa, lo que podría provocar el bloqueo del programa porque el sistema operativo le impedirá acceder a la memoria que sabe que no posee.
p = &x;
, estamos asignando al puntero una ubicación específica.fuente
En realidad, lo tienes claro, no hay nada más que necesites saber :-)
Solo agregaría los siguientes bits:
&
toma una variable y le da la dirección,*
toma una dirección y le da la variable (o contenido).char **p
significa quep
es un puntero a un puntero a unchar
.En cuanto a las cosas que funcionan de manera diferente, en realidad no:
\0
).fuente
Creo que estás un poco confundido. Deberías leer un buen tutorial / libro sobre punteros.
Este tutorial es muy bueno para empezar (explica claramente qué
&
y qué*
son). Y sí, no te olvides de leer el libro Pointers in C de Kenneth Reek.La diferencia entre
&
y*
es muy clara.Ejemplo:
fuente
Ok, parece que tu publicación fue editada ...
¿Ves cómo puedes usar
&
para obtener la dirección del comienzo de la estructura de la matriz? El seguimientoHará lo mismo.
fuente