Мой профессор в настоящее время преподает двоичные деревья в колледже, и она дала нам программу для создания двоичного дерева на C с использованием связанных списков.
Однако возник спор о том, нужно ли использовать амперсанд (&)
вместе с оператором стрелки (->)
для ввода данных узла в дерево struct
.
Это фрагмент кода, который она нам дала для создания узла:
BinTree *createNode() {
BinTree* newnode;
newnode = (BinTree*)malloc(sizeof(BinTree));
printf("Enter data: ");
scanf(" %c",newnode->data);
newnode->lchild=NULL;
newnode->rchild=NULL;
return newnode;
}
Однако когда я запускаю весь готовый код на своем компьютере, программа завершается после ввода ввода.
1.Create
2.Inorder
3.preorder
4.postorder
5.exit
Enter your choice:1
Enter data:A
Process finished with exit code -1073741819 (0xC0000005)
Однако когда я добавляю амперсанд &
в scanf, код выполняется отлично.
BinTree *createNode() {
BinTree* newnode;
newnode = (BinTree*)malloc(sizeof(BinTree));
printf("Enter data: ");
scanf(" %c",&newnode->data);
newnode->lchild=NULL;
newnode->rchild=NULL;
return newnode;
}
Я получаю следующий вывод, в котором программа больше не завершается с кодом ошибки.
1.Create
2.Inorder
3.preorder
4.postorder
5.exit
Enter your choice:1
Enter data:A
if you want left child press 1
1
Enter data:A
if you want left child press 1
Что как бы подтверждает, что амперсанд был весьма важен в этой программе. Однако при работе со связанными списками я никогда не использовал амперсанды при вставке данных в узлы связанного списка.
Зачем тогда мне пришлось использовать здесь амперсанд, если оператор стрелки ->
уже указывает на член a struct
?
Вам нужно передать адрес newnode.data, а не значение данных. Чтобы получить адрес данных, мы используем оператор &.
Оператор &
не имеет ничего общего со связанными списками, а скорее с scanf
.
"если оператор стрелки -> уже указывает на член структуры?" Потому что оператор ->
не указывает на член структуры. newnode
указывает на структуру и ->
получает доступ к члену внутри этой структуры.
Возможно, вы захотите перестать думать о магических заклинаниях и начать думать о типах. Какой тип scanf(" %c", ___)
требуется вместо ___
? Какой тип имеет newnode->data
? Какой тип имеет &newnode->data
?
@Sweeper Я только что просмотрел коды связанного списка из предыдущего семестра и заметил, что никогда не вставлял данные в узлы напрямую с помощью scanf, а делал это, назначая входное значение узлу LL непосредственно в другом операторе.
Амперсанд &
необходим, если вы используете scanf
, поскольку он указывает адрес переменной. Оператор стрелки ->
обращается непосредственно к значению, а не к его адресу, поэтому &
необходим для получения адреса этого элемента.
Тогда почему это не обязательно для массивов? Мы можем вставлять данные в массивы без использования амперсанда.
@SpaciousCoder78 Массивы отличаются от всех других типов данных. :-) Это признано ошибкой в исходном дизайне C, но, когда это заметили, они решили, что уже слишком поздно менять ее.
«Во время работы со связанными списками я никогда не использовал амперсанды при вставке данных в узлы связанного списка». Можете ли вы показать, какой код вы использовали для вставки данных в связанные списки? Довольно сложно понять, в чем заключается ваше недопонимание.