ошибка: несовместимый тип аргумента

Я пишу список на C. Ниже приведен источник:

#include <stdio.h>
#include <stdlib.h>


struct list {
 int value;
 struct list *next;
};

typedef struct list ls;



void add (ls **head, ls **tail, int val)
{
 ls *new, *tmp1, *tmp2;

 if (NULL == *head)
 {
    new = (ls*)malloc(sizeof(ls));
    *head = new;
    *tail = new;
    new->value = val;
    new->next = NULL;

    return;
 }

 else
 {
    tmp1 = *head;
    tmp2 = tmp1->next;
    while (tmp2 != NULL)
    {
        tmp1 = tmp2;
        tmp2 = tmp1->next;
    }

    new = (ls*)malloc(sizeof(ls));
    new->value = val;
    new->next = NULL;
    *tail = new;

    return;
 }
}



void show (ls **head, ls **tail)
{
 int i;
 ls *tmp;

 while (tmp->next != NULL)
 {
    printf("%d: %d", i,  tmp->value);
    i++;
    tmp=tmp->next;
 }

 return;
}



int main (int argc, char *argv[])
{
 ls *head;
 ls *tail;
 int n, x;

 head = (ls*)NULL;
 tail = (ls*)NULL;

 printf("\n1. add\n2. show\n3. exit\n");
 scanf("%d", &x);
 switch (x)
 {
    case 1:
        scanf("%d", &n);
        add(*head, *tail, n);
        break;

    case 2:
        show(*head, *tail);
        break;

    case 3:
        return 0;

    default:
        break;
}

 return 0;
}

Когда я скомпилирую его с помощью gcc

gcc -o lab5.out -Wall -pedantic lab5.c

Я получаю странные ошибки:

lab5.c: In function ‘main’:
lab5.c:84:3: error: incompatible type for argument 1 of ‘add’
lab5.c:16:6: note: expected ‘struct ls **’ but argument is of type ‘ls’
lab5.c:84:3: error: incompatible type for argument 2 of ‘add’
lab5.c:16:6: note: expected ‘struct ls **’ but argument is of type ‘ls’
lab5.c:88:3: error: incompatible type for argument 1 of ‘show’
lab5.c:52:6: note: expected ‘struct ls **’ but argument is of type ‘ls’
lab5.c:88:3: error: incompatible type for argument 2 of ‘show’
lab5.c:52:6: note: expected ‘struct ls **’ but argument is of type ‘ls’

Для меня все ок...

И тип аргумента ls**, а не ls, как говорит компилятор.

Кто-нибудь видит, что может быть не так?

PS. Я знаю, что *tail в качестве аргумента давать не нужно и он не используется, как бы то ни было, потому что я хочу развить эту "программу"...


person kostek    schedule 18.07.2012    source источник
comment
Вам нужно & вместо * в вызове.   -  person Daniel Fischer    schedule 18.07.2012
comment
Конечно... Это решило проблему. Большое спасибо...   -  person kostek    schedule 18.07.2012


Ответы (2)


Как сказал Даниэль в своем комментарии, а codaddict сказал в своем ответе, использование & вместо * даст вам то, что вы хотите. Вот небольшое объяснение, чтобы помочь вам вспомнить.

* de — ссылается на то, к чему он присоединен, что означает, что он принимает переменную, как если бы она была указателем, и возвращает значение по этому адресу.

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

Поскольку вы хотите передать указатель на переменные head и tail, вы хотите передать их как &head и &tail, что даст вам значения **head и **tail на другом конце. Это кажется нелогичным, пока вы не привыкнете к этому.

person Scott M    schedule 18.07.2012
comment
@kostek Круто. Извините, если я показался снисходительным. Трудно предотвратить это через Интернет. Я просто хотел убедиться, что объяснил это полностью, потому что лично у меня были проблемы с тем, чтобы понять это, когда я только учился. Удачи с кодом! - person Scott M; 18.07.2012
comment
Нет, все нормально. Спасибо за полное объяснение. - person kostek; 18.07.2012

add(*head, *tail, n);

должно быть :

add(&head, &tail, n);

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

Аналогичное исправление необходимо сделать для вызова функции show.

person codaddict    schedule 18.07.2012