Копирование адреса функции из указателя функции с использованием вызова по ссылке [дубликат]

Это происходит, когда вы вводите временную мертвую зону в глобальную область. Как вы можете знать, let объявления подняты, но оставлены неинициализированными . Из-за потока управления может случиться, что переменная никогда не инициализируется:

function …() {
    if (false)
        example; // would throw a ReferenceError if it was evaluated
    … // do something
    if (true)
        return; // stop!
    let example = 5; // never executed
}

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

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

throw new Error;
let example = 5;

В отличие от области функции, здесь имеет значение, что переменная остается неинициализированной. Глобальный охват длится вечно, и переменная вечно мертва. Это не было и никогда не будет инициализировано, и лексические переменные не могут быть повторно объявлены (что помогает предотвратить ошибки).

Этот обсуждался на es-discuss , но считался несущественным. Если выполнение верхнего уровня

5 ответов

Вам нужно передать указатель на указатель, если вы хотите это сделать.

void barPush(BarList ** list,Bar * bar)
{
    if (list == NULL) return; // need to pass in the pointer to your pointer to your list.

    // if there is no move to add, then we are done
    if (bar == NULL) return;

    // allocate space for the new node
    BarList * newNode = malloc(sizeof(BarList));

    // assign the right values
    newNode->val = bar;
    newNode->nextBar = *list;

    // and set the contents of the pointer to the pointer to the head of the list 
    // (ie: the pointer the the head of the list) to the new node.
    *list = newNode; 
}

Затем используйте его следующим образом:

BarList * l;

l = EMPTY_LIST;
barPush(&l,&b1); // b1 and b2 are just Bar's
barPush(&l,&b2);

Джонатан Леффлер предложил вернуться новый глава списка в комментариях:

BarList *barPush(BarList *list,Bar *bar)
{
    // if there is no move to add, then we are done - return unmodified list.
    if (bar == NULL) return list;  

    // allocate space for the new node
    BarList * newNode = malloc(sizeof(BarList));

    // assign the right values
    newNode->val = bar;
    newNode->nextBar = list;

    // return the new head of the list.
    return newNode; 
}

Использование становится:

BarList * l;

l = EMPTY_LIST;
l = barPush(l,&b1); // b1 and b2 are just Bar's
l = barPush(l,&b2);
44
ответ дан geofftnz 21 August 2018 в 13:39
поделиться
  • 1
    Спасибо, я подумал, что это проблема, но надеялся, что это не так.) – Paul Wicks 20 April 2009 в 05:38
  • 2
    Кроме того, функция возвращает указатель на новый заголовок списка. BarList * barPush (список BarList *, Bar * bar) – Jonathan Leffler 20 April 2009 в 05:40

Общий ответ: передайте указатель на вещь, которую вы хотите изменить.

В этом случае это будет указатель на указатель, который вы хотите изменить.

13
ответ дан aib 21 August 2018 в 13:39
поделиться

Помните, что в C значение EVERYTHING передается по значению.

Вы передаете указатель на указатель, например

int myFunction(int** param1, int** param2) {

// now I can change the ACTUAL pointer - kind of like passing a pointer by reference 

}
7
ответ дан Anthony 21 August 2018 в 13:39
поделиться

Да, вы должны передать указатель на указатель. C передает аргументы по значению, а не по ссылке.

2
ответ дан Charles E. Grant 21 August 2018 в 13:39
поделиться

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

2
ответ дан dirkgently 21 August 2018 в 13:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: