Список компилируется, но выдает предупреждение: несовместимый тип указателя - PullRequest
1 голос
/ 29 апреля 2020
#include<stdio.h>
#include<stdlib.h>

typedef struct
{
    int number;
    struct player *next;
}player;

player *newPlayer;
player *firstPlayer;
player *currentPlayer;

int main(void)
{
    newPlayer = malloc(sizeof(player));
    firstPlayer = newPlayer;
    currentPlayer = newPlayer;
    currentPlayer->next = NULL;
    printf("Please enter Head: ");
    scanf("%d", &currentPlayer->number);

    newPlayer = malloc(sizeof(player));
    currentPlayer->next = newPlayer;
    currentPlayer = newPlayer;
    currentPlayer->next = NULL;
    printf("Please enter second element: ");
    scanf("%d", &currentPlayer->number);


    currentPlayer = firstPlayer;
    while (currentPlayer)
    {
        printf("%d ", currentPlayer->number);
        currentPlayer = currentPlayer->next;
    }
    printf("\n");


}

Код компилируется правильно, но я получаю следующие предупреждения:
предупреждение: назначение из несовместимого типа указателя [-Wincompatible-pointer-types]
currentPlayer->next = newPlayer;
и
предупреждение: присвоение из несовместимого типа указателя [-Wincompatible-pointer-types]
currentPlayer = currentPlayer->next;
Почему это так и как это исправить?
Заранее спасибо:)

Ответы [ 2 ]

2 голосов
/ 29 апреля 2020

При определении вашей структуры вы пропустили имя структуры. Сделав это, вы фактически создали структуру generi c, на которую может ссылаться только ее typedef (псевдоним).

typedef struct
{
    int number;
    struct player *next;
} player;

В этом определении игрок просто псевдоним этого универсального c struct.

Чтобы это исправить, добавьте слово player в первую строку:

typedef struct player
{
    int number;
    struct player *next;
} player_t;

Теперь вы можете ссылаться на структуру либо struct player, или player_t.

Всегда помните, что ключевое слово typedef только для нас, программистов, для удобства чтения. Не надейтесь на это, чтобы выполнить некоторую дополнительную работу.

РЕДАКТИРОВАТЬ: Как упоминалось в комментариях, можно использовать typedef struct player player и ссылаться на структуру либо по struct player, либо просто по player.

2 голосов
/ 29 апреля 2020

В этом объявлении typedef

typedef struct
{
    int number;
    struct player *next;
}player;

объявлено два типа. Первый - это неназванная структура, которой присваивается имя typedef player.

typedef struct
{
    //...
}player;

Второй тип - это неполный тип struct player, объявленный в определении структуры без имени.

    struct player *next;

Типы указателей struct player * и player * являются двумя разными типами, которые несовместимы.

Таким образом, для такого оператора, как, например,

currentPlayer->next = newPlayer;

, компилятор выдаст ошибку, поскольку в левой части находится объект типа struct player *, в то время как в правой части находится объект типа player *.

Вы должны написать

typedef struct player
{
    int number;
    struct player *next;
}player;

Обратите внимание, что нет необходимости определять эти указатели в области видимости файла

player *newPlayer;
player *firstPlayer;
player *currentPlayer;

Каждая переменная должна быть объявлена ​​в наименьшей области видимости, где она используется. Таким образом, эти указатели могут быть объявлены внутри функции main.

...