IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C Discussion :

différentes questions d'un débutant


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre actif
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2013
    Messages
    84
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Tunisie

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Février 2013
    Messages : 84
    Par défaut différentes questions d'un débutant
    bonjour,
    Je suis arrivé à écrire ce code et je veux vous poser quelques questions.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    #include <pthread.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <sys/time.h>
    #define nbre_cycle 10
    #define nbre_trame 2
    #define PTU 1
     
    ////////////////////////////////////////////////////////////////////
    typedef struct signaux_thread
    {
       int sync ;
      char *(*schedule_table)[nbre_trame];
    }signaux_thread;
    ////////////////////////////////////////////////////////////////////
    void *func_thread (void *arg) 
    {
      int j;
      struct signaux_thread * signal= (struct signaux_thread *)arg;   
      fprintf(stderr,"sync frame number: %d\n ",signal->sync);
     
      for (j=0;j<nbre_trame;j++)
    	    {
    	      fprintf(stderr,"la trame %s est envoyée\n",signal->schedule_table[signal->sync][j]);	   
    	    }
     
    }
    ///////////////////////////////////////////////////////////////////
    int main(void)
    {
      int i,j;
     
      pthread_t thread;
      char *ScheduleTable[nbre_cycle][nbre_trame];
      struct signaux_thread arg;
      arg.sync = 0;
      arg.schedule_table = ScheduleTable;
      for ( i=0;i<nbre_cycle;i++)
        {
          for ( j=0;j<nbre_trame;j++)
    	{
    	  ScheduleTable[i][j]=(char*)malloc(3 * sizeof(char));
    	  sprintf(ScheduleTable[i][j],"%d.%d",i,j);
    	}
        }
      while(1)
        {
          if(pthread_create(&thread,NULL,func_thread,&arg)!=0)
    	{
    	  fprintf(stderr,"can't create thread");
    	  exit(EXIT_FAILURE);
    	}
          arg.sync++;
           if (arg.sync==nbre_cycle)
    	 {arg.sync=0;}
          sleep(PTU);
        }
    }
    1/ je trouve des difficultés a comprendre toutes instructions(surtout les prtotypes) contenant ( void *) ou (int *) et d'autres formes.
    comme
    • void *func_thread (void *arg)
    • struct signaux_thread * signal= (struct signaux_thread *)arg;
    • char *(*schedule_table)[nbre_trame];


    2/ et pour l’exécution de ce code voila comment ça se passe
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    sync frame number: 1
     la trame 1.0 est envoyée
    la trame 1.1 est envoyée
    sync frame number: 2
     la trame 2.0 est envoyée
    la trame 2.1 est envoyée
    sync frame number: 3
     la trame 3.0 est envoyée
    la trame 3.1 est envoyée
    alors que je pensais que ça doit commencer par 0 et non par 1

  2. #2
    Membre Expert
    Avatar de Metalman
    Homme Profil pro
    Enseignant-Chercheur
    Inscrit en
    Juin 2005
    Messages
    1 049
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Enseignant-Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 049
    Par défaut
    Le void* signifie souvent que tu peux mettre "ce que tu veux", à l'inverse de void tout seul qui signifie "rien du tout".

    Les int* en paramètre sont souvent associés au fait que la fonction/procédure modifiera la valeur... OU qu'il s'agit d'un tableau d'entiers qui est lu et/ou modifié.

    Ce qui me frappe le plus c'est ton "char *(*schedule_table)[nbre_trame];"
    Alors ça... jamais vu de ma vie...
    Bref, ton void* en paramètre d'une fonction est très trompeur car il acceptera TOUS les types... du coup, le compilo sera content quoique tu donnes en paramètre, mais cela risque de faire n'importe quoi tu appellera la fonction avec des paramètres de diverses tailles (si tu envoies un char au lieu d'une structure, etc...).
    Le cast de la structure est pas génial....

    Tu devrais mieux typer ta fonction pour savoir exactement ce qu'elle peut accepter et faire.

    Pour ton problème de 0 :
    Tu crées un thread et juste après tu incrémentes ta valeur !
    Si le thread a la main en 1er, il verra 0, mais s'il passe en 2e il verra 1 !
    A toi d'utiliser des verrous pour bloquer l'accès à la variable.
    --
    Metalman !

    Attendez 5 mins après mes posts... les EDIT vont vite avec moi...
    Les flags de la vie : gcc -W -Wall -Werror -ansi -pedantic mes_sources.c
    gcc -Wall -Wextra -Werror -std=c99 -pedantic mes_sources.c
    (ANSI retire quelques fonctions comme strdup...)
    L'outil de la vie : valgrind --show-reachable=yes --leak-check=full ./mon_programme
    Et s'assurer que la logique est bonne "aussi" !

    Ma page Developpez.net

  3. #3
    Membre actif
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2013
    Messages
    84
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Tunisie

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Février 2013
    Messages : 84
    Par défaut
    merci pour tes explications et est ce que vous pouvez me corriger la ligne que vous n'avez jamais vu ? je voulais juste déclarer un élément matrice dans ma structure.

    Rem : Pour l'histoire de l’incrémentation je l'ai déplacée après la ligne sleep (PTU) et ça marche bien.

  4. #4
    Membre Expert
    Avatar de kwariz
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Octobre 2011
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2011
    Messages : 898
    Par défaut
    Citation Envoyé par Metalman Voir le message
    [...]
    Ce qui me frappe le plus c'est ton "char *(*schedule_table)[nbre_trame];"
    Alors ça... jamais vu de ma vie...
    [...]
    schedule_table est un pointeur sur un tableau de nbre_trame pointeurs sur char, cela a été préconisé fort justement par diogène dans un post précédent.

  5. #5
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 493
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 493
    Billets dans le blog
    1
    Par défaut
    Je n'ai pas Linux donc pas de pthread. Je n'ai donc pas lancé ton code. En lisant je peux te dire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    #define nbre_cycle 10
    #define nbre_trame 2
    On met en général les noms de constantes crées avec des macros en majuscules. En lisant le code, on sait ainsi que ce sont des macros et non des variables. Personnellement, je me suis tout de suite demandé où étaient définies ces variables au premier coup d'oeil sur ton code.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void *func_thread (void *arg)
    Ta fonction prend un pointeur sur une zone de n'importe quel type et renvoie quelque chose de similaire, comme expliqué par metalman.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    struct signaux_thread * signal= (struct signaux_thread *)arg;
    Comme un void* pointe sur une zone mémoire qui peut être n'importe quoi, tu peux caster ce pointeur vers un pointeur d'un type voulu pour interpréter la zone comme tel. Ici, tu interprètes la zone pointée comme une structure signaux_thread. Note que rien ne te garantit que c'est effectivement une telle structure qui est réellement à cet endroit et tu peux donc lire n'importe quoi.

    Ton code ne semble pas être un cas d'erreur, pourquoi avoir choisi le flux stderr et non stdout ?

  6. #6
    Membre actif
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2013
    Messages
    84
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Tunisie

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Février 2013
    Messages : 84
    Par défaut
    je suis en train d'apprendre ce que je fais n'est pas 100 % intentionnel .

  7. #7
    Membre Expert
    Avatar de Metalman
    Homme Profil pro
    Enseignant-Chercheur
    Inscrit en
    Juin 2005
    Messages
    1 049
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Enseignant-Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 049
    Par défaut
    Le sleep n'est pas "une bonne réponse" en soi...

    Pourquoi elle semble être bonne ?
    Le comportement de sleep fait que le processus rend la main "en général" et se fait réveiller après.
    Du coup, la variable n'est pas modifiée par le programme à ce moment.

    Pourquoi cela n'est pas la bonne solution ?
    Je n'ai pas le man de sleep en tête (surtout pour la partie thread), mais ça n'est pas impossible qu'il endorme "aussi" le thread ! Et l'OS réveille celui qu'il veut en premier.
    De plus, sur certains SMP tu risques d'avoir le thread ET l'applications qui tourneront simultanément....

    Bref, du comportement parfaitement indéfini.

    Pour la ligne bizarre, je ne sais pas trop ce que tu voulais faire, par contre je peux te dire que tu devrais déclarer ta fonction ainsi :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void *func_thread (struct signaux_thread * signal)
    Et retirer la ligne qui déclare la variable.
    --
    Metalman !

    Attendez 5 mins après mes posts... les EDIT vont vite avec moi...
    Les flags de la vie : gcc -W -Wall -Werror -ansi -pedantic mes_sources.c
    gcc -Wall -Wextra -Werror -std=c99 -pedantic mes_sources.c
    (ANSI retire quelques fonctions comme strdup...)
    L'outil de la vie : valgrind --show-reachable=yes --leak-check=full ./mon_programme
    Et s'assurer que la logique est bonne "aussi" !

    Ma page Developpez.net

  8. #8
    Membre actif
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2013
    Messages
    84
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Tunisie

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Février 2013
    Messages : 84
    Par défaut
    voila ce que je veux faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    char *schedule_table [nbre_cycle][nbre_trame];
    et voila ce que ça donne a la compilation
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    erreur: incompatible types when assigning to type ‘char *[10][2]’ from type ‘char * (*)[2]

Discussions similaires

  1. Petite question d'un débutant en C++
    Par faboulous dans le forum C++
    Réponses: 6
    Dernier message: 04/08/2006, 15h43
  2. Réponses: 4
    Dernier message: 06/07/2006, 17h14
  3. Question d'un débutant sur Access
    Par RV80 dans le forum Access
    Réponses: 8
    Dernier message: 12/06/2006, 12h32
  4. Différentes questions algorithmiques
    Par Premium dans le forum Algorithmes et structures de données
    Réponses: 6
    Dernier message: 22/12/2005, 10h26
  5. question d'un débutant...
    Par chti_juanito dans le forum Général JavaScript
    Réponses: 8
    Dernier message: 01/06/2005, 10h29

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo