[programation] Structure et pointeur de structure.

Voila j'essaye toujour de m'ameliore en programation et je ne trouve pas ma reponse (meme sur internet)
est ce que l'on peut ecrire ce qui suit ( soustraction de pointeur de structure):

typedef struct Date Date;
struct Date
{
    int j;
    int m;
    int a;
};


/*_____________________________________________fonction evenement____________________________*/
// verifi si un evenement a eu lieu il prend en parametre deux date ( celle a verifier, celle de reference).

boolean Evenement(Date*date_1,Date*date){
  boolean reponse=false;

  if( date_1->a-date->a==0 && date_1->m-date->m==0 &&date_1->j-date->j>=0){// c'est ici que je suis pas sur!!!
    reponse=true;
  };
  if(date_1->a-date->a==0 && date_1->m-date->m>0){
    reponse=true;
  };
  if(date_1->a-date->a>0){
    reponse=true;
  };

  return reponse;
}

ça compile mais j'ai pas de quoi tester pour le moment , merci de votre aide!

Bonjour,

Bienvenue dans le monde merveilleux de l'ide arduino : quand tu commences à sortir des sentiers battus ya plus rien qui marche :grin:
Met ton typedef et ta déclaration de structure dans un fichier .h dans le même dossier que ton programme.
Et inclut ce .h dans ton programme, tout (re)marcheras comme par magie.

Pourquoi ? (blabla technique) :
En fait l'ide arduino n'extrait pas les typedef qui se retrouve donc âpres les prototypes de fonctions "auto-généré", du coup tout plante à la compilation sans raison.

Au passage, c'est tellement plus simple :

typedef struct Date
{
    int j;
    int m;
    int a;
} Date;

Merci skywodd!

Mais en fait sa compile trés bien ,c'est juste que je suis pas sur de l'ecriture avec le pointeur de structure , car pour le reste l'ide ne ma pas posé de souci, et j'ai bien fait un .h( je suis en train de me faire des petite bibliothéque pour me simplifier la vie)

voila par exemple le code a verifier :frowning: le coup des" ->")

if(date_1->a-date->a>0){
    reponse=true;
  };

Heloderma-kris:
Mais en fait sa compile trés bien ,c'est juste que je suis pas sur de l'ecriture avec le pointeur de structure , car pour le reste l'ide ne ma pas posé de souci, et j'ai bien fait un .h( je suis en train de me faire des petite bibliothéque pour me simplifier la vie)

T'avais déjà fait le .h, t'est du genre chanceux on dirait :grin:

Heloderma-kris:
voila par exemple le code a verifier :frowning: le coup des" ->")

if(date_1->a-date->a>0){

reponse=true;
  };

Simple :
pointeur ->
variable .
Donc ici les flèches sont effectivement adaptées :wink:

Par contre, j'avais pas vu (t'as eu de la chance !) :

  if( date_1->a-date->a==0 && date_1->m-date->m==0 &&date_1->j-date->j>=0){// c'est ici que je suis pas sur!!!
    reponse=true;
  };

C'est quoi ce ; en fin d'accolades ? Il a rien à faire là (même si c'est pas une erreur syntaxiquement parlant) :wink:
Et attention les parenthèses ne servent pas qu'as faire jolie dans les tests.

boolean Evenement(Date* date_1, Date* date) {

  if ((date_1->a - date->a) == 0 && (date_1->m - date->m) == 0 && (date_1->j - date->j) >= 0)
    return true;

  if ((date_1->a - date->a) == 0 && (date_1->m - date->m) > 0)
    return true;

  if ((date_1->a - date->a) > 0)
    return true;

  return false;
}

Merci c'est vrai que j'en colle partout des ";" et les parenthése a part clarifier le code la elle non pas de vrai role non?

petite question( peut etre béte :P) en passant est ce que les pointeurs prenent exactement la meme taille que leur type ou alors il on une place memoire bien caractéristique?

par exemple

void mafonction(int a,int b){
//le corps de ma fonction
};

void mafonction(int *a,int *b){
//le corps de ma fonction
};

est ce que la deuxieme genere moin de place en RAM ou pas?

PS : je veux bien la reponse pour le enumeration egalement!! :grin:

Heloderma-kris:
Merci c'est vrai que j'en colle partout des ";" et les parenthése a part clarifier le code la elle non pas de vrai role non?

Les parenthèses sont là pour clarifier le code mais surtout pour éviter toutes erreurs dans le if.
Tu le vois bien, avec des parenthèses et des espaces le code est tout de suite beaucoup plus simple à comprendre / modifier.
Ce n'est pas obligatoire mais autant prendre l'habitude dés le début :wink:

Heloderma-kris:
petite question( peut etre béte :P) en passant est ce que les pointeurs prenent exactement la meme taille que leur type ou alors il on une place memoire bien caractéristique?

Bien sûr que non et heureusement puisse que c'est le but de pointeurs : ne pas avoir à copier de contenu.
Un pointeur prend toujours 2 octets sur AVR (ou 3 sur les gros ATmega style mega2560).
Par conséquent faire une pointeur sur byte / char / int / long / ... (types primaires) n'as pas grand intérét si tu peut t'en passer (= tu n'as pas à retourner plusieurs résultats).
Par contre sur une structure ça peut être avantageux d'avoir un pointeur car tu ne copie pas son contenu lors de l'appel à la fonction.

Heloderma-kris:
PS : je veux bien la reponse pour le enumeration egalement!! :grin:

Une énumération est une série de constantes de type int.

voila une reponse claire!
Merci c'est exactement ce que je voulais !
et c'est difficile de trouvé ce type de reponse je trouve !

nouvelle question :

je galere comme pas possible pour faire un pointeur vers un tableau de structure , je sais pas si c'est moi qui est C.. :0 alors voila le prototpe:

void foncSaison( Saison *(saison[]),int nbSaison,Date*rtc,float *Tmax ,float *Tmin ,float*Tmoy);

/*c'est le *Saison qui me casse la tete*/

dans mon code je cherche a l'utiliser comme suit :

Saison tabsaison[4];

foncSaison(&tabsaison,4,&rtcD,&tmax,&tmin,&tmoy);

est ça c'est l' erreure

serpentduino.ino: In function 'void loop()':
serpentduino:39: error: cannot convert 'Saison*' to 'Saison**' for argument '1' to 'void foncSaison(Saison**, int, Date*, float*, float*, float*)'

merci d'avance

bon j'ai finalement reusi a compiler mais je compren pas pourkoi!

le code de la fonction et le suivant :
cette fonction me permet de calculer des temperature de consigne a partire de date de valeur et de longueur de la monté bref

/*_________________________________________ calcule de la temperature a apliqué par saison ______________________________________________*/
void foncSaison( Saison *saison,int nbSaison,Date*rtc,float *Tmax ,float *Tmin ,float*Tmoy){
//nbSaison = nombre de saison

  int indexSaison=0;
  int indexprecedent=0;
  float deltaMAX=0;
  float deltaMIN=0;
  float deltaMOY=0;
  int nbJour=0;
  float nbSemaine=0;

  for (byte i=0; i<nbSaison;i++){

    if ( Evenement((&saison[i].date),rtc)==true){
      indexSaison=i;
    };//detecte a quel niveau d'evenement on ce situ

  }

  //indexprecedent=constrainCycle((indexSaison-1),0,3);// on calcule l'index précédent

  deltaMAX=((saison[indexSaison].tempMax)-(saison[indexprecedent].tempMax))/(saison[indexSaison].nbS);//on calcul le delta de temperature par semaine
  deltaMIN=((saison[indexSaison].tempMin)-(saison[indexprecedent].tempMin))/(saison[indexSaison].nbS);//on calcul le delta de temperature par semaine
  deltaMOY=((saison[indexSaison].tempMoy)-(saison[indexprecedent].tempMoy))/(saison[indexSaison].nbS);//on calcul le delta de temperature par semaine



  //si nous somme dans le mois en cour
  if((rtc->a-saison[indexSaison].date.a)==0 && (rtc->m-saison[indexSaison].date.m)==0){
    nbJour=(rtc->j-saison[indexSaison].date.j);
  };

  //si nous somme dans l'annee en cour mais pas dans le mois
  if((rtc->a-saison[indexSaison].date.a)==0 && (rtc->m-saison[indexSaison].date.m)>0){
    nbJour=0;


    for (int mois=((saison[indexSaison].date.m)+1); mois<(rtc->m);mois++){
      nbJour=nbJour+jParM[mois-1];
    }   //les jour des mois entier

    nbJour=nbJour+(jParM[(saison[indexSaison].date.m)-1])-((saison[indexSaison].date.j));//on ajoute les jour restant du moi de levenement
    nbJour=nbJour+(rtc->j);                 //on ajoute les jour ecouler du moi en cour
  };
  //si nous ne somme pas dans la meme annee
  if((rtc->a)-(saison[indexSaison].date.a)>0){
    for (byte mois=1; mois<rtc->a;mois++){
      nbJour=nbJour+jParM[mois-1];
    }///penser a anne bisex
    for (byte mois=int(saison[indexSaison].date.m+1); mois<=12;mois++){
      nbJour=nbJour+jParM[mois-1];
    }///penser a anne bisex
    nbJour=nbJour+ (jParM[(saison[indexSaison].date.m)-1])-(saison[indexSaison].date.j);//on ajoute les jour restant du moi de levenement
    nbJour=nbJour+(rtc->j);//on ajoute les jour ecouler du moi en cour
  };

  nbSemaine=nbJour/7;


  *Tmax= saison[indexprecedent].tempMax+ (nbSemaine*deltaMAX);
  *Tmoy= saison[indexprecedent].tempMin+ (nbSemaine*deltaMIN);
  *Tmin= saison[indexprecedent].tempMoy+(nbSemaine*deltaMOY);

  if (nbSemaine>saison[indexSaison].nbS){
    *Tmax=saison[indexSaison].tempMax;
    *Tmoy=saison[indexSaison].tempMoy;
    *Tmin=saison[indexSaison].tempMin;
  };


  return;
}

pour moi quand on declare un pointeur de structure

comme ceci:

Structure *P_structure;

on obtenai la valeur dune variable de la structure par

une_variable=P_structure->variable;

comme mon pointeur Date*rtc
qui lui semble fonctioné je pije plus là :frowning:

ps ce code compile mais du coup je sui pas sur qu'i face bien ce que je veux!

Heloderma-kris:
je galere comme pas possible pour faire un pointeur vers un tableau de structure , je sais pas si c'est moi qui est C.. :0 alors voila le prototpe:

void foncSaison( Saison *(saison[]),int nbSaison,Date*rtc,float *Tmax ,float *Tmin ,float*Tmoy);

Un tableau est de fait un pointeur.

Saison *(saison[])

Ça aurait presque pu être un pointeur sur un tableau multi-dimensionnel mais la syntaxe n'est pas le même :stuck_out_tongue:

Heloderma-kris:
pour moi quand on declare un pointeur de structure

comme ceci:

Structure *P_structure;

on obtenai la valeur dune variable de la structure par

une_variable=P_structure->variable;

comme mon pointeur Date*rtc
qui lui semble fonctioné je pije plus là :frowning:

Tu sembles oublier un truc ... un pointeur pointe sur quelque chose.

MaStruct_t *p;

p est un pointeur qui pointe ... sur rien, il faut l'initialiser avant de l'utiliser.

Mon coco va falloir reprendre les cours de C :wink:
Allez hop hop hop :
http://www.siteduzero.com/informatique/tutoriels/apprenez-a-programmer-en-c/a-l-assaut-des-pointeurs
http://www.siteduzero.com/informatique/tutoriels/apprenez-a-programmer-en-c/pointeur-de-structure
http://www-igm.univ-mlv.fr/~paumier/C/C5-types%20structures.pdf

j'arete pas de relire les site mais je comprend pas en plus selon les site il ecrive pas tous de la meme magniere !

est ce que je comprend bien ?

lorsque je pase une structure a un pointeur de structure pour obtenir la variable on utilise ->
ex:

structure A;

fonction(structur *ptr_A){

une_variable=*(ptr_A).varX;
/* meme chose que :*/
une_variable=ptr_A->varX;
};

mais dans le cas d'un tableau qui est passer a une fonction il est consideré comme une adresse c'est ça non ?
donc :

structure A[];

fonction(structur *ptr_A){
/* directe on utilise */
une_variable=A[i].varX;

skywodd : desoler si j'ai du mal a comprendre , pour les pointeur clasique de variable j'ai je pense bien compris et pour les pointeur de structure clasique ausssi mais c'est pour les pointeur de tableaux de structure que je block grave!

que faut'il donc ecrire:
pour la fonction :

foncSaison( Saison *(saison[]));

avec pour utiliser le pointeur dans la fonction:

*(saison[indexSaison]).tempMax)

qui pour moi est la meme que :

(saison[indexSaison])->tempMax)

ou

foncSaison( Saison *saison);

avec pour utiliser le pointeur dans la fonction:

saison[indexSaison]).tempMax

avec pour utiliser la fonction

foncSaison( tab_structure);

je n'arrive plus a savoir a quel moment c'est une adresse et a quel moment c'est la variable situer a l'adresse! :expressionless:

char[] et char * sont tout deux des pointeurs.
Sauf que le premier réserve l'espace requis alors que le deuxième ne fait que pointer sur quelque choses sans réserver d'espace.

En gros :

foncSaison(Saison saison[]);

(attention bien que ce soit des [] ça ce comporte comme un pointeur simple dans le prototype d'une fonction)
ou plus simplement :

foncSaison(Saison* saison);

Puis :

Saison tab_structure[4];
// ...
foncSaison(tab_structure);

et dans la fonction :

saison[...] = ...;

Si tu veut un pointeur sur pointeur :

foncSaison(Saison** saison);

ou

foncSaison(Saison* saison[]);

Si tu veut un pointeur sur pointeur :

foncSaison(Saison** saison);

ou

foncSaison(Saison** saison);

heu est ce que c'est pas ça que tu voulais ecire:

foncSaison(Saison** saison);

ou

foncSaison(Saison* saison[]);

pour resume c'est bien parsque c'est un tableau de structure que la sytax est differente

dans les deux cas qui suivent on initialise le pointeur de structure ou de tableau de structure avec

 fonction(structure *ptr_structure);

donc pour un tableau de structure on obtiendra la valeur par

valeur de la variable =ptr_structur.champ

alorque dans le cas ou on envoi pas un tableau mes une structure on aurat

valeur de la variable =*(ptr_structur).champ

ou bien encore:

valeur de la variable =ptr_structur->champ

Heloderma-kris:
heu est ce que c'est pas ça que tu voulais ecire:

foncSaison(Saison** saison);

ou

foncSaison(Saison* saison[]);

Oui c'est ça.

Heloderma-kris:
pour resume c'est bien parsque c'est un tableau de structure que la sytax est differente

Les structures contiennent plusieurs champs, d'ou le point et la flèche pour y accéder.
C'est juste une extension à la syntaxe des pointeurs de base.

Heloderma-kris:
donc pour un tableau de structure on obtiendra la valeur par

valeur de la variable =ptr_structur.champ

NON NON NON NOOOOON

Pour un tableau :

val = ptr_structure[x].champs;

ptr_structure : pointeur sur la première structure du tableau
ptr_strcuture[...] : accès à une des structures du tableau (alloué en mémoire)
ptr_structure[...].champs : accès à un des champs de la structure dans le tableau

Faut bien comprendre qu'un pointeur peut pointer sur 1 à N valeurs (quelque soit le type, int, char, struct, ...).
Si tu fait :

*pointeur = val;

ou :

pointeur[0] = val;

c'est la même chose.

Heloderma-kris:
alorque dans le cas ou on envoi pas un tableau mes une structure PAR POINTEUR on aurat

valeur de la variable =*(ptr_structur).champ

ou bien encore:

valeur de la variable =ptr_structur->champ

Oui

Heloderma-kris:
donc pour un tableau de structure on obtiendra la valeur par

valeur de la variable =ptr_structur.champ

NON NON NON NOOOOON

oups desoler c'eait ce que tu a s ecri que je voulais ecrire !

merci c'est bien plus claire maintenant
desoler mais sur internet j'arrivais pas a comprendre
meme dans le bouquin du site du zero c'est pas expliqué comme ça !