2009-11-23 3 views
1

Я рассматриваю пример учебника связанного списка, который реализует стек. Я не понимаю, почему для операции push требуется использование указателя на указатель на стек. Смотрите следующий пример:Зачем использовать указатель на указатель на стек при создании функции push?

bool push(Element **stack, void *data) 
{ 
    Element *elem = new Element; 
    if(!elem) return false; 

    elem->data = data; 
    elem->next = *stack; 
    *stack = elem; 
    return true; 
} 

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

Удивительно, спасибо вам за отличную помощь.

+0

C Безразлично у меня есть новый k eyword. C++ делает. Тем не менее, C++ с вызовом исключения при неспособности выделить память, нет необходимости проверять значение null. – GManNickG

+0

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

ответ

8

Функция должна изменить значение указателя элемента, поэтому ему нужен указатель на , указатель.

Положите это другим способом: функция принимает указатель чего-то, когда ему нужно изменить эту вещь.

В этом случае это что-то само указатель. Таким образом, функция заканчивается тем, что делает указатель на указатель.

+0

ОК, так что ... исправьте меня, если я ошибаюсь: если мы просто хотели добавить что-то в END связанного списка (а не функцию push, просто функцию addItem), нам не нужен указатель на указатель на список? – Lou

+0

Как правило, у вас есть указатель на последний элемент, который будет содержать указатель со значением NULL, который вы хотите изменить. Итак, да, вам нужен только указатель на последний элемент. –

+0

Ну, ваш указатель '** stack' в этом случае предназначен для отслеживания положения конца списка. Если вам не нужно отслеживать такое значение, то нет, вам не нужно будет вообще об этом беспокоиться при добавлении элементов в ваш связанный список. Вы могли бы просто использовать указатель на сам список. – int3

0

Вам нужно будет обновить указатель.

Список - это не что иное, как указатель на Element. Таким образом, вы можете переписать это

bool push(List* stack, void* data); 

Не вы видите, что, в случае, если не будет использовать двойной указатель, фактическая декларация

bool push(List stack, void* data); 

, который не изменит первоначальный список на все.

Но поочередно,

bool push(Element* &stack, ...) 

это тоже нормально, так как это позволяет вам обновления.

4

Указатель - это просто переменная, которая содержит значение , это значение является адресом памяти.

Указатель на указатель - это просто переменная, которая содержит значение. Это значение является адресом памяти указателя.

Вы используете указатель на указатель, если хотите изменить значение значение указателя.

//Not a very useful example, but shows what I mean... 
void getOffsetBy3Pointer(const char *pInput, char **pOutput) 
{ 
    *pOutput = pInput + 3; 
} 

И вы называете эту функцию следующим образом:

const char *p = "hi you"; 
char *pYou; 
getOffsetBy3Pointer(p, &pYou); 
assert(!stricmp(pYou, "you")); 

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

//Note: This is completely wrong 
void BadGetOffsetBy3Pointer(const char *pInput, char *pOutput) 
{ 
    //*pOutput refers to the first actual char element that pOutput points to. 
    pOutput = pInput + 3; 
    //pOutput now points to pInput + 3, but the variable we passed in remains distinct. 
} 

И вы называете эту функцию следующим образом:

const char *p = "hi you"; 
char *pYou = NULL; 
BadGetOffsetBy3Pointer(p, pYou); 
assert(pYou == NULL); 

Примечание в BadGetOffsetBy3Pointer, мы могли бы изменили некоторые из персонажей, но мы не могли изменить то, что pYou очков.

0

Стек представлен указателем на последний элемент, который был нажат на него. Чтобы изменить стек, нажав на него элемент, этот указатель должен быть обновлен, поэтому мы передаем ему указатель на функцию push.

0

Посмотрите на то, как кто-то будет использовать эту функцию нажимной:

Data d1, d2; 

Stack *s = null; // s := null 
push(&s, &d1); // s := {d1}->null 
push(&s, &d2); // s:= {d2}->{d1}->null 

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

В стеке вы всегда хотите сохранить указатель на верх, а функция push упрощает сохранение этого указателя.

1

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

Чтобы изменить значение в " указатель на голову списка», вам нужно Адрес этой указатель

1

из-за этой линии:..

*stack = elem; 

в основном изменяемого оригинальный указатель внутри функции

 Смежные вопросы

  • Нет связанных вопросов^_^