web-dev-qa-db-fra.com

Modification de l'adresse contenue par le pointeur à l'aide de la fonction

Si j'ai déclaré un pointeur p comme int *p; dans le module principal, je peux changer l'adresse contenue par p en affectant p=&a;a est une autre variable entière déjà déclarée. Je veux maintenant changer l'adresse en utilisant une fonction comme ::

void change_adrs(int*q)
{
    int *newad;
    q=newad;
}

Si j'appelle cette fonction depuis le module principal

int main()
{
    int *p;
    int a=0;
    p=&a; // this changes the address contained by pointer p
    printf("\n The address is %u ",p);
    change_adrs(p);
    printf("\n the address is %u ",p); // but this doesn't change the address
    return 0;
}

le contenu de l'adresse est inchangé. Quel est le problème avec l'utilisation d'une fonction pour la même tâche?

31
pranphy

En C, les arguments des fonctions sont passés par valeur. Ainsi, une copie est faite de votre argument et la modification est apportée à cette copie, pas au pointeur réel que vous vous attendez à voir modifié. Vous devrez modifier votre fonction pour accepter un argument de pointeur double et apporter la modification à l'argument déréférencé si vous souhaitez le faire. Par exemple

 void foo(int** p) {
      *p = 0;  /* set pointer to null */
 }
 void foo2(int* p) {
      p = 0;  /* makes copy of p and copy is set to null*/
 }

 int main() {
     int* k;
     foo2(k);   /* k unchanged */
     foo(&k);   /* NOW k == 0 */
 }

Si vous avez le luxe d'utiliser C++, une autre façon serait de changer la fonction pour accepter une référence à un pointeur.

37
mathematician1975

En C, les variables sont passées par valeur - une copie du pointeur est passée à la fonction. Utilisez un autre pointeur sur le pointeur à la place:

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);

Cela imprime

*p = 1
*p = 2
12
user529758

Si vous voulez modifier le contenu d'une variable dans une fonction en C, le pointeur est aussi une sorte de variable, vous devez le passer par pointeur ou référence indirecte en utilisant toujours & et * opérateurs de déréférencement. Je veux dire que l'opérateur * Est toujours utilisé et précédé lors du changement de la valeur d'une 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;

}
2
snr

Pour un type de données primitif tel qu'un int, les pointeurs doubles ne sont pas nécessaires. Vous pouvez écrire directement dans l'adresse où le int est stocké, en traitant son adresse comme un pointeur dans la fonction appelée. C'est différent d'un tableau char ("chaîne") où la taille de ce qui est pointé est variable et vous devez donc utiliser un autre niveau d'indirection lorsque vous le changez depuis une fonction appelée. Essaye ça:

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

Cela ne changera pas la valeur réelle de p car la fonction q in est locale à cela et le changement dans cette fonction ne se reflétera pas dans main donc passez l'adresse de p au lieu de passer p par valeur

Utilisez cette syntaxe ci-dessous

  void change_adrs(int **q)
  {
  int * otheraddess;
  *q = otheraddress; 
  }

et appeler comme ceci change_adrs(&p);

Ou, vous avez une autre solution: changez le type de fonction de retour et récupérez l'adresse retournée.

int* change_adrs(int *q)
      {
      int * otheraddess;
      q = otheraddress;
      return q; 
      }


int main()
{
 p=change_adrs(p);
 return 0;
}
0
Omkant