Функции и указатель на указатели - PullRequest
2 голосов
/ 16 октября 2010

Я пытался создать переменную-указатель в вызываемой функции и каким-то образом передать значение, указанное им, в основную функцию. Я написал несколько примеров программ, но я все еще что-то упускаю. и задача состояла в том, чтобы достичь этого, используя указатели на указатели на указатели. Вот код, который я написал и протестировал. Я думаю, что упускаю что-то очевидное, можете ли вы, ребята, указать на это. Спасибо.

        int one(int ***ptr)
        {
            static int *p,**pp,b=10;
            p=&b;
            pp=&p;
            ptr=&pp;
            printf("b:%d\tp:%d\tpp:%d\n",b,*p,**pp);
            printf("Sub Ptr:%d\n",***ptr);
            printf("Address of ***ptr:%d\n",&ptr);
            return 32;
        }
        int main(int argc, char *argv[])
        {
              static int ***ptr;
              int a=200,*b,**c;
              b=&a;
              c=&b;
              ptr=&c;
              printf("Main Ptr:%d\n",&ptr);
              a=one(ptr);
              printf("Main Ptr:%d\n",&ptr);
              printf("Main Ptr:%d\n",***ptr);
              system("PAUSE");
              return 0;
        }

Я получаю вывод 32, который является возвращаемым значением функции. Можно ли получить значение 10, которое указано в вызываемой функции.

Я также пробовал глобальное объявление, но тоже работает. Я хотел бы сохранить местную декларацию и посмотреть, возможно ли это ...

Ответы [ 2 ]

4 голосов
/ 16 октября 2010

Я думаю, вы неправильно поняли указатели.Проблема вашего кода заключается в том, что вы не понимаете, что указатель также «передается по значению», указатель в функции - это другая переменная в стеке, а не та, которую вы объявляете в основной функции.

Я бы использовал более простой пример, но идея та же.

void changePointerValue (int * ptr) 
{
    int newValue = 10;
    ptr = &newValue;
}

int main () 
{
    int x = 20;
    int * ptr = &x;
    changePointerValue (ptr);
    printf ("After Change: %d\n", *ptr);
}

Какое значение, по вашему мнению, будет выводиться в основной функции?Это будет 10?

Но нет, на самом деле, он выдаст 20.

Почему?Давайте посмотрим, что делает наш код.В строке chagePointerValue (ptr) компьютер скопирует значение ptr в основной функции в новое переменное в стеке, назовем его ptr 'и передадим его в функцию changePointerValue.

Таким образом, фактически ptr в функции changePointerValue - это ptr ', а не тот, который вы объявляете в основной функции.Во второй строке changePointerValue вы назначили новый адрес памяти для ptr ', а после этого ptr' отбрасывается, потому что функция возвращается.Значение ptr в основной функции остается тем же значением, то есть адресом памяти, указанным на x.

Если вы хотите, чтобы вывод был равен 10, вам нужно задавать ptr в changePointerValue, и назначение будет означать «Изменитьзначение, на которое указывает ptr '.

void changePointerValue (int * ptr) 
{
    int newValue = 10;
    *ptr = newValue;   // Now you are change the content of the memroy cell where ptr is pointed at.
}

int main () 
{
    int x = 20;
    int * ptr = &a;
    printf ("Before Change:%d", x); // 20
    printf ("Before Change:%d", *ptr); // 20
    changePointerValue (ptr);
    printf ("After Change: %d\n", *ptr); // 10
    printf ("After Change: %d\n", x); //10
}

Редактировать:

Итак, если вы хотите, чтобы в основной функции было напечатано 10, правильный способ сделать этоуважение ptr в функции.Но это также изменит значение переменной a в главной функции.

    int one(int ***ptr)
    {
        ***ptr=10; // Dereference ptr to where it points to. (Varaible a in the main function)
        return 32;
    }
    int main(int argc, char *argv[])
    {
          static int ***ptr;
          int a=200,*b,**c;
          int result;
          b=&a;
          c=&b;
          ptr=&c;
          printf("Main Ptr:%d\n",&ptr); // The memory address of variable ptr.
          result=one(ptr);
          printf("Main Ptr:%d\n",&ptr); // the memory address of variable ptr.
          printf("Main Ptr:%d\n",***ptr); // 10
          printf("Main a:%d\n", a); // 10
          printf("Main result:%d\n", result); //32
          system("PAUSE");
          return 0;
    }
1 голос
/ 16 октября 2010

Вы устанавливаете ptr на адрес адреса локальной адресной переменной (b), который выходит из области видимости в конце функции.Это неопределенное поведение.Вам нужно либо присвоить ***ptr, либо malloc что-то в куче.

Кроме того, вы передаете ptr по значению функции.Поэтому любые локальные изменения в нем не будут отражены в main.Вам нужно передать указатель, то есть вам понадобится int **** в качестве аргумента.

Я действительно надеюсь, что это не что иное, как учебное упражнение, потому что любой более двух уровней указателей обычно указывает, чтодизайн действительно нуждается в переоценке!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...