Устранение ошибки «возврат делает указатель из целого числа без приведения» - PullRequest
0 голосов
/ 11 января 2020

Мне нужна помощь, чтобы разблокировать меня в моей программе. Я хотел бы напечатать доску и иметь возможность изменить ее позже во время игры.

Но компилятор говорит мне, что "return делает указатель из целого числа без приведения [-Wint-преобразование]". Я искал в Интернете некоторые решения, но не нашел ничего, что могло бы мне помочь.

Как мне решить эту проблему?

Мой заголовок jeu.h:

    #ifndef __JEU__
    #define __JEU__
    void AfficherPlateau(signed char *plateau);
    int LanceDeDe(void);
    int setup(void);
    void jeu(void);
    signed char *plateauVide(void);
    #define SIZE 17
    #endif

Функции управления моей доской jeu.c:

    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #include "jeu.h"
    #define SIZE 17

    static signed char plateau[SIZE][SIZE] =
    {
            {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'},
            {'0','x','x','x','x','x','x','O','O','O','x','x','x','x','x','x','0'},
            {'0','x',' ',' ',' ',' ','x','O','1','O','x',' ',' ',' ',' ','x','0'},
            {'0','x',' ',' ',' ',' ','x','O','2','O','x',' ',' ',' ',' ','x','0'},
            {'0','x',' ',' ',' ',' ','x','O','3','O','x',' ',' ',' ',' ','x','0'},
            {'0','x',' ',' ',' ',' ','x','O','4','O','x',' ',' ',' ',' ','x','0'},
            {'0','x','x','x','x','x','x','O','5','O','x','x','x','x','x','x','0'},
            {'0','O','O','O','O','O','O','O','6','O','O','O','O','O','O','O','0'},
            {'0','O','1','2','3','4','5','6','W','6','5','4','3','2','1','O','0'},
            {'0','O','O','O','O','O','O','O','6','O','O','O','O','O','O','O','0'},
            {'0','x','x','x','x','x','x','O','5','O','x','x','x','x','x','x','0'},
            {'0','x',' ',' ',' ',' ','x','O','4','O','x',' ',' ',' ',' ','x','0'},
            {'0','x',' ',' ',' ',' ','x','O','3','O','x',' ',' ',' ',' ','x','0'},
            {'0','x',' ',' ',' ',' ','x','O','2','O','x',' ',' ',' ',' ','x','0'},
            {'0','x',' ',' ',' ',' ','x','O','1','O','x',' ',' ',' ',' ','x','0'},
            {'0','x','x','x','x','x','x','O','O','O','x','x','x','x','x','x','0'},
            {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'}
    };
    signed char *plateauVide(void)
    {
        return *plateau;
    }

     void AfficherPlateau(signed char *plateau)
     {
        int a;
        int b;
        for (a = 1; a < SIZE-1; a++)
            {
                for (b = 1; b < SIZE-1; b++)
                {
                    printf("%c", plateau[a][b]);
                    printf(" ");    
                }
                printf("\n");
            }
     }

     int LanceDeDe(void)
     {
        int i = 1;
        int Lance = 0;
        srand(time(NULL));
        Lance = (rand() % 6) + 1;
        return (Lance);
     }

     int setup(void)
     {
        int nombreJoueur;
        int i;
        signed char PionsJoueurs[4]={'1','2','3','4'};
        int reponseIA;
        int nombreIA = 0;
        int erreur = 0;
        signed char *plateau = plateauVide();
        printf("Bonjour, combien de joueurs ?\n");
        scanf("%d", &nombreJoueur);
        while (nombreJoueur != 2 && nombreJoueur != 3 && nombreJoueur != 4)
        {
            erreur++;
            if (erreur >= 3)
            {
                printf("Seriez-vous en train de chercher la petite bete ?\n");
            } 
            printf("La valeure entree ne correspond pas a un nombre possible, vous ne pouvez jouer que de 2 a 4 joueurs.\nCombien de joueurs ?\n");
            scanf("%d", &nombreJoueur);

        }
        erreur = 0;
        printf("Souhaitez-vous remplacer un ou des joueurs par une IA ? Oui = 1\n");
        scanf("%d", &reponseIA);
        if (reponseIA == 1)
        {
            printf("Combien d'IA voulez-vous ?\n");
            scanf("%d", &nombreIA);
            while (nombreIA > nombreJoueur && nombreIA < 1)
            {
                erreur++;
                if (erreur >= 3)
                {
                    printf("Seriez-vous en train de chercher la petite bete ?\n");
                }
                printf("Vous ne pouvez pas avoir une autre valeur qu'un nombre entier allant de 1 à %d",nombreJoueur);
                printf("Combien d'IA voulez-vous ?\n");
                scanf("%d", &nombreIA);

            }
        }
        else
        {
            printf("Aucune IA en jeu.\n");
        }
        AfficherPlateau(plateau);
        for (i = 1; i <= (nombreJoueur-nombreIA); i++)
        {
            printf("Joueur %d, veuillez choisir vos pions avec 1 caractere :\n",i);
            scanf("%c",PionsJoueurs[i]);
        }


        erreur = 0;
        printf("%d\n",LanceDeDe());
     }

     void jeu(void)
     {
        setup();
     }

Наконец, мой main.c:

    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #include "jeu.h"

    int main(void)
    {
        jeu();
        return 0;
    }

1 Ответ

0 голосов
/ 12 января 2020

Короче говоря

В вашем коде много проблем с печатанием, и в зависимости от вашего компилятора сообщение может вводить в заблуждение. Основная проблема здесь - это способ обработки двумерного массива (а также неприятная ошибка, которая приводит к повреждению памяти при компиляции).

Очень долго и шаг за шагом

Учитывая тип plateau:

static signed char plateau[SIZE][SIZE] = { ...};

Проблемы начинаются, когда вы пишете это:

signed char *plateauVide(void)
    {
        return *plateau;
    }

К сожалению для вас, это прекрасно компилируется. Но это так же, как return plateau[0]. Так что тип правильный. Но вы теряете второе измерение вашего 2D-массива.

Эта проблема распространена во многих местах. Например, в AfficherPlateau(signed char *plateau) вы пытаетесь получить к нему доступ с 2 измерениями, что должно привести к ошибке компиляции:

                printf("%c", plateau[a][b]);

2D-массивы очень сложны в C. Потому что:

  • если вы определите их так, как вы это сделали, все строки будут помещены в память последовательно, и если вы хотите сохранить 2D, вам нужно будет передать его как аргумент 2D. Это исправляет размер массива во время компиляции.

  • Если позже вы захотите динамически выделить такой фиксированный массив, вы все равно можете использовать аналогичную конструкцию. Однако, если вы хотите использовать двумерные массивы динамического размера c, скажем, используемый хочет 20х20 вместо 17х17, вам придется работать с указателями на указатели, которые имеют разную структуру памяти.

Но чтобы это не было слишком сложным, просто сохраните 2 измерения и фиксированную ширину:

void AfficherPlateau(signed char plateau[][SIZE])
{
     ...// there you can use the 2D structure as you did 
}

Это изменение необходимо выполнить для каждой функции который использовал *plateau. К сожалению, вы не можете определить переменную таким образом и не вернуть значение этого типа. Я сказал, 2D сложно. Поэтому начните со следующего определения в заголовке:

typedef signed char (*PLATEAU)[SIZE];

Затем вы можете переписать свою первую функцию:

PLATEAU plateauVide(void)
{
    return plateau;
}

Затем вы можете изменить определение плато в setup():

PLATEAU plateau = plateauVide();

Наконец, у вас есть очень неприятная ошибка в одном из l oop. Это может привести к повреждению памяти, и его трудно обнаружить с помощью аргументов scanf:

       scanf("%c",&PionsJoueurs[i]);   //<--- & is required for the address!!
                                       //(sinon ça plante ;-) ) 

И затем все должно скомпилироваться нормально.

Online DEMO

Редактировать: Я почти забыл: setup() должен вернуть целое число. Это очень плохая привычка объявлять тип возврата и не возвращать.

...