Developpement Amateur de SpixSh@dow |
|
| [Cours 06] Header, Macro et Librairie | |
| | Auteur | Message |
---|
Sekoda Admin
Nombre de messages : 1631 Date d'inscription : 04/01/2007
| Sujet: [Cours 06] Header, Macro et Librairie Dim 18 Mar - 20:50 | |
| Bonjour a tous et bienvenue au 6e cours de C . Aujourd'hui nous allons aborder les fichiers headers qui portent une extension en *.h, les differents types de macros et la creation de librairie . Fichier Header - Code:
-
/* ** my.h for my in /Cours_06/ ** ** by Sekoda MasGaNo ** ** Started on Fri Oct 13 14:10:51 2006 ** Last update Wed Mar 14 21:47:20 2007 */
#ifndef __MY_H__ #define __MY_H__
int my_getnbr(char *str); int my_strlen(char *str); int my_strcmp(char *s1, char *s2); int xtime(); int *xmalloc_int(int size); char *my_strcpy(char *dest, char *src); [...] char *xmalloc_char(int size); char **xmalloc_tab(int size); void my_putchar(char c); void my_putstr(char *str); void my_put_nbr(int nb); float my_getnbrf(char *str);
#endif /* __MY_H__ */
Macro - Code:
-
/* ** cours_06.c for Cours_06 in /Cours_06/ ** ** by Sekoda MasGaNo ** ** Started on Sun Feb 25 18:14:01 2007 ** Last update Wed Mar 14 23:26:28 2007 */
#define TEMP ((x * x) + (y * y) + (z * z)) #define ADD(a, b) (a + b)
int main() { int x; int y; int z; int result;
result = TEMP; result += ADD(x, y); }
Dernière édition par le Dim 18 Mar - 20:52, édité 1 fois | |
| | | Sekoda Admin
Nombre de messages : 1631 Date d'inscription : 04/01/2007
| Sujet: Re: [Cours 06] Header, Macro et Librairie Dim 18 Mar - 20:51 | |
| Fichier Header Presentation Attends ! Je croyais que les headers representaient l'en-tete des fichiers Bien, vous avez tout compris En effet, les header, comme leur nom l'indique represente l'en-tete d'un fichier que vous creez. Ou plutot ce sont les informations qui se situe a cet endroit. Les fichiers header, sont donc des fichiers que vous declarez au tout debut du fichier code et qui contiennent des informations relatifs aux autres fichiers . Durant ce cours, je vais vous imposer des nouvelles regles de normes ! J'entends deja les protestations . Cependant, je peux vous assurer que cela va grandement faciliter votre organisation et donc par la meme occasion, votre travail Commencons : Je ne veux qu'un type de fonction par fichier. Par exemple, un fichier qui gere les evenements lies a la touche 'A', ou un fichier qui s'occupera de faire avancer un missile, etc... Ainsi, si jamais vous vous rendez compte que le missile en question n'avance pas comme il faut, au lieu de chercher dans les milliers de code de votre unique fichier, il vous suffira tout simplement de prendre le fichier "missile.c" et de l'editer Plus rapide et plus efficace ^^. Particulierement si vous avez besoin de modifier des parametres sur plusieurs fonctions, vous pourrez alors ouvrir en cascade vos differents fichiers de fonction et modifier directement dessus, au lieu de passer votre temps a faire defiler l'ecran | |
| | | Sekoda Admin
Nombre de messages : 1631 Date d'inscription : 04/01/2007
| Sujet: Re: [Cours 06] Header, Macro et Librairie Dim 18 Mar - 20:51 | |
| UtilisationMaintenant que vous avez votre programme decoupe en plein de petits fichiers de fonction, ils vous faut lancer la compilation. Mais la que se passe-t-il ??? Un warning ! voir une erreur de compilation dans certains cas ! Quelque chose dans ce genre : - Code:
-
warning: implicit declaration of function `my_function' Si vous vous rappelez bien, le compilateur commence son travail par la fonction "main". Il enregistre dans une sorte de registre, toutes les fonctions qu'il rencontre lors de la lecture du fichier. Cependant, sachant que vous avez decoupe vos differentes fonctions dans d'autres fichiers, le compilateur a donc beaucoup plus de chance de ne rencontrer qu'une seule fonction : "main". Ainsi, quand vous ferez appel a une fonction, le compilateur ne saura pas de qui vous voudriez parler et donc generera une erreur ! Par contre, en mettant les fichiers header contenant toutes les informations de vos fonctions en debut de code, le compilateur recupere ce fichier et s'en sert comme registre. Il connaitra alors toutes les fonctions que vous appeliez et avancera dans la joie et la bonne humeur Pour la creation : -On commences par l'header habituel - Code:
-
/* ** my.h for my in /Cours_06/ ** ** by Sekoda MasGaNo ** ** Started on Fri Oct 13 14:10:51 2006 ** Last update Wed Mar 14 21:47:20 2007 */ Jusqu'a la, rien de nouveau. Si vous hesitez encore dessus, vous connaissez la direction -Ensuite nous avons, ce qu'on appelle, la "Protection de l'Header" - Code:
-
#ifndef __MY_H__ #define __MY_H__
[...]
#endif Je vais vous expliquer pas a pas - Code:
-
#ifndef On pourrait traduire cette syntaxe par "If not define". En effet, c'est une condition qui permet de savoir si le fichier header a deja ete utilise. Sachant que votre fichier header sera dans chaque code source, le compilateur va avoir un grand nombre de copie de votre header. Il risque de s'y perdre avec toute cette paperasse . Ainsi, on met cette commande pour dire : "Est-ce que __MY_H__ est deja defini ?" Si oui, le compilateur passe dessus, autrement : - Code:
-
#define __MY_H__ "Je definie __MY_H__". S'ensuit les informations concernant les fonctions, mais j'y reviens juste apres . Et on termine par : - Code:
-
#endif /* __MY_H__ */ Fin de la condition -Enfin : les fonctions : - Code:
-
typedef struct s_val { int i; int j; } t_val;
#define TEMP ((x * x) + (y * y) + (z * z))
/* key_a.c */ void key_a(t_prog *prog);
/* key_b.c */ void key_b(t_prog *prog);
/* missile.c */ void missile(t_mis *missile); Afin de mieux se reperer, je vous demanderai de presenter les headers de cette facon : -les declarations de vos structures. En effet, si vous ne les mettez pas ici, les typedef ne seront pas reconnu lors des definitions des fonctions dans le fichier header . -les declarations des MACROS. Je vous expliquerai ce que c'est juste apres . -la provenance de la fonction entre commentaire. Cela permet de regarder le fichier header pour savoir ou est la fonction a modifier -la declaration de votre fonction et c'est tout . Et oui, vous ne revez pas, c'est bien le prototype de la fonction suivi d'un ';'. Il n'y a rien de plus simple . Si jamais vous modifier le prototype de la fonction, pensez a apporter les modifications necessaires dans le fichier erreur. Autrement, le compilateur va vous afficher une erreur de multi-declaration. Vous devriez avoir une fichier dans ce genre, la fin de votre programme : - Code:
-
/* ** mysh.h for mysh in /mysh/ ** ** Made by Sekoda MasGaNo ** Login Sekoda ** ** Started on Wed Feb 14 20:46:31 2007 ** Last update Fri Mar 16 06:53:56 2007 */
#ifndef __MYSH_H__ #define __MYSH_H__
typedef struct s_path { char *path; int j; int nb; char *temp; } t_path;
typedef struct s_mysh { int i; int nb; int coma; int ok; int pscreen; int pkey; } t_mysh;
/* args.c */ void cleanarg(char ***arg); void parseread(char *buf, char ***arg, int nb); int parsepatharg(char *buf, char **tab); void read_arg(char *buf, char ***arg, char **tab); int cleanread(char *buf);
/* argsslash.c */ void argsslash(char *buf, char **tab);
/* chdir.c */ void parsechdir(char **arg); void new_pwd(t_list **env, char *npwd); void savedir(char **save, int first, char **buf); int parsecdmod(char **arg, char *save, int i, int j); void my_cd(char **arg, t_list **env);
/* cleanarg.c */ void freetab(char **tab); char **cpy_res_to_arg(char **res); void check_arg_direc(char **arg); void cleanpipebuf(char *buf);
/* cleanbuf.c */ void cleandirecdoubler(char *buf); void cleandirecsimpler(char *buf); void cleandirecdoublel(char *buf); void cleandirecsimplel(char *buf); void cleancoma(char *buf);
/* cleannbrredirec. */ void cleannbrredirec(char **arg); void cleannbrredirec2(char **arg);
/* cleanparent.c */ void cleanparent(char *buf); void cleanparent2(char *buf);
/* cleanposdirect.c */ void cleanposintermed(int k, char **res, char **arg); char **cleanposstart(char **arg, char **res, int k); char **cleanposdirect(char **arg);
/* listedoublel.c */ void my_put_to_list(t_list **begin, char *str);
/* my_env.c */ char *new_varenv(char **arg); void my_modifenv(t_list **env, char **arg); void my_setenv(t_list **env, char **arg); void my_unsetenv(t_list **env, char **arg);
/* my_fdstr.c */ void my_fdstr(char *str);
/* my_revarg.c */ char **my_revarg(char **arg); void rev_arg(char **arg, char **buf, int i, int *k);
/* my_unsetenv.c */ void unsetall(t_list **env); int my_star(char **arg); void forremovenv(t_list **env, char **arg, t_list **temp, int i); void removenv(t_list **env, char **arg); void my_unsetenv(t_list **env, char **arg);
/* mysh.c */ void beginmysh(char *buf, int *end, char **tab, int nb, t_list **env, char **arg); void func(char *buf, int *end, char **tab, int nb, t_list **env, char **arg, int sortie); t_list *my_envlist(char **env); void preparmysh(t_list **env, int *end);
/* path.c */ int nbr_path(char *path); void parsepath(char *path, char ***tab, int nb); void tabpath(t_path *xp, char ***tab); int my_path(char ***tab, t_list *env);
/* parsecoma.c */ int parsecoma(char *buf); int countcoma(char *buf); int flag_no_zero(char *sbuf, char *buf);
/* parsedirectdoublel.c */ t_list *arguparsedirectl(char **arg, int *i); void error_pipe(); void free_liste(t_list **begin); void parsedirectdoublel(char **arg);
/* parsepatharg.c */ int nbrpath(char *buf); void tiltslash(char *buf, char **tab); void slash(char *buf, char **tab); void pointslash(char *buf, char **tab);
/* parsepipe.c */ void parsedirectdoubler(char **arg); void parsedirectsimpler(char **arg); int cleanbufread(char *buf, char *arg); void parsedirectsimplel(char **arg);
/* pipe.c */ void cleanpipe(char *buf); void parsepipe(char **arg);
/* prog.c */ void mysh(char *buf, int *end, t_list **env);
/* sysfunc.c */ void aff_prompt(); char **my_list_to_tab(t_list **env); void my_fork(char **arg, char **tab, int nb, t_list **env);
/* sysfuncmysh.c */ int pipeleft(char **arg); char **cpyarg(char **arg);
/* my_strpcpy.c */ void my_strpcpy(char *dest, char *src);
/* xdup.c */ int xdup(int oldd); void xdup2(int fd, int num);
/* xlogin.c */ char *xgetlogin(); char *xhomelong(); char *xhome();
#endif /* __MYSH_H__ */ | |
| | | Sekoda Admin
Nombre de messages : 1631 Date d'inscription : 04/01/2007
| Sujet: Re: [Cours 06] Header, Macro et Librairie Dim 18 Mar - 20:51 | |
| Les MACROSVoici un autre élément que vous devez absolument connaître (enfin, c'est relatif ) car elle vous permet de vous simplifier la vie , ou du moins votre developpement En effet, il n'est pas rare que vous devez réutiliser les mêmes syntaxes dans votre code. - Code:
-
/* Les evenements lies a l'interaction avec les touches par exemple.
int move(int x, int y) { x += Pad.Held.Right - Pad.Held.Left; y += Pad.Held.Down - Pad.Held.Up; return (0); } Ainsi, au lieu de réécrire un nombre incalculable de fois les mêmes éléments, on va créer une MACRO qui permettra de remplacer toutes ces opérations en un seul mot-clé. Soit un gain de temps énorme | |
| | | Sekoda Admin
Nombre de messages : 1631 Date d'inscription : 04/01/2007
| Sujet: Re: [Cours 06] Header, Macro et Librairie Dim 18 Mar - 20:52 | |
| MACRO de remplacement.La plus grande utilité des MACRO, sont celles de remplacement. En effet, lorsque vous compilerez votre code, il transformera ce code : - Code:
-
int move(int x, int y) { x += RIGHT - LEFT; y += DOWN - UP; return (0); } en - Code:
-
int move(int x, int y) { x += Pad.Held.Right - Pad.Held.Left; y += Pad.Held.Down - Pad.Held.Up; return (0); } Sauf que vous, vous n'aurez pas eu à taper tout ça . C'est le compilateur qui se charge de remplacer vos MACRO par leur valeur Pour les utiliser, il suffit alors de les déclarer dans l'en-tête de votre fichier, ou dans votre fichier header directement de cette façon : - Code:
-
#define TEST (((a + b) / c) % 20) Au début, vous avez le - Code:
-
#define qui vous permet de déclarer la création d'une MACRO, puis, vous avez le nom de votre MACRO toujours en MAJUSCULE, et enfin, vous avec entre '( )' la valeur de la MACRO concerné. Sympa et éfficace, non ? Attention : les MACRO sont déclarés de manière globale. Donc choisissez bien vos nom de MACRO pour éviter de prendre le risque de les redéclarer (d'où une déclaration dans le fichier header et de manière trier ) et les réutiliseez à mauvais escient Ainsi, le code complet doit plus ou moins ressembler a ceci : - Code:
-
#define RIGHT (Pad.Held.Right) #define LEFT (Pad.Held.Left); #define UP (Pad.Held.Up); #define DOWN (Pad.Held.Down);
int move(int x, int y) { x += RIGHT - LEFT; y += DOWN - UP; return (0); } | |
| | | Sekoda Admin
Nombre de messages : 1631 Date d'inscription : 04/01/2007
| Sujet: Re: [Cours 06] Header, Macro et Librairie Dim 18 Mar - 20:53 | |
| MACRO de fonctionMoins utilise, mais pas moins efficace, les MACRO de fonction ont le meme role que les MACRO de remplacement, sauf qu'ils prennent en plus un parametre. Imaginons que je joue a un jeu ou je dois placer des pions a certaines cases du plateau, sachant qu'il y a des obstacles et que quand j'appuie sur une fleche, cela affecte TOUS mes pions ! Bon, vous aurez compris, qu'il aurait ete plus simple de faire ca en Liste Chainee, en utilisant une boucle qui tant qu'il me reste des pions a deplacer, je dois rappeler la meme fonction. Je le savais, vous etes trop doues pour moi . Mais pour vous faire comprendre ce l'utilite de ces MACRO, on va oublier quelques instants l'existence des Listes Chainees (les pauvres... ) La premiere logique a faire serait : - Code:
-
#define RIGHT (Pad.Held.Right) #define LEFT (Pad.Held.Left); #define UP (Pad.Held.Up); #define DOWN (Pad.Held.Down);
int move() { x += RIGHT - LEFT; y += DOWN - UP; x1 += RIGHT - LEFT; y1 += DOWN - UP; x2 += RIGHT - LEFT; y2 += DOWN - UP; x3 += RIGHT - LEFT; y3 += DOWN - UP; x4 += RIGHT - LEFT; y4 += DOWN - UP; x5 += RIGHT - LEFT; y5 += DOWN - UP; x6 += RIGHT - LEFT; y6 += DOWN - UP; return (0); } Sauf que taper tout ca, ca commence a faire long (meme si j'ai fait un copier-coller ) Le plus simple, est donc de proceder de cette facon : - Code:
-
#define RIGHT (Pad.Held.Right) #define LEFT (Pad.Held.Left); #define UP (Pad.Held.Up); #define DOWN (Pad.Held.Down); #define MOVEX(x) (x = RIGHT - LEFT) #define MOVEY(y) (y = DOWN - UP)
int move() { MOVEX(x); MOVEY(y); MOVEX(x1); MOVEY(y1); MOVEX(x2); MOVEY(y2); MOVEX(x3); MOVEY(y3); MOVEX(x4); MOVEY(y4); MOVEX(x5); MOVEY(y5); MOVEX(x6); MOVEY(y6); return (0); } C'est deja plus simple, non ? Bien entendu, on peut changer la valeur de ces MACRO pour faire d'autre manipulation qu'une simple assignation . C-Comment c'est possible ! Tu utilises une MACRO dans une autre MACRO Et oui ! C'est tout a fait possible . Le compilateur se chargera de remplacer la valeur des MACRO de fonction par la valeur de la MACRO appele (j'espere que c'est assez clair ce que je dis ) Pour cela, il faut avoir declarer la fonction concerne avant Mais attention ! Pas de : - Code:
-
#define ADD(a) (ADD(a) + 5) Je n'ose meme pas vous dire ce qu'il se passera C'est comme pour les structures Vous pouvez appeler une structure precedement declaree dans une nouvelle structure | |
| | | Sekoda Admin
Nombre de messages : 1631 Date d'inscription : 04/01/2007
| Sujet: Re: [Cours 06] Header, Macro et Librairie Dim 18 Mar - 20:54 | |
| LibraireVoici une notion, qui peut vous etre tres utile, ou juste repondre a une question que vous vous posez surement (ou rien du tout, mais ce serait bien dommage ). Les librairies ! Mais qu'est-ce qu'une librairie C'est exactement ce genre de question que je voulais parler C'est une exelente question, mais d'un cote, vous savez deja ce que c'est si vous avez deja developpe avec la PAlib par exemple . Generalement, ils portent l'extension *.a (pour Unix surtout) et *.lib (pour windows), et sont present par exemple dans votre dossier : "./Palib/lib" C'est un fichier, qui possede le code source de toutes les fonctions que vous avez codez (enfin, ici c'est la team PAlib ). Si par exemple vous vous faites des fonctions generiques dans un fichier source, puis vous comptez reutiliser ces fonctions generiques dans vos programmes, au lieu de copier-coller vos fichier sources et les recompiler a chaques fois que vous faites un test de votre programme, je vous propose alors, de les compiler qu'une seule fois, et de ne copier qu'un seul fichier (ou rien du tout si vous mettez votre librairie dans le dossier de librairie par defaut de votre compilateur. Ici : ./Palib/lib/). Vous n'aurez juste que le header contenant toutes les fonctions de votre librairie a inclure dans vos fichiers sources, puis vous pourrez coder librement, en n'ayant aucune inquietudes a avoir lors de vos compilations Cependant, cela demande une certaine rigueur, a savoir : il faut absolument que vos fonctions lib, fonctionnent parfaitement ! En effet, imaginez-vous que PA_Init(), soit buguee Sachant que vous n'avez pas le code source, vous aurez l'air assez malin, en tentant de chercher le bug pendant des jours, des semaines ou des mois ! (si vous n'avez pas abandonne d'ici la, ou si PAlib n'ait pas encore sortie de nouvelle version ) Donc des fonctions fonctionnelles , et si possible, optimisees (tant qu'a faire ). Ainsi, les seuls bugs possible seront seulement dans le code de votre programme et non dans vos librairies . Donc une fois que vous avez tous vos fichiers sources qui sont prets a etre compiler, creer un nouveau projet (Un compilateur C est demande comme DevC++ ou Visul Studio), en choisissant comme type de projet : Dynamic-Link Library. Puis pensez à ajouter votre fichier Header contenant toutes les prototypes de votre future librairie. Compilez et zou voici votre librairie prête à être utilisée Il vous faudra alors mettre votre librairie dans le dossier de vos libs et et ne surtout pas oublier d'inclure votre fichier header à vos codes sources | |
| | | Sekoda Admin
Nombre de messages : 1631 Date d'inscription : 04/01/2007
| Sujet: Re: [Cours 06] Header, Macro et Librairie Lun 19 Mar - 4:05 | |
| ConclusionEt voilà, ce nouveau cours s'achève en vous laissant des moyens et une organisation efficaces pour réaliser vos programmes J'espère ne pas avoir été un peu trop rapide Avec tout cela, vous en savez pratiquement autant que moi il me semble . Bon, il reste les arbres binaires, les masques et decalages de bit et encore quelques autres notions, mais je ne pense pas qu'ils vous seront utiles. Cependant, si tel cas se présentait, je vous ferais alors un nouveau cours sur les notions manquantes à avoir. Mais pour l'instant il me semble que vous êtes prêts à developper ce que vous voulez A l'issue des exercices du cours (et oui, n'imaginez pas que vous alliez échapper à cela ), vous serez normalement fin prêt à coder sur la PAlib sans le moindre problème de lacune . Cependant, si vous avez un gros projet de developpement, je vous conseille de commencer avant à developper des minis-projets intermédiaire, non forcément sans rapport avec votre projet initial. Par exemple si vous voulez réaliser un RPG, vous pouvez par exemple commencez par coder un projet de dialogue, puis un projet d'interation avec les objets, éléments de décor, personnages, etc..., puis un projet de gestion de menu, un projet de combat, puis réunir toutes vos compétences en un seul projet principal que sera le votre. Comme ça vous récupererez de l'expérience efficacement. Bien entendu, il faudra repartir de zero à chaques fois, si vous voulez que cela devienne bien limpide. Sinon quand je dis un seul projet par theme, c'est plutôt plusieurs projets par thême, histoire que vous testiez plusieurs gameplay avant de selectionner celui que vous jugerez meilleur. Cela permettra d'éviter d'être bridé par un mode de jeu, vous empechant ainsi, d'être opérationnel sur tous les points. Sur ce, je vous souhaite bon courage pour la suite En cas de problème, vous savez où me trouver | |
| | | Contenu sponsorisé
| Sujet: Re: [Cours 06] Header, Macro et Librairie | |
| |
| | | | [Cours 06] Header, Macro et Librairie | |
|
Sujets similaires | |
|
| Permission de ce forum: | Vous ne pouvez pas répondre aux sujets dans ce forum
| |
| |
| |
|