Langage C Carré magique (Débutant) [Fermé]

Signaler
-
Messages postés
25
Date d'inscription
samedi 12 mars 2011
Statut
Membre
Dernière intervention
17 mars 2011
-
Bonjour,
En dev C++ , en langage C non pas C++
Dans un exercice , je dois faire un programme qui crée un carré magique d'ordre impair , cet ordre est donné comme une constante en haut du programme , que je pourrais modifier comme je veux pour avoir un carré plus grand , j'ai donc fait mon programme avec des actions simples , tres simples meme , sans biensur que l'utilisateur (qui sera moi , qui ne veut que voir le carré a la fin) ait a entrer qqch au clavier . Le problème , rien n'arrive quand j'execute , pourtant , je suis presque sûr de l'enchaînement logique de mon programme.
Merci de me dire où est l'erreur
#include <stdio.h>
#include <stdlib.h>
#define N 3

int main(int argc, char *argv[])
{
    int T[N][N],L,C,M;
    for(L=0;L<=N-1;L++)
    {
                       for(C=0;C<=N-1;C++)
                       {
                                          T[L][C]=0;
                       }
    }
    T[(N+1)/2][(N-1)/2]=1;
    L=(N+1)/2;
    C=(N-1)/2;
    do
    {
              if(L!=N-1 && C!=N-1)
              {
                        if(T[L+1][C+1]==0)
                        {
                                          T[L+1][C+1]=T[L][C]+1;
                                          L++;
                                          C++;
                        }
                        else
                        {
                            if(L!=N-2)
                            {
                                      T[L+2][C]=T[L][C]+1;
                                      L=L+2;
                            }
                            else
                            {
                                T[0][C]=T[L][C]+1;
                                L=0;
                            }
                        }
              }  
               if(L==N-1 && C!=N-1)
              {
                        if(T[0][C+1]==0)
                        {
                                          T[0][C+1]=T[L][C]+1;
                                          L=0;
                                          C++;
                        }
                        else
                        {
                            T[1][C]=T[L][C]+1;
                            L=1;
                        }
              }   
               if(L!=N-1 && C==N-1)
              {
                        if(T[L+1][0]==0)
                        {
                                          T[L+1][0]=T[L][C]+1;
                                          L++;
                                          C=0;
                        }
                        else
                        {
                            if(L==N-2)
                            {
                                      T[0][C]=T[L][C]+1;
                                      L=0;
                            }
                            else
                            {
                                T[L+2][C]=T[L][C]+1;
                                L=+2;
                            }
                        }
              } 
               if(L==N-1 && C==N-1)
              {
                        if(T[0][0]==0)
                        {
                                          T[0][0]=T[L][C]+1;
                                          L=0;
                                          C=0;
                        }
                        else
                        {
                           T[1][C]=T[L][C]+1;
                           L=1;
                        }
              }  
              M=0;
                 for(L=0;L<=N-1;L++)
                     {
                       for(C=0;C<=N-1;C++)
                       {
                                       if(T[L][C]==0)
                                       M++;
                       }
                     }
}while(M!=0);
 for(L=0;L<=N-1;L++)
                     {
                       for(C=0;C<=N-1;C++)
                       {
                                       printf("%d\t",T[L][C]);
                       }
                       printf("\n");
                     }
  system("PAUSE");	
  return 0;
}




7 réponses

Messages postés
1143
Date d'inscription
mardi 10 août 2010
Statut
Membre
Dernière intervention
18 mars 2012
111
Bonsoir,

Tu as une boucle infinie dans ta boucle do..while générale.
Vérifie les cans dans lesquels M doit etre égale à 0, et si cela est fait correctement.

Cordialement.

Edit:
Je t'avouerai que j'ai pas lu le reste du code, si tu pouvais le rendre lisible (avec des fonctions et tout et tout) ça serait bien :)

J'ai un rêve. C'est que tous les supporters de football se tiennent par la main...
...Et se jettent dans le vide
Boonjour,

Merci tout d'abord pour ta réponse.
Comme le titre l'indique , je ne suis que débutant , je suis élève en prépas , et jusqu'à maintenant nous n'avons pas fait de fonctions. Notre prof nous a donc chargé de faire le programme avec les trucs "élementaires" qu'on a etudié jusqu'a maintenant (la majorité est présente dans le programme).J'ai bien assimilé la correction qu'on a faite , qui était TRES differente du programme que j'ai fait, mais mon prof ne m'a toujours pas dit ce qui clochais dans mon programme...
Maintenant vous dites que c'est une boucle infini , bien ; mais comment resoudre celà , sachant que (par exemple , quand j'execute le programme a la main pour N=3) , je fini bien par trouver apres un nombre fini d'operations (9) que M=0 , du coup je dois bien sortir de la boucle... pourtant , en le compilant (toujours pour N=3) , il ne sort pas .....


Cordialement
Messages postés
1143
Date d'inscription
mardi 10 août 2010
Statut
Membre
Dernière intervention
18 mars 2012
111
Salut,

Toujours pas vraiment eu le temps de décortiquer tout le programme, mais je vois à la fin de la boucle:

M=0;
for(L=0; L <= N-1; L++)
    {
      for(C=0; C<=N-1; C++)
        {
          if(T[L][C]==0)
	  M++;
        }
    }


A chaque passage dans ta boucle do..while, à cet endroit ta variable M est remise à 0.
Ensuite, en utilisant un débuger (ou à ton niveau, en ajoutant de l'affichage), on voit que M est toujours incrémenté, donc la condition (M != 0) est toujours vraie et on ne sort pas de la boucle.

Par exemple si tu essaie ce code:

      M=0;
      puts("M = 0");
      for(L=0; L <= N-1; L++)
        {
          for(C=0; C<=N-1; C++)
            {
              if(T[L][C]==0)
                {
                  M++;
                  puts("M est incremente");
                }
            }
        }
      puts("On sort de la boucle");


Tu obtiens ceci:

M = 0
M est incremente
M est incremente
M est incremente
M est incremente
M est incremente
M est incremente
On sort de la boucle
M = 0
M est incremente
M est incremente
M est incremente
M est incremente
M est incremente
M est incremente
On sort de la boucle
.. etc etc à l'infini


On voit que M est toujours incrémenté avant de sortir de la boucle.
Revois tes deux for et ton if, j'imagine qu'à un moment la condition est vérifiée alors qu'elle ne devrait pas l'etre.

Cordialement
Bonjour, je vois que tu sembles utiliser plus ou moins la méthode de construction siamoise, et bien que Gaunts a bien répondu à ton problème, je vois qu'algorithmiquement, comme dans la syntaxe, ton code est à améliorer. Voici, peut-être comment tu devrais penser à le changer :
#include <stdlib.h>   
#include <stdio.h>   
#include <math.h>   

#define USING "a.out <magic square's order>\n"   
#define ORDER_ERROR "Error : can't create a magic quare with an order from %d. It must not be smaller than 3.\n"   
#define CONSTANT_MESSAGE "With a magic constant from %ld\n"   

int createOddMagicSquare(long **ppOut, int order)   
{   
    if (order < 3) return -1;   
    int totalSize = order * order;   

    long *pOut = (long*) malloc(sizeof(int) * totalSize);   
    if (!pOut) return -2;   

    int i;   
    for (i=0; i<totalSize; i++) pOut[i] = 0;   

    int p = order / 2, pn;   
    pOut[p] = 1;   
    for (i=1; i<totalSize; i++)   
    {   
        pn = p;   
        pn += order;   
        pn %= totalSize;   
        pn = ((pn - pn % order) + (pn + 1) % order);   
        if(pOut[pn])   
        {   
            p -= order;   
            if (p < 0) p += totalSize;   
        }   
        else p = pn;   

        pOut[p] = i + 1;   
    }   

    *ppOut = pOut;   
    return 0;   
}   

void getStrLng(long in, char*pOut, int size)   
{   
    pOut[size] = '\0';   
    int i;   
    for(i=size-1; i>=0; i--, in/=10) pOut[i] = in % 10 + '0';   
}   

int printSq(FILE * stream, long *pIn, int order, unsigned short maxSzBytes)   
{   
    char *outStr = (char*) malloc(sizeof(char) * maxSzBytes);   
    int i, ii, max = order-1;   
    for (i=0; i<order; i++)   
    {   
        fprintf(stream, "[");   
        for (ii=0; ii<max; ii++)   
        {   
            getStrLng(pIn[i*order + ii], outStr, maxSzBytes);   
            fprintf(stream, "%s, ", outStr);   
        }   

        getStrLng(pIn[i*order + ii], outStr, maxSzBytes);   
        fprintf(stream, "%s", outStr);   

        fprintf(stream, "]\n", outStr);   
    }   
}   

int main(int argc, char* argv[])   
{   
    if (argc != 2)   
    {   
        printf("Using : %s\n", USING);   
        return -1;   
    }   

    long *pMagic;   

    int order = atoi(argv[1]);   
    if (order < 3)   
    {   
        printf(ORDER_ERROR, order);   
        return -1;   
    }   

    createOddMagicSquare(&pMagic, order);   

    printf(CONSTANT_MESSAGE, (order*order*order + order) / 2);   
    printSq(stdout, pMagic, order, log10(order*order) + 1);   
    return 0;   
}   


Bref, plutôt que des (x==0), qui bien qu'explicitent, me paraissent un peu encombrant, utiliser des (x), et aussi, essayer d'utiliser moins de if et de if...else en condensant dans une boucle plus performante. Et peut-être, plutôt que de parcourir ton carré magique en incrémentant chacun des nombres, partir avec une seule variable d'incrément qu'on affecte aux cases à chaque «repositionnement» des vecteurs de déplacement.

Et puis, ça aiderait d'avoir des noms de variables plus explicite comme «laLigne» et «laColonne» plutôt que L et C.
(ou plus proprement)
#include <stdlib.h>
#include <stdio.h>
#include <math.h>

#define USING "a.out <magic square's order>\n"
#define ORDER_ERROR "Error : can't create a magic quare with an order of %d. It must not be smaller than 3.\n"
#define ORDER_MESSAGE "A magic square of order %d\n"
#define CONSTANT_MESSAGE "With a magic constant of %ld\n"

int createOddMagicSquare(long **ppOut, int order)
{
    if (order < 3) return -1;
    int totalSize = order * order;

    long *pOut = (long*) malloc(sizeof(int) * totalSize);
    if (!pOut) return -2;

    int i;
    for (i=0; i<totalSize; i++) pOut[i] = 0;

    int p = order / 2, pn;
    pOut[p] = 1;
    for (i=1; i<totalSize; i++)
    {
        pn = p;
        pn += order;
        pn %= totalSize;
        pn = ((pn - pn % order) + (pn + 1) % order);
        if(pOut[pn])
        {
            p -= order;
            if (p < 0) p += totalSize;
        }
        else p = pn;

        pOut[p] = i + 1;
    }

    *ppOut = pOut;
    return 0;
}

void getStrLng(long in, char*pOut, int size)
{
    pOut[size] = '\0';
    int i;
    for(i=size-1; i>=0 && in>0; i--, in/=10) pOut[i] = in % 10 + '0';
    for(i=i; i>=0; i--) pOut[i] = ' ';
}

void printSq(FILE * stream, long *pIn, int weight, int height, unsigned short maxSzBytes)
{
    char *outStr = (char*) malloc(sizeof(char) * maxSzBytes);
    int i, ii, max = height-1;
    for (i=0; i<weight; i++)
    {
        fprintf(stream, "[");
        for (ii=0; ii<max; ii++)
        {
            getStrLng(pIn[i*weight + ii], outStr, maxSzBytes);
            fprintf(stream, "%s, ", outStr);
        }

        getStrLng(pIn[i*weight + ii], outStr, maxSzBytes);
        fprintf(stream, "%s", outStr);

        fprintf(stream, "]\n");
    }
}

int main(int argc, char* argv[])
{
    if (argc != 2)
    {
        printf("Using : %s\n", USING);
        return -1;
    }

    long *pMagic;

    int order = atoi(argv[1]);
    if (order < 3)
    {
        printf(ORDER_ERROR, order);
        return -1;
    }

    createOddMagicSquare(&pMagic, order);

    printf(ORDER_MESSAGE, order);
    printf(CONSTANT_MESSAGE, (long)(order*order*order + order) / 2);
    printSq(stdout, pMagic, order, order, log10(order*order) + 1);
    return 0;
}

Messages postés
25
Date d'inscription
samedi 12 mars 2011
Statut
Membre
Dernière intervention
17 mars 2011
451
Juste pour le lien