Подтвердить что ты не робот

Изменение адреса, содержащегося в указателе с использованием функции

Если я объявил указатель p как int *p; в основном модуле я могу изменить адрес, содержащийся в p, назначив p=&a;, где a - еще одна объявленная целочисленная переменная. Теперь я хочу изменить адрес, используя функцию as::

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

Если я вызываю эту функцию из основного модуля

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

содержимое адреса не изменяется. Что неправильно с использованием функции для одной задачи?

4b9b3361

Ответ 1

В C аргументы функций передаются по значению. Таким образом, создается копия вашего аргумента, и в нее вносятся изменения, а не фактический указатель, который вы ожидаете увидеть измененным. Вам нужно будет изменить свою функцию так, чтобы она принимала аргумент с двойным указателем и вносила изменения в аргумент разыменованного, если вы хотите это сделать. Например,

 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 */
 }

Если у вас есть возможность использовать C++, альтернативным способом было бы изменить функцию, чтобы она принимала ссылку на указатель.

Ответ 2

В C переменные передаются по значению - копия указателя передается функции. Вместо этого используйте другой указатель на указатель:

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

Отпечатает

*p = 1
*p = 2

Ответ 3

Если вы хотите изменить содержимое переменной в функции в C, указатель также является своеобразной переменной, вам нужно передать ее указателем или косвенной ссылкой, используя всегда & address и * операторы разыменования, Я имею в виду, что оператор * всегда используется и предшествует при изменении значения переменной.

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

}

Ответ 4

Для примитивного типа данных, такого как int, двойные указатели не нужны. Вы можете писать непосредственно в адрес, где хранится int, обрабатывая его адрес как указатель вызываемой функции. Это не похоже на массив char ( "строка" ), где размер указателя на него является переменным, и поэтому вы должны использовать другой уровень косвенности при его изменении из вызываемой функции. Попробуйте следующее:

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

Ответ 5

Это не изменит фактическое значение p, поскольку функция q in является локальной для этого, и изменение этой функции не отразится на main, поэтому передайте адрес p вместо передачи p по значению

Используйте этот синтаксис ниже

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

и назовите это change_adrs(&p);

Или у вас есть другой путь: изменить возвращаемый тип функции и уловить возвращенный адрес.

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


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