кто-нибудь может помочь? почему '&' не требуется при вызове функции в этой программе? но считается, что '&' требуется при вызове по ссылке.
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node *next;
};
void traversal(struct node *ptr)
{
while(ptr!=NULL)
{
printf("%d\n", ptr->data);
ptr = ptr->next;
}
}
int main()
{
struct node *head;
struct node *second;
struct node *third;
head = (struct node*) malloc(sizeof(struct node));
second = (struct node*) malloc(sizeof(struct node));
third = (struct node*) malloc(sizeof(struct node));
head->data = 7;
head->next = second;
second->data = 5;
second->next = third;
third->data = 12;
third->next = NULL;
traversal(head);
return 0;
}
кто-нибудь может помочь? почему '&' не требуется при вызове функции в этой программе? но считается, что '&' требуется при вызове по ссылке.
В C нет «передачи по ссылке». Вы передаете ссылки (указатели) по значению.
Кроме того, приведение результата malloc
не требуется в C. Преобразование указателя из void*
неявно. (Приведение было бы необходимо в C++, но вы все равно не должны использовать malloc
).
У вас есть односвязный список, в котором узлы связаны указателями.
Функция traversal
не принимает объект типа struct node
. Он принимает указатель на объект типа struct node *
.
void traversal(struct node *ptr)
{
while(ptr!=NULL)
{
printf("%d\n", ptr->data);
ptr = ptr->next;
}
}
Поскольку исходный указатель, используемый в качестве выражения-аргумента, внутри функции не изменяется, то нет смысла передавать его в функцию по ссылке через указатель на нее.
Разыменование указателей внутри функции, например
ptr->data
функция имеет прямой доступ к членам данных узлов, на которые указывают указатели.
То есть объект типа struct node
действительно передается по ссылке в функцию через указатель на нее. Но сам указатель передается по значению.
Чтобы было понятно, рассмотрим следующую простую демонстрационную программу.
#include <stdio.h>
void f( int *px )
{
printf( "x = %d\n", *px );
}
int main( void )
{
int x = 10;
int *px = &x;
f( px );
}
Как видите, для вывода значения переменной x
, объявленной в main
, внутри функции f
с помощью указателя px
на x
нет необходимости передавать сам указатель по ссылке через указатель на него. Однако объект x
передается в функцию по ссылке косвенно через указатель px
.
Не попадайтесь в ловушку культового программирования, когда вы видите паттерн и применяете его, не понимая семантики и того, почему и когда паттерн уместен.
В этом случае требование состоит не в том, чтобы слепо применять &
ко всем вызовам передачи по ссылке. Требование состоит в том, чтобы просто передать ссылку. В этом случае struct node*
. Если у вас есть объект struct node
, адрес оператора (&
) дает struct node*
. Однако в вашем случае head
уже является struct node*
, поэтому получение его адреса даст struct node**
(указатель на указатель на struct node
), а не тип, соответствующий объявлению параметра traversal()
.
То есть в данном случае head
уже правильного типа, вам не нужно брать его адрес, это уже адрес.
Потому что
head
уже является указателем наstruct
, который был выделен динамически.