вернуть адрес двойного - PullRequest
       8

вернуть адрес двойного

1 голос
/ 01 апреля 2010

У меня проблема с пониманием, почему работает следующее:

void doubleAddr(double* source, double** dest)
{
     *dest = source;
}

я получаю указатель на двойное число и хочу изменить двойное значение, на которое указывает dest:

//usage:
int main()
{
     double* num;
     double* dest;

     doubleAddr(num, &dest);
     return 0;
}

спасибо заранее

Ответы [ 6 ]

4 голосов
/ 01 апреля 2010

Вы не правильно используете указатели. Начнем с того, что вы ничего не инициализируете в main(), так что это довольно опасно. Ваш код для doubleAddr() правильный, но он копирует указатель, а не двойной. Если вы пытаетесь скопировать число через указатель, вам нужно что-то вроде:

void copyDouble(double source, double *dest)
{
    *dest = source;
}

int main()
{
    double num = 5.6;
    double dest;

    copyDouble(num, &dest);

    printf("%f\n", dest);
    return 0;
}

Вы можете добавить больше * или &, если вы пытаетесь сделать что-то другое.

1 голос
/ 01 апреля 2010

Давайте сделаем шаг за шагом:

  • doubleAddr работает, потому что double** dest является указателем на указатель. Это не самый лучший способ сделать это, но это хорошее учебное упражнение.

  • Вы передаете адрес dest с помощью &dest, который затем возвращается к двойному указателю, когда вы говорите *dest.

  • Поскольку source также является «двойным» указателем, *dest = source просто работает.

Кстати, ваша программа не завершена. Если вы хотите проверить это, вам нужно изменить его, например:

int main()
{
 double* num;
 double* dest;
 double test;
 num = &test;

 doubleAddr(num, &dest);
 printf("%lf\n", *dest);
 return 0;
}
1 голос
/ 01 апреля 2010

Функция работает, потому что вы на самом деле не обращаетесь к той памяти, на которую она указывает. Вы просто назначаете переменную-указатель назначения так, чтобы она указывала на тот же адрес памяти, что и переменная-указатель источника, и ничего более. Поскольку ваша переменная 'num' на самом деле не указывает на допустимое двойное значение в памяти, ваш код будет иметь плохое поведение, если впоследствии вы попытаетесь разыменовать указатель, поскольку он указывает на случайную память. Другими словами:

int main() 
{ 
     double* num; // <- uninitialized, points at random memory
     double* dest; 

     doubleAddr(num, &dest); 
     // 'dest' now points to the same address that 'num' points to

     *dest = 12345.0; // BAD!!!!

     return 0; 
} 

Правильный способ заставить код работать следующим образом:

int main() 
{ 
     double num; // <- physical value in memory
     double* dest; 

     doubleAddr(&num, &dest); 
     // 'dest' now points at 'num'

     *dest = 12345.0; // OK! 'num' is updated correctly    

     return 0; 
} 
1 голос
/ 01 апреля 2010

В вашей функции source является указателем на двойное число. dest - указатель на указатель на двойное число.

*dest = source

разыменовывает dest один раз (делая его указателем на двойное число) и устанавливает его на source.

В main(), dest - это указатель на double, и вы берете его адрес при вызове doubleAddr, делая его указателем на указатель на double.

0 голосов
/ 01 апреля 2010

Во-первых, я удивлен, что это сработало - это сводится к удаче «удачи» ... поскольку переменные указывают на что-то, это сработало в первый раз, в следующий раз, возможно, вам не повезет, худшим будет код сбой!

Чтобы оценить это, попробуйте следующее:

Вызов doubleAddr правильный, но ... вы не выделили память для переменных num и dest, измените параметры немного, как показано ниже.

double num = 5.0F;
double dest = 0.0F;

doubleAddr(num, &dest);

Затем измените параметры для doubleAddr

void doubleAddr(double source, double* dest)
{
     *dest = source;
}

Обратите внимание, что dest будет иметь значение '5.0', то есть параметр обращения по ссылке, который принимает адрес переменной dest.

0 голосов
/ 01 апреля 2010

В первой функции source это указатель на double, а dest это указатель на указатель на double, который может быть изменен функцией.

Задание

  *dest = source; 

изменяет копию вызывающей стороны Dest.

И, да, main называет это неинициализированными данными. Мусор на входе, мусор на выходе.

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