pranfia
Si he declarado un puntero p
como int *p
; en el módulo principal, puedo cambiar la dirección contenida por p
asignando p = &a;
donde a
es otra variable entera ya declarada. Ahora quiero cambiar la dirección usando una función como:
void change_adrs(int*q)
{
int *newad;
q = newad;
}
Si llamo a esta función desde el módulo principal
int main()
{
int *p;
int a = 0;
p = &a; // this changes the address contained by pointer p
printf("The address is %u\n", p);
change_adrs(p);
printf("The address is %u\n", p); // but this doesn't change the address
return 0;
}
el contenido de la dirección no cambia. ¿Qué tiene de malo usar una función para la misma tarea?
matemático1975
En C, los argumentos de las funciones se pasan por valor. Por lo tanto, se hace una copia de su argumento y el cambio se realiza en esa copia, no en el objeto de puntero real que espera ver modificado. Deberá cambiar su función para aceptar un argumento de puntero a puntero y realizar el cambio en el argumento desreferenciado si desea hacer esto. Por ejemplo
void foo(int** p) {
*p = NULL; /* set pointer to null */
}
void foo2(int* p) {
p = NULL; /* makes copy of p and copy is set to null*/
}
int main() {
int* k;
foo2(k); /* k unchanged */
foo(&k); /* NOW k == NULL */
}
Si tiene el lujo de usar C++, una forma alternativa sería cambiar la función para aceptar una referencia a un puntero.
-
Solo me gustaría señalar que el estándar C no garantiza que asignar p a 0 lo haga nulo.
– JKRT
17 de noviembre de 2017 a las 20:28
-
si yo fuera a
*arr = malloc()
una nueva matriz en la función llamada y el punto**p
a eso, es*p = &arr
?– mlestudiante33
6 de julio de 2020 a las 5:45
-
@JKRT: 6.2.3.2 en la especificación C dice “Una expresión constante de entero con el valor 0, o una expresión de este tipo convertida en tipo void *, se denomina constante de puntero nulo”. — por lo que asignar un 0 literal lo hará nulo. El ‘o’ en esa oración significa que no es necesario moldear.
– Chris Dodd
16 de noviembre de 2020 a las 22:51
En C, las variables se pasan por valor: se pasa una copia del puntero a la función. Use otro puntero al puntero en su lugar:
void change(int **p, int *someOtherAddress)
{
*p = someOtherAddress;
}
int a = 1, b = 2;
int *p = &a;
printf("*p = %d\n", *p);
change(&p, &b);
printf("*p = %d\n", *p);
esto imprime
*p = 1
*p = 2
-
Vote a favor simplemente porque esta respuesta evita la frase “doble puntero”
– William Pursell
5 de agosto de 2020 a las 22:49
gruñido
Si desea modificar el contenido de una variable en una función en C, el puntero también es un tipo de variable, debe pasarlo por puntero o referencia indirecta usando siempre &
dirección y *
operadores de desreferencia. quiero decir *
El operador siempre se usa y va precedido al cambiar el valor de una variable.
#include <stdio.h>
#include <stdlib.h>
void changeIntVal(int *x) {
*x = 5;
}
void changePointerAddr(int **q) {
int *newad;
*q = newad;
}
void changePPAddr(int ***q) {
int **dummy;
*q = dummy;
}
int main() {
int *p;
int **pp;
int *tempForPP;
int a = 0;
printf("\n The address pointing by p -> %p, pp -> %p, value of a -> %d ", p, pp, a);
p = &a;
pp = &tempForPP;
printf("\n The address pointing by p -> %p, pp -> %p, value of a -> %d ", p, pp, a);
changeIntVal(&a); // ----
// |---
changePointerAddr(&p); // ---- |----> parts of what I mean
// |---
changePPAddr(&pp); // ----
printf("\n The address pointing by p -> %p, pp -> %p, value of a -> %d ", p, pp, a);
return 0;
}
Para un tipo de datos primitivo como un int
, los punteros dobles no son necesarios. Puede escribir directamente a la dirección donde se encuentra el int
se almacena, tratando su dirección como un puntero en la función que se llama. Esto es diferente a un char
matriz (“cadena”) donde el tamaño de lo que se apunta es variable y, por lo tanto, debe usar otro nivel de direccionamiento indirecto al cambiarlo desde dentro de una función llamada. Prueba esto:
void foo(int *oldVal)
{
int newVal = 99; // or whatever you want
*oldVal = newVal;
}
int main(int argc, char *argv[])
{
int someVal = 0;
foo(&someVal); // we send its address to foo()
printf("someVal is now %d.\n", someVal);
return EXIT_SUCCESS;
}
Omkant
Esto no cambiará el valor real de p
porque el q
en función es local a eso y el cambio en esa función no se reflejará en main
así que pasa la dirección de p
en lugar de pasar p
por valor
Use esta sintaxis a continuación
void change_adrs(int **q)
{
int * otheraddess;
*q = otheraddress;
}
y llamar asi change_adrs(&p);
O bien, tiene otra forma: cambie el tipo de devolución de la función y capture la dirección devuelta.
int* change_adrs(int *q)
{
int * otheraddess;
q = otheraddress;
return q;
}
int main()
{
p = change_adrs(p);
return 0;
}
Está pasando el puntero por valor. Si necesita cambiar el puntero dentro de la función, páselo por referencia… doble puntero.
– Alok Guardar
17 de noviembre de 2012 a las 13:43