Retourner string sans allocation dynamique

Retourner string sans allocation dynamique - C - Programmation

Marsh Posté le 06-05-2008 à 17:57:22    

Bonjour,
 
Dans le cadre d'un projet je suis contraint et forcé à utiliser C pour programmer un microcontrolleur. Je dis contraint et forcé car j'ai une peine d'enfer à me faire aux notions de pointeurs.
Le problème qui me préoccupe est le fait d'avoir une fonction qui me retourne un string (de taille fixe) en sachant que je n'ai pas le droit d'utiliser calloc/malloc et confraires car le microcontrolleur ne les fourni pas. À ce que j'ai compris en lisant à gauche et a droite, la seule manière de faire serait donc de déclarer le tableau de caractère en dehors de la fonction, et d'après lui passer un pointeur dessus afin qu'il le modifie. Jusqu'à la j'ai juste?
Bien que je trouve moyennement élégant d'avoir une fonction ne retournant rien mais modifiant ses arguments, j'ai essayé d'écrire quelque chose dans ce style là (tout est bien prototypé dans un .h, myFunc() est appelée dans mon main)
 

Code :
  1. static unsigned char * buffer[100];
  2. void myFunc()
  3. {
  4. // Operations sur buffer
  5. // Calculs et définition de unData
  6. char* value[10];
  7. getValue(value, unData);
  8. sprintf(buffer, "Value %s",*value);
  9. }
  10. void getValue(char *value, unsigned int data)
  11. {
  12.   // Operations sur data
  13.  
  14.   sprintf(value,"%d [Unit]",data);
  15. }


 
Mais ça ne marche absolument pas ... Est-ce que vous pouvez m'éclairer? Je sais que ça doit être qqch de super con mais je vois vraiment pas..

Message cité 1 fois
Message édité par esox_ch le 06-05-2008 à 18:00:22

---------------
Si la vérité est découverte par quelqu'un d'autre,elle perd toujours un peu d'attrait
Reply

Marsh Posté le 06-05-2008 à 17:57:22   

Reply

Marsh Posté le 06-05-2008 à 18:04:34    

esox_ch a écrit :


Mais ça ne marche absolument pas ... Est-ce que vous pouvez m'éclairer? Je sais que ça doit être qqch de super con mais je vois vraiment pas..


 
char* value[10] => un tableau de 10 char*
 
C'est pas char value[10] que tu veux (tableau de 10 char)?

Reply

Marsh Posté le 06-05-2008 à 19:17:23    

Salut,
 
merci là effectivement ça compile. Je verrai demain si ça marche sur le microcontrolleur (je l'ai pas sous la main là). En tous cas merci de ton aide.
Par contre, une question, en temps normal (c'est à dire avec un compilateur courrant) quelle serait la technique à utiliser pour faire ce que je voulais faire ? Passer par l'allocation dynamique?
Je demande parce que ça me parait super compliqué pour faire un truc aussi con que retourner un string .. :D

Reply

Marsh Posté le 06-05-2008 à 19:56:23    

Passer en argument est souvent le mieux en C, ça laisse le choix de l'allocation (dynamique ou non) à celui qui va utiliser la fonction. Par contre, il faut absolument passer le pointeur et la taille maximale du buffer, comme ça ta fonction sait la longueur maximale qu'elle peut écrire sans écrire n'importe ou dans la mémoire.


---------------
Me: Django Localization, Yogo Puzzle, Chrome Grapher, C++ Signals, Brainf*ck.
Reply

Marsh Posté le 06-05-2008 à 21:28:09    

esox_ch a écrit :

Salut,
 
merci là effectivement ça compile. Je verrai demain si ça marche sur le microcontrolleur (je l'ai pas sous la main là). En tous cas merci de ton aide.
Par contre, une question, en temps normal (c'est à dire avec un compilateur courrant) quelle serait la technique à utiliser pour faire ce que je voulais faire ? Passer par l'allocation dynamique?
Je demande parce que ça me parait super compliqué pour faire un truc aussi con que retourner un string .. :D


n'ayant du C qu'une expérience scolaire, je serai passé par une allocation dynamique, mais je n'ai pas beaucoup de pratique.
Disons que j'aurai plus tendance a faire ce code en C++ ...
 
Mais je pense que les deux méthodes se valent, selon l'ampleur du projet :
si j'utilises souvent un type de donnée, je crée la structure qui convient et toutes les fonctions d'accès (équivalent d'une classe C++)
si je n'ai besoin que d'une chaîne de caractères a un endroit, je pense faire comme toi ...
 
Mais je le repete, je n'ai aucune 'vraie' expérience en C ...

Reply

Marsh Posté le 06-05-2008 à 23:14:18    

esox_ch a écrit :

Salut,
 
merci là effectivement ça compile. Je verrai demain si ça marche sur le microcontrolleur (je l'ai pas sous la main là). En tous cas merci de ton aide.
Par contre, une question, en temps normal (c'est à dire avec un compilateur courrant) quelle serait la technique à utiliser pour faire ce que je voulais faire ? Passer par l'allocation dynamique?
Je demande parce que ça me parait super compliqué pour faire un truc aussi con que retourner un string .. :D


Pour ce bout de code:

Code :
  1. void myFunc()
  2. {
  3. // Operations sur buffer  
  4. // Calculs et définition de unData  
  5. char value[10];
  6. getValue(value, unData);
  7. sprintf(buffer, "Value %s",*value);
  8. }

Si tu appelles myFunc de maniere sporadique, ca sera tres bien (allocation et desallocation automatique)
Si tu appelles souvent myFunc, un static char value[10], peut être plus efficace, s'il n'y a pas necessité de nettoyer le contenu du buffer a chaque fois avant utilisation (pas besoin dans le cas ici, vu que ce qui va etre ecrit dans le buffer est terminé par un \0, qui sert d'indicateur de fin de chaine).
Les allocations dynamiques, ca sert quand tu vas vouloir que ce que tu as alloué serve encore une fois ta fonction executée (et soit donc recupérée par la fonction appellante, comme retour de la fonction, ou comme modification d'un parametre passé par pointeur).
A+,


Message édité par gilou le 06-05-2008 à 23:14:51

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 07-05-2008 à 10:23:43    

Soit tu déclares buffer en global comme tu l'as fait, soit tu le laisse dans la fonction mais en le déclarant "static". Ca revient strictement au même (sauf qu'en static dans la fonction c'est un poil plus propre puisqu'au moins il n'est pas visible en dehors de ta fonction).
 
Evidemment ça fait du code non réentrant, mais peut-être que tu t'en fout.

Reply

Marsh Posté le 07-05-2008 à 12:38:22    

Salut,
 
Je viens d'envoyer le code sur le microcontrolleur et tout fonctionne bien. Merci beaucoup
 
Cependant, désolé pour mon ignorance, mais pouvez vous m'expliquer quel serait l'intérêt de déclarer value comme static ? ça voudrait dire que la mémoire est allouée une fois pour toute et non pas à chaque appel?
 
Parallèlement, et pour éviter de vous déranger pour d'autres "détails" du même genre : Avez vous un tutorial C dans vos bookmark (J'entend quelque chose comme Thinking C++ et Thinking Java)
 
merci pour tout

Reply

Marsh Posté le 07-05-2008 à 13:59:25    

L'intéret de déclarer "static" le buffer est que celui-ci n'est pas local à la fonction et donc n'est pas détruit à la sortie de celle-ci.
C'est en quelque sorte une variable globale connue uniquement à l'intérieur de la fonction !
Méthode fortement déconseillée en cas de multi threading.

Reply

Marsh Posté le 07-05-2008 à 14:02:51    

esox_ch a écrit :

Salut,
 
Je viens d'envoyer le code sur le microcontrolleur et tout fonctionne bien. Merci beaucoup
 
Cependant, désolé pour mon ignorance, mais pouvez vous m'expliquer quel serait l'intérêt de déclarer value comme static ? ça voudrait dire que la mémoire est allouée une fois pour toute et non pas à chaque appel?
 
merci pour tout

Oui, et que ce qu'il y a a l'interieur du buffer ne disparait pas entre deux appels. Le compilateur alloue la place necessaire lors de la compilation (sans static, c'est alloué lors de l'execution).
A+,
 


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed