Каким будет указатель pNext в следующем случае с использованием C? - PullRequest
3 голосов
/ 11 октября 2008
func()
{
    Object* pNext;
    func1(pNext);
}

func1(Object* pNext)
{
    pNext = Segement->GetFirstPara(0);
}

Я ожидал, что это указатель на firstpara, возвращаемый из func1 (), но я вижу, что NULL может кое-что объяснить и как это исправить, чтобы он действительно возвращал указатель firstpara ()?

Ответы [ 5 ]

16 голосов
/ 11 октября 2008

Только для C ++, вы можете сделать параметр ссылкой

func()
{
    Object* pNext;
    func1(pNext);
}

func1(Object*& pNext)
{
    pNext = Segement->GetFirstPara(0);
}

Здесь происходит разница между передачей параметров по значению и передачей по ссылке. C всегда проходит по значению. Чтобы получить значение обратно, оно должно быть ссылочным значением (например, объект ** ссылается на объект * как указатель). C ++ добавляет ссылочные параметры (обозначается символом &). Передача по значению передает только копию данных, а не сами данные. Вот почему переменная, используемая в вызове функции, не была обновлена ​​в функции.

5 голосов
/ 11 октября 2008

В с, вы хотели бы:

func1(&pNext);
func1(Object** pNext) { *pNext = ... }

В С ++

func1(pNext);
func1(Object*& pNext) { pNext = ... }

На любом языке ваш пример передаст неинициализированный Object* в func1, который скопирует его, присвоит значение копии и затем вернет. Обратите внимание, что исходный pNext никогда не изменяется (это поможет, если вы используете разные имена для своих переменных).

На обоих языках вам необходимо явно передавать ссылки, если требуется передача по ссылке, а не передача по значению.

4 голосов
/ 11 октября 2008

Чтобы изменить указатель, вам нужно передать указатель на указатель, т.е. Object** pNext. Чтобы изменить значение переменной внутри функции, вы передаете указатель. Следовательно, для расширения значения указателя внутри функции передайте указатель на указатель.

func() { 
    Object* pNext;
    func1(&pNext);
}

func1(Object** pNext) { *pNext = Segement->GetFirstPara(0); }
1 голос
/ 11 октября 2008

Пожалуйста, инициализируйте pNext, когда вы его создадите. Это может быть NULL сейчас, когда вы отлаживаете, но в поле это будет 0x12AbD468 или что-то в этом роде. Если у вас есть тест, как:

if( NULL != pNext )
{
  pNext->DoSomething();
}

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

В вашем случае, так как 'func1 ()' не использует pNext в качестве параметра, вы можете просто вернуть его из функции:

func()
{
  Object *pNext = func1();
}

Object* func1()
{
  return Segment->GetFirstPara(0);
}
0 голосов
/ 11 октября 2008

должно быть


func()
{
  Object *pNext;
  func1(&pNext);
}

void func1(Object **pNext)
{
  *pNext = Segment->GetFirstPara(0);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...