Передача структуры в функцию на языке c

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

#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;
}

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

Потому что head уже является указателем на struct, который был выделен динамически.

Weather Vane 09.04.2023 12:37

В C нет «передачи по ссылке». Вы передаете ссылки (указатели) по значению.

Paul Hankin 09.04.2023 13:50

Кроме того, приведение результата malloc не требуется в C. Преобразование указателя из void* неявно. (Приведение было бы необходимо в C++, но вы все равно не должны использовать malloc).

BoP 09.04.2023 18:18
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
3
85
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

У вас есть односвязный список, в котором узлы связаны указателями.

Функция 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 уже правильного типа, вам не нужно брать его адрес, это уже адрес.

Другие вопросы по теме

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

Безопасно ли привести результат fgetc() к короткому, если я использую его только с файлом, открытым в режиме «rb»?
Чтение значений внутри fscanf дает разные значения при чтении снаружи?
Как отправить текст и двоичный файл через сокет в одном сообщении в C?
Я не могу обновить новые данные в текстовом файле
C сортировать целые числа из текстового файла с сортировкой выбором и записывать отсортированные числа в новый файл
Как исправить ошибку: «предварительная задача 'c/c++: gcc build active file' завершена с кодом выхода -1"
Алгоритм минимакса не работает должным образом (реализован на C)
Как удалить элемент из одного связанного списка без обхода?
Распределитель памяти — простое раздельное хранилище: как определить размер выделенного блока по его адресу?
Что может вывести программа на C, если мы присвоим символ, не заканчивающийся нулевым символом, разными способами объявления?