Annonce

Réduire
Aucune annonce.

Cours langage C n°12 - Les structures

Réduire
Ceci est une discussion importante.
X
X
 
  • Filtre
  • Heure
  • Afficher
Tout nettoyer
nouveaux messages

  • #16
    Grrr J'aimerais comprendre x)

    graph point, another; -> Ok tu crées deux variables de type "graph"

    graph *p = &point; -> *Le vide* "*p" ??? Alors que "p" est-une structure ? WHAT ? x'D

    Quand j'te dis que j'ai pas compris grand chose..

    EDIT : *Viens de relire le code* OK JE SORS:

    Code:
     *p = another;
    Déjà tu vois, j'aurais jamais imaginé que cette ligne permette de changer toute les valeurs de la variable "point"..

    Comment fonctionne un pointeur de type "structure" ? !!!! x)
    Dernière modification par shirocen, 31 décembre 2014, 19h10.
    deux et deux font cinq

    Commentaire


    • #17
      Dernière tentative:

      Code:
      #include <stdio.h>
      #include <stdlib.h>
      
      typedef struct graph graph;
      
      void initialiserCoordonnes(graph *Point);
      
      struct graph
      {
          int x;
          int y;
      };
      
      int main( int argc, char argv[])
      {
          graph point;
          printf("%d\n", &point.x); // 2686728
          printf("%d\n", &point.y); // 2686732
          printf("%d\n", &point);   // 2686728 -> Donc revient à faire &point.x
          initialiserCoordonnes(&point);
          printf("%d", point.x);    // 0
          printf("%d", point.y);    // 0
      
      }
      
      void initialiserCoordonnes(graph *Point)
      {
          printf("%d\n",Point); // 2686728 -> Le pointeur contient l'adresse de &point.x
          printf("%d\n",&((*Point).x)); // 2686728
          printf("%d\n",&((*Point).y)); // 2686732
          (*Point).x = 0; // Pourquoi Diable t'écris-tu comme ça ?! 
          Point -> y = 0;
      }
      Pourrais-tu détailler en langage naturel comment l'ordinateur interprète : (*Point).x = 0

      Une autre proposition :

      Code:
      #include <stdio.h>
      #include <stdlib.h>
      
      typedef struct graph graph;
      
      void initialiserCoordonnes(graph *Point);
      
      struct graph
      {
          int x;
          int y;
      };
      
      int main( int argc, char argv[])
      {
          graph point;
          
          initialiserCoordonnes(&point);
          
          return 0;
      
      }
      
      void initialiserCoordonnes(graph *Point)
      {
      
      }
      Alors pourrais-tu compléter et/ou me dire les erreurs que je fais dans ce tableau :

      === Variable === | === Adresse === | === Valeur ===


      point.x | FFFFFF0 | 0
      point.y | FFFFFF1 | 0
      Point.x | FFFFFF2 | FFFFFF0
      Point.y | FFFFFF3 | FFFFFF1

      Et pour finir je cite un paragraphe d'openclassroom :

      "Oui mais voilà, problème… On ne peut pas vraiment faire :

      Code:
      void initialiserCoordonnees(Coordonnees* point)
      {
          *point.x = 0;
          *point.y = 0;
      }
      Ce serait trop facile… Pourquoi on ne peut pas faire ça ? Parce que le point de séparation s'applique sur le mot point et non sur *point en entier. Or, nous ce qu'on veut, c'est accéder à *point pour en modifier la valeur.
      Pour régler le problème, il faut placer des parenthèses autour de *point. Comme cela, le point de séparation s'appliquera à *point et non juste à point :

      Code:
      void initialiserCoordonnees(Coordonnees* point)
      {
          (*point).x = 0;
          (*point).y = 0;
      }
      "

      -> "Or, nous ce qu'on veut, c'est accéder à *point pour en modifier la valeur"

      On veut accéder à point.x et non à *point ?
      Dernière modification par shirocen, 01 janvier 2015, 00h02.
      deux et deux font cinq

      Commentaire


      • #18
        Pourrais-tu détailler en langage naturel comment l'ordinateur interprète : (*Point).x = 0
        On déréférence *Point car les parenthèses sont prioritaires sur toutes opérations, donc ça devient Point.
        Ensuite (*Point).x est équivalent à Point.x

        En fait ton problème est simple, tu n'arrives pas à assimiler le fait qu'en paramètre de fonction, tu peux avoir une adresse sur une structure. Ça fonctionne pourtant sur le même principe qu'une adresse sur un entier.

        Code:
        #include <stdio.h>
        
        void maFonction(int *a);
        
        int main(void){
        
        	int n = 5;
        
        	maFonction(&n);
        
        	return 0;
        }
        
        void maFonction(int *a){
        	printf("adresse de a: %p\n", a);
        	printf("déréférencement de a: %d\n", *a);
        }
        Donc tu inverses tout car tu crois partir d'une valeur et non d'une adresse.

        Code:
        #include <stdio.h>
        
        typedef struct{
        	int x;
        	int y;
        } graph;
        
        void maFonction(graph *g);
        
        int main(void){
        
        	graph gr;
        
        	maFonction(&gr);
        
        	printf("x vaut %d et y vaut %d", gr.x, gr.y);
        
        	return 0;
        }
        
        void maFonction(graph *g){
        	printf("adresse de g: %p\n", g);
        	puts("déréférencement et initialisation de g:");
        	(*g).x = 0;
        	(*g).y = 0;
        }
        Après je ne sais pas comment mieux t'expliquer, j'ai pris beaucoup de temps sur mes cours pour que la partie pédagogique soit au top, il est donc difficile pour moi de faire mieux... Je pense qu'il faudrait que tu prennes le temps de bien comprendre les pointeurs, faire des exercices, et je pense qu'à force d'appliquer, ça rentrera doucement mais sûrement.

        Commentaire


        • #19
          *Un problème d'adresses..*

          Fiou' j'ai enfin compris le truc :

          Quand on pointe sur une structure on pointe vers le DEBUT de la structure -> (*g) <- dans ton code.

          Ensuite on va donné une valeur de la structure : " .x " par exemple.

          Le pointeur étant du même type que la structure, sait qu'il trouvera la variable "x" dans les

          4 premiers octets de la structures c'est-à-dire les 4 premières adresses (Je ne savais pas qu'une adresse -> 1 OCTET)

          Si aurait voulu modifier le "y", on aurait été dirigé vers les 4 adresses suivantes de la structure, on appel cela un "offset" ?
          deux et deux font cinq

          Commentaire


          • #20
            1 octet, pas forcément... En ajoutant 1, tu passes à l'adresse suivante, effectivement, c'est un offset, mais le nombre d'octet dépendra de la taille des types de tes attributs x et y. Dans ton cas c'est des attributs de type int, donc de taille 4 octets

            EDIT: En l’occurrence ici, la taille de ma structure graph serait de 8 octets, 2x4 octets (2 int).

            On rentre dans les détails, et je trouve que ce n'est pas forcément utile, je pense que ce qu'il te manque, est une plus grosse pratique des pointeurs. Il faut vraiment que tu te sentes plus à l'aise avec...

            Si je devais faire ce genre d'exercice, je le ferais dans ce style

            Code:
            #include <stdio.h>
            #include <stdlib.h>
            
            typedef struct{
            	int x;
            	int y;
            } Point;
            
            Point *initialiser(void);
            void delete(Point *p);
            
            int main(void){
            
            	int i;
            	Point *array[5];
            
            	for (i=0; i<5; i++){
            		array[i] = initialiser();
            	}
            
            	for (i=0; i<5; i++){
            		delete(array[i]);
            	}
            
            	return 0;
            }
            
            Point *initialiser(void){
            
            	static int n = 1;
            
            	Point *p = malloc(sizeof(Point));
            	if (p == NULL){
            		fprintf(stderr, "Erreur allocation au point n°%d", n);
            		exit(EXIT_FAILURE);
            	}
            	p->x = 0;
            	p->y = 0;
            
            	printf("point n°%d créé !\n", n);
            
            	n += 1;
            
            	return p;
            }
            
            void delete(Point *p){
            
            	free(p);
            
            	puts("Suppression d'un point");
            }
            Mais il n'y a pas de bonnes manières, juste, il faut avoir une bonne idée dont on va construire sa résolution.
            Dernière modification par fred, 01 janvier 2015, 23h10.

            Commentaire


            • #21
              Un grand merci Fred' pour ton aide.

              Je vais continué la lecture de mon livre sur le C et approfondir mes connaissances après avoir galéré sur les pointeurs et les structures

              Rien que la ligne :

              Code:
              Point *array[5];
              Un tableau de pointeur de type "Point" me fait frissonné
              Dernière modification par shirocen, 01 janvier 2015, 23h48.
              deux et deux font cinq

              Commentaire


              • #22
                Un tableau de pointeur de type "Point" me fait frissonné
                Au lieu d'avoir un tableau de valeurs, tu as un tableau d'adresses, tout simplement... Pour avoir leur valeur, tu devras déréférencer (avec l'opérateur *) ton adresse et accéder aux différents attributs avec le point ( (*g).x par exemple ) ou plus simplement utiliser l'opérateur -> ( g->x par exemple ).

                Bonne continuation...

                Commentaire


                • #23
                  Bonjour à tous,

                  je rencontre quelques difficultés pour l'exercice n°1 :

                  Code:
                  #include <stdio.h>
                  #include <string.h>
                  #include "fonction.h"
                  
                  
                  int main(void)
                  {
                      char produits[3][50];
                      produits[0] = "tomates";
                      produits[1] = "Pomme de terre";
                      produits[2] = "betterave";
                  
                      struct article monPanier[3];
                  
                      strcpy(monPanier[0].nom,produits[0]);
                      strcpy(monPanier[1].nom,produits[1]);
                      strcpy(monPanier[2].nom,produits[2]);
                  
                      monPanier[0].prix = 1.5;
                      monPanier[1].prix = 1.0;
                      monPanier[2].prix = 2.0;
                  
                      monPanier[0].quantite = 100;
                      monPanier[1].quantite = 200;
                      monPanier[2].quantite = 50;
                  
                      afficher(monPanier);
                  
                  }
                  
                  void afficher(struct article art)
                  {
                      int i;
                  
                      for(i=0; i<3; i++)
                      {
                          printf("L'article %s coute : %f / La quantite restante est : %d\n", art[i].nom, art[i].prix, art[i].quantite);
                      }
                  }
                  Code:
                  #ifndef FONCTION_H_INCLUDED
                  #define FONCTION_H_INCLUDED
                  
                  struct article
                  {
                      const char nom[50];
                      double prix;
                      int quantite;
                  
                  } article;
                  
                  void afficher(struct article art);
                  
                  #endif
                  L'assignation des structures par le biais d'un tableau se fait bien comme cela ? :s
                  Dernière modification par shirocen, 18 janvier 2015, 18h07.
                  deux et deux font cinq

                  Commentaire


                  • #24
                    Ah non ! Surtout pas

                    Code:
                    produits[0] = "tomates";
                        produits[1] = "Pomme de terre";
                        produits[2] = "betterave";
                    Ça c'est niet de chez niet, regarde du côté de strcpy

                    Commentaire


                    • #25
                      Justement, je pensais bien faire

                      Sachant qu'il est interdit d'écrire directement dans la structure, j'ai créer des variables contenant la chaine à écrire

                      pour ensuite utiliser strcpy pour écrire sur la structure :

                      Code:
                      strcpy(monPanier[0].nom,produits[0]);
                      strcpy(monPanier[1].nom,produits[1]);
                      strcpy(monPanier[2].nom,produits[2]);
                      C'est peut-être ça qui t'embêtes

                      Code:
                      produits[0] = "tomates";
                      produits[1] = "Pomme de terre";
                      produits[2] = "betterave";
                      ->
                      Code:
                      produits[0][0] = "tomates";
                      produits[1][0] = "Pomme de terre";
                      produits[2][0] = "betterave";
                      je vois pas comment écrire dessus, j'ai jamais utilisé les tableaux à deux dimensions.
                      deux et deux font cinq

                      Commentaire


                      • #26
                        Non ce qui m'embête c'est l'initialisation que tu n'as pas le droit de faire.

                        Soit tu initialises comme cela

                        Code:
                        const char produits[3][50] = {"tomates", "pommes de terre", "betteraves"};
                        Soit comme tu as fais, mais

                        Code:
                        strcpy(produits[0], "tomates");
                        /* etc */
                        Tu vois le truc ou pas ?

                        Commentaire


                        • #27
                          Okok.

                          Donc nous sommes obligé d'utiliser ces deux méthodes pour modifier les tableaux à deux dimensions.

                          Le code suivant fonctionne :

                          Code:
                          #include <stdio.h>
                          #include <string.h>
                          #include "fonction.h"
                          
                          
                          int main(void)
                          {
                              char produits[3][50] = {"tomates","betterave","poireau"};
                          
                          
                              struct article monPanier[3];
                          
                              strcpy(monPanier[0].nom,produits[0]);
                              strcpy(monPanier[1].nom,produits[1]);
                              strcpy(monPanier[2].nom,produits[2]);
                          
                              monPanier[0].prix = 1.5;
                              monPanier[1].prix = 1.0;
                              monPanier[2].prix = 2.0;
                          
                              monPanier[0].quantite = 100;
                              monPanier[1].quantite = 200;
                              monPanier[2].quantite = 50;
                          
                              afficher(monPanier);
                          
                          }
                          
                          void afficher(struct article art[])
                          {
                              int i;
                          
                              for(i=0; i<3; i++)
                              {
                                  printf("L'article %s coute : %f  La quantite restante est : %d\n", art[i].nom, art[i].prix, art[i].quantite);
                              }
                          }
                          Code:
                          #ifndef FONCTION_H_INCLUDED
                          #define FONCTION_H_INCLUDED
                          
                          struct article
                          {
                              const char nom[50];
                              double prix;
                              int quantite;
                          
                          } article;
                          
                          void afficher(struct article art[]);
                          
                          #endif
                          Par contre je trouve dommage qu'on ne puisse pas toucher aux valeurs du tableau en dehors de l'initialisation et de la fonction "strcpy"
                          Dernière modification par shirocen, 19 janvier 2015, 19h19.
                          deux et deux font cinq

                          Commentaire


                          • #28
                            Donc nous sommes obligé d'utiliser ces deux méthodes pour modifier les tableaux à deux dimensions.
                            Oui mais pas seulement deux, une seule aussi par exemple...

                            Pour le code j'ai pas le temps de tester mais ça me semble correct.

                            Commentaire


                            • #29
                              Exercice n°1 :

                              Code:
                              #include <stdio.h>
                              #include <string.h>
                              #include "supermarche.h"
                              
                              int main(void)
                              {
                                 struct article mesArticles[3];
                              
                                 struct article a; /* initialisation des articles */
                                 struct article b;
                                 struct article c;
                              
                                 strcpy(mesArticles[0].nom, "Computer");
                                 mesArticles[0].prix = 512.5;
                                 mesArticles[0].quantite = 1;
                              
                                 strcpy(mesArticles[1].nom, "Bières");
                                 mesArticles[1].prix = 5;
                                 mesArticles[1].quantite = 12;
                              
                                 strcpy(mesArticles[2].nom, "Bonbons");
                                 mesArticles[2].prix = 2.5;
                                 mesArticles[2].quantite = 5;
                              
                                 int i;
                                 for (i = 0; i<3 ; i++)
                                 {
                                     afficher(mesArticles[i]);
                                 }
                                  return 0;
                              }
                              
                              
                              void afficher(struct article art)
                              {
                                  printf("nom : %s \n", art.nom);
                                  printf("prix : %f \n", art.prix);
                                  printf("quantite : %d \n \n", art.quantite);
                              }
                              Code:
                              #ifndef SUPERMARCHE_H_INCLUDED
                              #define SUPERMARCHE_H_INCLUDED
                              
                              struct article
                              {
                                  const char nom[20];
                                  double prix;
                                  int quantite;
                              } article;
                              
                              void afficher(struct article art);
                              
                              #endif
                              Je ferais surement le deux cette après-midi, j'éditerais mon post en conséquence

                              Edit : comme promis

                              Exercice n°2 :

                              Code:
                              #include <stdio.h>
                              #include <string.h>
                              #include "livre.h"
                              
                              void main(void)
                              {
                                  struct livre a;
                                  strcpy(a.title, "1984");
                                  strcpy(a.author, "George Orwell");
                                  a.year = 1948;
                              
                                  struct livre b;
                                  strcpy(b.title, "Le Pavillon d\'Or");
                                  strcpy(b.author, "Yukio Mishima");
                                  b.year = 1956;
                              
                                  display(a);
                                  display(b);
                                  /* En fait il est paru en 1956 au Japon mais traduit en français qu'en 1960 */
                                  b.year = 1960;
                                  display(b);
                              
                                  return 0;
                              }
                              
                              void display(struct livre l)
                              {
                                  printf("Titre : %s \n", l.title);
                                  printf("Auteur : %s \n", l.author);
                                  printf("Année de parution : %d \n \n", l.year);
                              }
                              Code:
                              #ifndef LIVRE_H_INCLUDED
                              #define LIVRE_H_INCLUDED
                              
                              struct livre
                              {
                                  const char title[100];
                                  const char author[50];
                                  int year;
                              }livre;
                              
                              void display(struct livre l);
                              
                              #endif
                              Dernière modification par Sadik, 25 janvier 2015, 13h44.
                              Mon blog : http://rootsheep.info

                              Commentaire

                              Chargement...
                              X