1

Bonjour;

Je débute dans la programmation C sur TI (merci TIGCC tongue) et donc j'ai quelques problèmes pour le passage de paramètres entre autres :/

Voila je voudrais passer une liste ou matrice à un programme.
genre :
{1,2,3,4,5}->liste
monprog(list)
ou encore
monprog({1,2,3,4})

le problème c'est que je ne sais pas du tout comment la récuperer après.
J'ai compris pour les int et string etc mais liste et matrice j'y arrive pas.

Je suis ouvert a toutes proposition smile

2

Tiens regarde les tutos de C de squale92.

Tu ne peux pas passer un tableau en argument ni en renvoyer mais tu peux faire ça à l'aide de pointeur wink lis les tutos.
avatar
Combien de tas de bois une marmotte pourrait couper si une marmotte pouvait couper du bois ?

3

j'ai pas encore parlé de ce genre de trucs dans mon tuto sad
(faut dire qu'on utilise pas ça tous les jours)

si tu y arrives avec des ints ou des strings, c déjà pas mal : ça doit être un peu dans le même principe, mais avec des LIST_TAG ou dans le genre
(pas touché à ça depuis super longtemps ; coder des programmes pour les maths, c pas mon truc grin )
et là, tu trouves les données de ta liste, en ordre inverse, si j'ai bonne mémoire
avatar
Tutorial C (TI-89/92+/v200) - Articles Développement Web (PHP, Javascript, ...)
« What is the sound of Perl? Is it not the sound of a wall that people have stopped banging their heads against? » - Larry Wall

4

Oh j'avais mal lu je pensais qu'il s'agissait de fonction classiques dans un programme tsss désolé.

Mais tu peux regarder les exemples fournis avec TIGCC
-Add Arguments
-Symbolic Add Arguments
Et la faq de TIGCC, ils en parlent.
avatar
Combien de tas de bois une marmotte pourrait couper si une marmotte pouvait couper du bois ?

5

C'est remoi

Bon il y a du progres , j'accede au 1ier élément de ma liste (pour acceder au autres ca devrait pas être trop difficile maintenant tongue).
Je sais pas si c'est la bonne façon de faire mais bon c'est déjà ça

ca ressemble a ca : void _main(void) {   ESI ap;   clrscr();   InitArgPtr(ap);   if (ArgCount()>0)   {    if (GetArgType(ap) == LIST_TAG)    {       printf("LIST_TAG\n");       top_estack--;     }     ngetchx();     if (GetArgType(top_estack) == POSINT_TAG)       printf("%lu",GetIntArg(top_estack));     ngetchx();   } }

Merci a vous 2

6

Tu utilises la bonne méthode. Je t'invite à consulter estack.h pour parvenir à tes fins.
avatar
« Quand le dernier arbre sera abattu, la dernière rivière empoisonnée, le dernier poisson capturé, alors vous découvrirez que l'argent ne se mange pas. »

7

Me revoila smile

Bon alors j'ai réussit a récuperer une matrice depuis l'estack mais par contre je me retrouve avec un programme bien gros je trouve pour ce que ca fait :/ // C Source File // Created 31/03/2005; 16:15:06 // Delete or comment out the items you do not need. #define COMMENT_STRING         "Place your comment here." #define COMMENT_PROGRAM_NAME   "Place your program name here." #define COMMENT_VERSION_STRING "Place your version string here." #include <tigcclib.h> static int sizeMat; int **StackToMat(ESI stack) {      ESI save_stack=stack;      int nb_row=0, nb_line=0, nb_tag=1;      int i,j;      int **mat;              //si on pointe pas sur le début d'une liste on retourne null      if (GetArgType(stack)!=LIST_TAG)           return NULL;      stack--;         //calcul des dimension de la matrice      while (nb_tag!=0 && GetArgType(stack)!=ENDSTACK_TAG)      {           printf("%d\n",nb_tag);           switch(GetArgType(stack))           {                case LIST_TAG:                     nb_tag++;                     stack--;                break;                     case END_TAG:                     nb_tag--;                  nb_line++;                     stack--;                break;                               case POSINT_TAG:                     SkipArg(stack);                     nb_row++;                break;                case NEGINT_TAG:                     SkipArg(stack);                     nb_row++;                break;                default:                     return NULL;           }      }   // la liste n'est pas fini correctement      if (GetArgType(stack)==ENDSTACK_TAG)           return NULL;            //restoration du pointeur de pile d'origine           stack=save_stack;      nb_line--;      nb_row=(int)sqrt(nb_row);            //allocation de la matrice      mat=malloc(nb_line*sizeof(int*));      for (i=0; i<nb_line; i++)           mat[i]=malloc(nb_row*sizeof(int));      sizeMat=nb_line;                 //remplissage de la matrice           i=0;      j=0;      nb_tag=1;           while (nb_tag!=0)      {           switch(GetArgType(stack))           {                case POSINT_TAG:                     mat[i][j]=(int)GetIntArg(stack);                     j++;                break;                case NEGINT_TAG:                     mat[i][j]=-(int)GetIntArg(stack);                     j++;                break;                case END_TAG:                     j=0;                     i++;                     nb_tag--;                     stack--;                break;                default:                     nb_tag++;                     stack--;           }      }      return mat; } void libererMat(int **mat) {      int i;      for (i=0; i<sizeMat; i++)           free(mat[i]);      free(mat); } void _main(void) {   ESI ap;   int **mat;      clrscr();      InitArgPtr(ap);      if (ArgCount()>0)      {            if (GetArgType(ap) == LIST_TAG)           {                int i,j;                printf("LIST_TAG");                mat=StackToMat(top_estack);                if (mat != NULL)                     printf("!= NULL");                else                     printf("== NULL");                                     for(i=0; i<sizeMat; i++)                          for (j=0; j<sizeMat; j++)                          printf("%d ",mat[i][j]);                                                          libererMat(mat);           }                ngetchx();      } }
Pensez vous que je me complique bcp trop la vie? lol

8

* Déjà, une grosse faute: ne pas vérifier le résultat de malloc.
* Comme la plupart des fonctions de stdio.h, printf n'est pas une fonction directement disponible dans le système. En passant à DrawStr (ou printf_xy, moins adapté ici), tu vas gagner de la place.
* Il est sensiblement plus efficace en taille et en vitesse d'allouer ta matrice en un seul bloc (mat=(int **)malloc(nb_line*nb_row*sizeof(int))). Ca utilise moins de blocs de mémoire. Dans ce cas-là, tu peux toujours accéder à la matrice comme à un tableau unidimensionnel, moyennant une petite fonction d'index facile à écrire. En cas d'accès séquentiels (comme lors du remplissage), utilise un pointeur postincrémenté (*ptr++ = GetIntArg(...)). Les recalculs d'index prennent du temps et de la place.
avatar
Membre de la TI-Chess Team.
Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP.
Co-admin de TI-Planet.

9

Lionel Debroux :
* Déjà, une grosse faute: ne pas vérifier le résultat de malloc.

Je m'exerce pour l'instant donc les verification de ce style ca sera pour plus tard wink
Lionel Debroux :
* Comme la plupart des fonctions de stdio.h, printf n'est pas une fonction directement disponible dans le système. En passant à DrawStr (ou printf_xy, moins adapté ici), tu vas gagner de la place.

Le printf me sert juste a vérifier les valeur, il va disparaître dans la suite, mais c'est tjrs bon a savoir tongue.
Lionel Debroux :
* Il est sensiblement plus efficace en taille et en vitesse d'allouer ta matrice en un seul bloc (mat=(int **)malloc(nb_line*nb_row*sizeof(int))). Ca utilise moins de blocs de mémoire. Dans ce cas-là, tu peux toujours accéder à la matrice comme à un tableau unidimensionnel, moyennant une petite fonction d'index facile à écrire.

j'ai hésité a le faire mais a parament pas assez longtemps. J'en prend note tongue
Lionel Debroux :
En cas d'accès séquentiels (comme lors du remplissage), utilise un pointeur postincrémenté (*ptr++ = GetIntArg(...)). Les recalculs d'index prennent du temps et de la place.

Si tu parle des index i et j que j'utilise pour la matrice alors j'ai compris et j'en prend note aussi, sinon ben j'ai peur de pas avoir compris.

En tout cas merci pour tout ces conseil smile

pour le premier switch j'ai trouver comment le remplacer par une ligne en placant le pointeur au bon endroit avant smile
size=remaining_element_count(ptr-1); //j'utilise une matrice carre donc la ca me suffit

et a la place du while + deuxieme switch j'utilise deux boucle for imbriqué et next_expression_index (ptr) mais maintenant j'ai un probleme avec les signes, quand je met un nb négatif dans la matrice ca passe plus :/

n'y a t-il pas moyen d'eviter de tester POSINT_TAG et NEGINT_TAG mais de convertir directement en entier signé ?

Merci encore

10

Au passage, j'ai oublié: utilise short (16 bits) à la place d'int (16 bits sur cette plate-forme à moins d'utiliser un switch bizarre qui passe int à 32 bits comme sur les PC, mais qui va donner des résulats faux sur plusieurs fonctions) qui est moins portable.

> n'y a t-il pas moyen d'eviter de tester POSINT_TAG et NEGINT_TAG mais de convertir directement en entier signé ?
Peut-être, ça n'irait que pour des shorts (estack_to_short, estack_to_ushort), mais je ne suis pas sûr que ces fonctions existent sous tous AMS. A éviter, à moins que ton programme nécessite de toute façon AMS >= 2.04 (ce qui est très rare).
En tout cas, la définition de GetIntArg ne semble pas le permettre.
avatar
Membre de la TI-Chess Team.
Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP.
Co-admin de TI-Planet.

11

Ca avance smile

Bon j'avais pas trop compris comment utiliser estack_to_short (qui nécessite l'AMS 1.01 ou plus donc c'est parfait ) mais maintenant ca va mieux ^^.
Et hop plus de switch grin
(usage() et message() sont deux fonctions qui quitte après avoir affiché un messange dans le status)

ca donne ca : static short sizeMat; short *StackToMat(const ESI stack)      {           ESI ptr=stack,tmp;           short size,i,j;           short *mat;                        //si on pointe pas sur le début d'une liste on retourne null           if (!is_square_matrix(stack))                usage();           ptr--;                   //calcul des dimensions de la matrice carre           size=remaining_element_count(ptr-1);           sizeMat=size;                      //allocation de la matrice           mat=malloc(size*size*sizeof(int*));           if (mat==NULL)                message("Erreur! Memoire insuffisante");                      //remplissage de la matrice                for(i=0; i<size; i++)           {                tmp=ptr-1;                for(j=0; j<size; j++)                {                     if(estack_to_short(tmp,&(mat[i*size+j]))!=1)                          usage();                     tmp=next_expression_index(tmp);                }                ptr=next_expression_index(ptr);           }           return mat;      }      short locate(short *mat, short i, short j)      {           return mat[i*sizeMat+j];      }

Une derniere question tongue
faut il vider l'estack avant de renvoyer le resultat ou ca se fait tout seul à la fin ?

Merci beaucoup pour vos conseils.
Bonne journée.


12

> mat=malloc(size*size*sizeof(int*));
mat = malloc(size*size*sizeof(short));

Et il est peut-être possible de rester en GetIntArg, moyennant quelques vérifications d'étendue...

> faut il vider l'estack avant de renvoyer le resultat ou ca se fait tout seul à la fin ?
En principe, c'est à toi de le faire. Il me semble que ça consiste à un delete_between(old_top [sauvegardé au début], new_top [l'adresse la plus basse de ton résultat]).
avatar
Membre de la TI-Chess Team.
Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP.
Co-admin de TI-Planet.

13

arf j'avais pas vu pour le short, merci smile

sinon j'ai modifié le prototype de la fonction qui devien donc plutot une procedure (je lui passe le pointeur non alloué en argument) comme ca je peux retourner un code d'erreur pour pouvoir liberer la memoire si besoin, parce qu'avant, usage() et message() quittaient sans liberer et je ne savais pas ce qui avait été alloué dans le programme principal donc pas très pratique.

pour le vidage de l'estack je verrai ca une autre fois, j'ai plus trop le temps la , vaut mieux que je me mette a vraiment réviser la crypto, le DS approche :/, mais maintenant je sais qu'il faut le vider grin

Merci encore pour tes conseilS.
Bonne soirée

14

A ton service. Pour une fois, a) je sais à peu près répondre et b) personne de plus disponible ou compétent que moi ne l'a déjà fait...
avatar
Membre de la TI-Chess Team.
Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP.
Co-admin de TI-Planet.

15

Tu vide d'abord l'estack, ensuite tu déposes le résultat avant de sortir.
De cette manière seul ce que tu as déposé en dernier reste sur l'estack.
Tout ce que tu a mis avant est effacé.

La méthode ci-dessus ne nécessite pas de déplacement du contenu de l'estack mais seulement une mis à jour de top_estack : c'est la plus efficace.

Les exemple de TIGGC montre comment vider l'ESTACK.
Il s'agit tout bonnement de remonter à travers l'ESTACK avec 'next_expression_index' pour trouver le END_TAG indiquant le début de l'ESTACK ( il ne faut jamais l'effacer ). Il ne reste plus qu'à lui rajouter 1 pour redéfinir la valeur de top_estack.


Dans le cas ou tu serais obliger d'utiliser la seconcode méthode , il te faudra utilser 'delete_between'.

16

Le delete between est beaucoup plus simple. Voir: http://www.tiwiki.org/Delete_between et aussi http://www.tiwiki.org/Estack.

Voir en général aussi http://www.tiwiki.org grin

17

y'a des [tiwiki]liens[/tiwiki] fait exprès wink

18

fpgforce :
Le delete between est beaucoup plus simple. Voir: http://www.tiwiki.org/Delete_between et aussi http://www.tiwiki.org/Estack.

Voir en général aussi http://www.tiwiki.org grin


comme je disais, c'est moins efficace, même si c'est plus simple d'utilisation.
Dans la mésur où tu es obligé de nettoyer l'estack, autant le faire avant de déposer
le résultat. Tu vas appeller un ROM_CALL de plus histoire d'alourdir unitilement ton code.
Tu perdras en taille et en vitesse d'exécution.
Autant bien faire une bonne fois pour toute.

19

> Tu vas appeller un ROM_CALL de plus histoire d'alourdir inutilement ton code.
Ca dépend de la méthode de ROM_CALLs qu'il utilise.
delete_between est essentiellement un memmove (regarde le code). Pour un déplacement, difficile de faire plus efficace et sûr...
avatar
Membre de la TI-Chess Team.
Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP.
Co-admin de TI-Planet.

20

Oui mais selon le cas , y en a pas besoin.
puisqu'il suffit de faire seulement top_estack = (ESI)debut_code_dans_la_pile au lieu d'un delete_betwween surtout que l'on connait déjà la valeur de (ESI)debut_code_dans_la_pile.

difficile de faire plus compliqué.

21

Il s'agit tout bonnement de remonter à travers l'ESTACK avec 'next_expression_index' pour trouver le END_TAG indiquant le début de l'ESTACK ( il ne faut jamais l'effacer ). Il ne reste plus qu'à lui rajouter 1 pour redéfinir la valeur de top_estack.

Attend tu vois ta methode... Tu vas utiliser un "next_expression_index" (un ROM_CALL) en boucle triso
Moi je propose d'appeler un seul ROM_CALL un seule fois.
Dans la mésur où tu es obligé de nettoyer l'estack, autant le faire avant de déposer le résultat.
Je ne vois pas où est le problème trifus Ma technique reste la plus simple et la plus rapide ici. (et si tu definit OPTIMIZE_ROMCALL tu dois gagner encore plus en taille)

Et ya encore une autre méthode encore plus courte qui est sur la page de "delete_between" de TiWiki (voir lien sur mon précédent post).

22

je ne veux pas briser ton enthousiasme mais comment fait tu pour connaître la valeur de old_top_estack ? c'est bien beau de dire 'top_estack = old_top_estack' mais ce n'est pas une solution miracle delete_between , le tout est de savoir ce que vaut ce old_top_estack.

ta solution plus rapide c'est exactement ce que j'ai préconisé au post précédent, c'est dire redéfinir top_estack. Et en plus moi je dit comment obtenir la valeur de old_top_estack.
D'après toi comment on s'y prend pour effacer le code d'appel d'un prog C dans l'ESTACK ?


- supposons que tu passes plusieurs arguments à un prog C, dans le cas d'espèce, je pense que celui qui a créer ce topic fait quelque chose comme une librairie.
S'il n'y aucune erreur dans le passage des arguments il se retrouve avec une valeur de son pointeur courant égale à old_top_estack+1 qui pointe sur END_TAG de début d'appel de son prog C.
Mais en cas d'erreur d'argument faut obligatoirement remonté l'estack pour la nettoyer correctement.
__________________________________________________________________

A part ça, il n'est pas mal ton site, c'est en quelque sorte le manuel de TIGCC en français avec des truc en plus. Dommage qu'il n'est pas été mis en ligne 9 mois plus tôt lorsque j'apprenais le C sur TIGCC

23

je ne veux pas briser ton enthousiasme mais comment fait tu pour connaître la valeur de old_top_estack ? c'est bien beau de dire 'top_estack = old_top_estack' mais ce n'est pas une solution miracle delete_between , le tout est de savoir ce que vaut ce old_top_estack.
Mais on s'en fout completement de savoir ce que ça vaut. Regarde si tu procède comme ça:
Début du programme:

old_estack = top_estack ; [...]

Fin du programme :
delete_between (old_estack, top_estack) ;
push_expression (ton_resultat_final) ;
Et ça marche très bien!
Ensuite ta technique qui s'amuse a descendre dans l'estack à la recherche de l'ENDSTACK_TAG (parce que ce n'est pas un banal END_TAG comme tu met dans ton post) est débile, il suffit de faire à ce moment là:
top_estack = bottom_estack + 1 ;

A part ça, il n'est pas mal ton site, c'est en quelque sorte le manuel de TIGCC en français avec des truc en plus. Dommage qu'il n'est pas été mis en ligne 9 mois plus tôt lorsque j'apprenais le C sur TIGCC
Ce n'est pas mon site, c'est celui de Spectras, en effet il est bien et toute personne qui pense pouvoir aider est encouragée à participer. smile

24

> et si tu definit OPTIMIZE_ROMCALL tu dois gagner encore plus en taille
OPTIMIZE_ROM_CALLS n'est pas ce qui se fait de mieux en taille, c'est USE_FLINE_ROM_CALLS. En revanche, C'est plus lent.
avatar
Membre de la TI-Chess Team.
Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP.
Co-admin de TI-Planet.

25


old_estack = top_estack ;
[...]


là tu viens de m'apprendre quelque chose de nouveau. j'avais déjà posé la question sur le forum
à savoir comment savoir la valeur de top_estack avant l'appel d'un prog C, parceque figure toi qu'une fois que le TIOS passe la main au Prog appelé, ces arguments ont tous déjà été recopiés sur le sommet de l'estack et comme top_estack reflète toujours l'état actuel de l'estack, je te laisse imaginé la suite.

Désolé mais tu te trompes. je te sens un peu agressif sur ce coup, je pensais que l'on discutait calmement ici. Il y a bien un fossé entre ces 2 expressions linguistiques qui en dit long
je ne veux pas briser ton enthousiasme ...

Ensuite ta technique qui s'amuse a descendre dans l'estack à la recherche de l'ENDSTACK_TAG ... est débile, il suffit de faire à ce moment là:


Et je passe sur les déclaration du style

Mais on s'en fout completement de savoir ce que ça vaut..


On ne fait que parler de calc et prog, je ne pense pas avoir lancé d'attaque personnel.


Lorsqu'on utilise une librairie C, dans un prog basic en l'ocurrence, celui-ci laisse aussi dans l'estack des données. Et comme bottom_estack représente une position absolu indiquant le début de l'estack, par ta méthode tu vides systématiquement tout ce que le prog basic ( ou un autre prog C ou ASM ) aurait pu laisser sur l'estack.
top_estack = bottom_estack + 1 ;

tu risques d'obtenir des résultats inattendus voir des bugs. je me trompe peut-être car je n'ai pas testé le fait que bottom_estack refletait une valeur absolu. Mais je vais essayer ta méthode
et je te ferai part de mes test.


Je pense qu'il n'y a pas lieu de de s'emporter un instant dans ce débat. tu fait part de tes connaissances et moi des mienne, alors sachons resté amicale même si l'on ne se connait pas encore.

26

Et comme bottom_estack représente une position absolu indiquant le début de l'estack, par ta méthode tu vides systématiquement tout ce que le prog basic ( ou un autre prog C ou ASM ) aurait pu laisser sur l'estack.
Ben c'est bien ce qu'on veut faire il me semble, rétablir l'etat initial de l'estack, avant l'appel au programme...
top_estack = bottom_estack + 1 ;



tu risques d'obtenir des résultats inattendus voir des bugs. je me trompe peut-être car je n'ai pas testé le fait que bottom_estack refletait une valeur absolu. Mais je vais essayer ta méthode
et je te ferai part de mes test.
Euh ben ça n'est pas ma technique, c'est toi qui l'a proposée et je te démontre qu'elle n'est pas adaptée. Bien entendu elle supprime tout l'estack! Par contre je suis intérréssé par tes tests smile
Je pense faire bientot un utilitaire pour analyser l'estack.
Je pense qu'il n'y a pas lieu de de s'emporter un instant dans ce débat. tu fait part de tes connaissances et moi des mienne, alors sachons resté amicale même si l'on ne se connait pas encore.
Je te signale que c'est toi qui a commencé a me parler sur un ton douteux triroll De plus tu as l'air de ne pas vraiment connaitre ce dont tu parle celà dit j'ai rien cnotre toi.

27

28

j'ai dit 'debut_code_dans_la_pile' donc je parle celui du prog C utilisé comme utilitaire.
faut croire que je suis allé de travers en disant ceci

le END_TAG indiquant le début de l'ESTACK


Comme il a eu un peu de confusion de ta part sur mes propos, je vais reprendre par un exemple plus claire tiré de la doc de top_estack pour clore le débat .

voici un extrait de top_estack montrant comment est représenté l'appel d'une fonction dans l'estack.

Algebraic form: my_func (a, b, c)
RPN form: END_TAG c b a my_func USERFUNC_TAG
Sequence of bytes: [E5] [0D] [0C] [0B] [00 6D 79 5F 66 75 6E 63 00] [DA]


le [E5] est le END_TAG délimitant la fin d'un appel à une fonction/programme .
C'est ce END_TAG que je recherche lorsque le TIOS passe la main à mon programme.
Je pense que tu seras d'avis qu'il n'y a aucun de savoir comment trouver cela sans remonter l'estack, surtout s'il s'agit d'un prog C/ASM appelé dans un prog TI-Basic ou comme argument d'une autre fonction.

Cette technique est la seule adapté pour nettoyé correctement les arguments du code d'un prog C/ASM appelé.
Comme tu peux le constater cette méthode à une utilisation spécifique de même que les autres :

- Delete_between ne sert qu'à faire des suppression de milieu d'estack.

- Quand on veut supprimer des arguments en début d'estack, il n'y qu'à sauvegarder et restaurer la valeur de top_estack avant d'envoyer sur la pile ces dits arguments sur l'estack.

De plus je te signale que cette méthode n'est pas de moi. Elle fait parti des exemples de code distribué avec TIGCC.

Bon je pense qu'on a tout dit là et que j'ai été un peu plus clair.

Je vois que tu ne peux pas t'empêcher de continuer les petites vannes.
Vu ma méprise, tu peux t'autoriser tous les écarts.
Je te laisse continuer sur ce terrain car ce n'est pas mon objectif en venant poster ici.

29

-> Martial Demolin

Merci de jouer le modérateur, t'inqiète je ne vais pas m'emporter.
tu sais ça me rappel, le jour ou on a fait connaissance dans un topic Ti-Basic..

30