Linuxman - mai 1999


INDEX

Mois précédent

Mois suivant


1 5 1999
2 5 1999
3 5 1999
4 5 1999
5 5 1999
7 5 1999
8 5 1999
9 5 1999
10 5 1999
16 5 1999
17 5 1999
18 5 1999
20 5 1999
21 5 1999
22 5 1999
23 5 1999
24 5 1999
25 5 1999
30 5 1999
31 5 1999

 1 5 1999

Mots Clés : Expressions régulières (introduction).

Alors, c'est le premier mai, donc pas de folie, juste une légère (très légère comme je le sens venir) introduction sur les expressions régulières. Une expression régulière est, d'une certaine façon, une « méta chaîne de caractères », c'est-à-dire une chaîne de caractères qui permet de définir d'autres chaînes de caractères, enfin définir n'est pas tout à fait le mot, disons plutôt correspondre à certaines chaînes de caractères.  Je m'explique, une expression régulière permet de tester si oui ou non une certaine chaîne de caractères peut être décrite par un certain schéma. Elle est formée d'un groupement de motifs dans le but de rechercher ces motifs dans du texte.  Les expressions régulières sont utilisées dans tout programme ou logiciel où la recherche de chaînes de caractères spécifiques existe. Ces programmes sont très nombreux sous Unix et les plus connus sont sed, awk, grep et egrep, vi et j'en passe.

Les expressions régulières sont très puissantes, et peuvent permettre de chercher simplement un mot dans vi, comme tous les mots commençant par a ou b, avec ensuite un espace, puis un mot de 4 caractères avec au plus un chiffre dedans et un mot de plus de 6 lettres en fin de ligne.  

Alors comme c'est le premier mai, fête du travail, et que je vous avais prévenu que ce ne serait qu'une introduction, faudra attendre un peu pour vous la péter avec egrep :-)

haut de page

 2 5 1999

Mots Clés : Expression régulières (structure).

Voilà, c'est le deux mai, la fête du travail terminée, mais tout n'est pas perdu, c'est encore le week-end :-).

La structure globale d'une expression régulière est formée de une ou plusieurs branches séparées par des |, qui, comme vous vous en doutez, ont la signification de OU.  
Chaque branche est la concaténation de plusieurs motifs. Pour être en correspondance avec une branche, une chaîne de caractères doit être formée de chacun de ces motifs, dans le même ordre.
Chaque motif est constitué par une succession d'atomes (je ne sais pas du tout si les termes branches, motifs et atomes sont les bons, c'est au feeling, rien de sûr, alors ne me mailbombez pas si on vous prend pour un débile mental profond polio du cerveau à cause de moi). Chaque atome peut être suivi de *, +, ? ou un truc du genre {n},{n,},{,n} ou encore {n,m} ; leur utilité est de définir combien de fois on veut que l'atome apparaissent successivement dans la chaîne :  
* : zéro ou plusieurs fois.
+ : une ou plusieurs fois.
? : au plus une fois.
{n} : n fois.
{n,} : au moins n fois.
{,n} : au plus n fois.
{n,m} : entre n et m fois.

Pour finir sur la structure d'une expression régulière, vous aurez donc un truc dur genre : A*B{10}C{,3}|D?E?F{3,}|G*H{2,4} où A,B,C,D,E,F,G et H sont des atomes. Alors pour les atomes, on va pas se la jouer speed, on verra ça en temps voulu...

haut de page

 3 5 1999

Mots Clés : Cube.

Sorry bien trop naze aujourd'hui pour les atomes, ça attendra...

Alors quelques mots sur Cube, que je suis allé voir ya pas longtemps. Je ne sais pas trop si vous en avez entendu parler, ya pas eu une promo extra il me semble, je n'ai vu que quelques affiches... Les thèmes de l'histoire sont l'homme, l'espoir, le désespoir, la lutte, la résignation, l'orgueil (tous les films parlent d'orgueil, d'ailleurs, si vous regardez bien une fois sur deux quand un des personnages fait une erreur c'est par orgueil, ça en devient lassant à force), la peur, le sens de la vie...

L'histoire, en deux mots : 5 personnes se retrouvent enfermées dans un cube géant composé de petits cubes qui sont chacun une salle. Certaines salles sont piégées et les héros cherchent à sortir du cube.

On peut trouver de très nombreuses significations et thèmes au film, dont le très controversé sens de la vie dans la société moderne. Les personnages luttent pour sortir, ils s'entraident, se détestent, s'aiment, se trompent, se haissent mais, finalement, ils ne peuvent pas se passer les uns des autres, et leur but est d'aller vers la lumière. Ceci n'est rien d'autre, finalement, que la vie de tous les jours, nous ne savons pas trop pourquoi nous sommes là, nous ne savons pas trop où est la sortie s'il y en a une, comment y aller, et si finalement tout ceci rime à quelque chose.

Les problèmes sont pausés par le film assez habilement en fait. Bien sûr il n'y a pas vraiment de réponse, mais ces questions n'en ont pas. Les personnages jouent assez bien, je me rappelle plus de la musique... Les incohérences ne sont pas très nombreuses, on tient jusqu'au bout. Finalement je dirais que c'est un bon film, pas exeptionnel, mais bon, j'aime bien l'approche du problème, il a le mérite de poser les questions de façon claire sans avoir la prétention d'y répondre.

haut de page

 4 5 1999

Mots Clés : Expression régulière (atomes).

Bon, ben on va en finir avec les expressions régulières avec le point essentiel, c'est-à-dire ce que j'ai appelé les atomes et que je n'ai pas eu le courage de traiter hier... Alors pour illustrer tout cela je me baserai sur des exemple avec egrep (ou grep -E, qui est presque pareil).

  Un atome peut être simplement une lettre ou un mot, par exemple c ou bateau, grep -E a file vous sortira toutes les lignes de file avec un a dedans (il n'y a d'ailleurs pas besoin de -E dans ce cas la, grep tout seul suffit).

Dans les expressions régulières certains caractères ont une signification spéciale, ce sont:
^ : signifie début de ligne.
$ : fin de ligne.
. :  n'importe quel caractère.
Par exemple grep -E ^Maison.{2}bleue$ cherchera les lignes avec « Maison » au début, puis deux caractères puis « bleue » qui termine la ligne ; notez que vous pouvez utiliser les parenthèses pour rendre le tout plus clair (les caractères spéciaux perdent leur signification s'ils sont backslashés).
Les crochets [ ] permettent de spécifier un groupe de caractères qui convient. grep -E [abcd]$ cherche une ligne qui se termine par a, b, c ou d (attention ce qu'il y a à l'intérieur des crochet compte pour UN caractère, utilisez les fonctions de répétition (*,+,?,{n}...) pour en chercher plusieurs).
Vous pouvez spécifier un ensemble de caractères comme cela : [a-z] ou [A-Z0-9].
Il existe de plus des classes de caractères bien utiles :
[:alnum:] : caractère alphanumérique, équivaut à [A-Za-z0-9]
[:alpha:] : caractère alphabétique (pas un chiffre).  
[:blank:] : blanc ou tabulation.
[:cntrl:] : caractère de contrôle.
[:digit:] : chiffre.
[:graph:] : caractère imprimable et visible (par exemple a, et pas un espace qui n'est pas visible (enfin si, on voit qu'il y a un espace, mais on voit rien, enfin vous voyez ce que je veux dire :-)).
[:lower:] : minuscule.
[:print:] : caractère imprimable (pas un caractère de contrôle).
[:punct:] : ponctuation.
[:space:] : espace (un peu plus large que blank).
[:upper:] : majuscule.
[:xdigit:] : caractère hexadécimal.
Alors un petit exemple pour mettre les idées au clair, sinon je suis sûr que vous allez oublier des crochets : grep -E [[:upper:][:space:]] cherche une lettre majuscule ou un espace et grep -E [[:alpha:]] cherche un caractère de l'alphabet.

A l'intérieur des crochets, le caractère ^ signifie « tout sauf ça ». grep -E [^[:xdigit]] cherche tout caractère qui n'est pas hexadécimal.

Il existe encore quelques petits trucs :
\w : pareil que [[:alnum:]]
\W :  pareil que [^[:alnum:]]
\y, \B, \<, \> : qui correspondent respectivement à la chaîne vide en début ou en fin de mot, au milieu d'un mot, au début d'un mot et enfin, à la fin d'un mot.  

Bon et bien voilà qui est fait, maintenant vous pouvez frimer et chercher des mots zarbis dans vos fichiers...

haut de page

 5 5 1999

Mots Clés : info.

En fait, quand on y regarde bien, le tout n'est pas tellement de savoir tout plein de choses, enfin, si, un peu quand même, mais il se trouve qu'on oublie vite (enfin je ne sais pas pour vous mais moi j'oublie vite ; il suffit que je n'utilise pas une fonction ou programme pendant un mois ou deux et je ne sais déjà plus tout ce que j'avais ingurgité comme doc pour plus ou moins maîtriser la bête). Mais, oh joie ! Il existe la doc, et c'est la clé du succès : savoir où et comment trouver l'information.

Vous voilà donc en face de ce nouveau programme super cool (paraît-il), mais bon, au premier abord tout paraît un peu rude, surtout dans un xterm moche tout noir (utilisez donc des Eterm transparents pour la frime). Premier réflexe, man programme_cool, qui, la plupart du temps, vous donnera de quoi vous amusez pendant quelques temps. Si cela ne suffit ou n'existe pas, tentez toujours un info programme_cool. Vous pouvez ensuite vous rendre dans le répertoire /usr/doc/programme_cool-vx.y.z qui contient souvent un peu d'aide, des références de sites web sur le programme, ou même des manuels.  

Un bon réflexe aussi est de faire un petit locate programme_cool pour voir un peu ce qu'il y a de beau planqué dans votre système à propos de ce programme_cool. Un petit coup d'oeil chez les HOWTOs aussi (/usr/doc/HOWTO) peut être une idée pas extrêmement mauvaise. Avec un tranquille grep programme_cool *, on peut sans se fatiguer savoir si par hasard il n'y aurait pas un HOWTO qui cause de notre programme_cool.

Bon ben ensuite, en désespoir de cause, on peut toujours se taper une petite recherche sur le Web, ça ne peut pas faire de mal...

haut de page

 7 5 1999

Mots Clés : fork, fork.

Bon c'est vendredi, donc le week end, qui ne s'annonce pas joyeux avec le $*%*##|@ de rhume que j'ai chopé je ne sais pas où encore. J'étais d'ailleurs trop naze hier pour avoir la force d'écrire quoi que ce soit d'intelligent (taper au clavier, finalement, cela n'a rien de compliqué, mais taper des MOTS, ça, faut déjà être plus balèze...).

Enfin bon, c'est la vie, certains attrapent des rhumes, et d'autres pas... Je me plains pas, non non, enfin, un petit peu parce que devoir se trimbaler quarante paquets de mouchoirs en papier en permanence sur soi n'a rien d'excitant...

Enfin, tout ça mis à part il a fait un temps pourri aujourd'hui...

  Et bien, si vous avez déjà tapé quelques lignes de C dans votre vie, euh, c'est très bien. « Mais comment faire un daemon ? » Me demandez vous alors... C'est simple répondé-je promptement (je consens un léger manque de logique dans ce paragraphe, mais léger), il faut utiliser la fonction fork. À vrai dire fork n'est pas une fonction C standard telle que, euh, je sais pas moi, une fonction standard, tiens, atoi ou autre, fork est un « system call » (TA DAM !!), ou « appel système » pour les puristes. Voilà, c'est cool hein ?  

Mais que sont les system calls ? Et bien, sans trop entrer dans les détails (en ce moment je sens que je m'enfonce et c'est pas bon), sur votre beau linux qui tourne, les choses peuvent être divisées en deux, il y a d'un côte le noyau qui tourne, gère les interruptions, les périphériques, et contrôle tous les processus du système, c'est-à-dire exécute chacun d'eux à leur tour une petite fraction de temps (c'est beau le multitâche). Le noyau peut tout faire, et d'ailleurs, ça tombe bien parce qu'il fait tout, et si vous regardez tout ça d'une manière séquentielle, car, finalement, c'est comme cela que ça se passe (sur une machine mono processeur en tout cas), votre noyau n'est rien d'autre qu'un gros programme qui fait tout plein de choses une part une, mais comme il est plutôt speed, pour vous, petit utilisateur innocent, il vous semble que t! ! ! ! ! ! ! ! ! ! ! out est  fait en parallèle (ha ha, que vous êtes naïfs !! :-) ).  Le noyau possède toutes les fonctions nécessaires pour utiliser la carte ethernet, créer un nouveau processus, etc... Mais ces fonctions ne sont pas accessibles dans le mode utilisateur (faut pas réver non plus) où vous êtes confiné dans votre petit espace réservé pour faire vos petites affaires... Les system calls sont l'interface entre l'espace utilisateur et l'espace du noyau.  

Il y a un certain nombre de system calls, environ 190 dans la lignée 2.2, et chacun permet à l'utilisateur de faire appel à une fonction du noyau (noyau qui, je le rappelle, a tous les droits et peut donc utiliser les périphériques alors que l'utilisateur ne le peut pas directement). L'utilisation de system calls permet donc de switcher entre l'espace utilisateur et l'espace du noyau pour, par exemple, envoyer un message TCP (sendmesg, sendto, bind, listen... sont en fait un seul system call, socketcall, qui permet d'utiliser les fonctions réseaux du noyau), ou créer un répertoire (mkdir), changer les permissions d'un fichiers (chmod), envoyer des signaux aux processus (kill), etc...

L'appel d'un system call dans un programme génère une interruption qui permet de passer dans l'espace du noyau et pour pouvoir en utiliser les fontions.  

« Et fork dans tout ça ? » Me direz-vous, et bien, oui, vous avez raison, mais bon, maintenant je suis fatigué avec toutes ces histoires, alors plus tard pour fork...

haut de page

 8 5 1999

Mots Clés : fork.

Alors pour revenir à la discussion qui nous occupait hier, c'est-à-dire la création d'un démon, mieux vaut en premier lieu faire un peu de code, c'est toujours plus intéressant.


#include <unistd.h>

int main(){
      int pid;
      if (pid=fork()){ /* C'est le père */
            printf(Démon créé, taper \kill %d\ pour le détruire\n,pid);
      } else { /* C'est le fils, celui qui va devenir le demon */
            while (1){
                  printf(Coucou je suis un démon :-)\n);
                  sleep(10);
            }
      }
      return 0;
}
      

fork est un appel système qui permet de créer un nouveau processus. Je m'explique : au début n'existe qu'un seul processus qui s'exécute séquentiellement comme n'importe quel processus. Quand l'appel à fork() est exécuté, alors un nouveau processus est créé, identique au père, si ce n'est qu'il possède son propre environnement, sa mémoire, son PID...  À ce point il y a alors deux processus exécutant le programme, ce qui permet alors de différencier si on est dans le père ou dans le fils, c'est, comme le montre l'expression if(pid=fork()), que fork() ne retourne pas la même valeur dans le père et dans le fils.  0 est retourné dans le fils alors que c'est le PID du fils qui est retourné dans le père. Dans le programme exemple, le père se termine après avoir indiqué le PID du fils, alors que celui-ci entre dans une boucle infinie caractéristiques des démons.

fork est entre autre utilisé dans beaucoup de serveurs (http ou autre). En effet, un programme père écoute un port particulier, dès qu'une requête arrive, un fils est créé pour la traiter et le père continue d'écouter le port, permettant ainsi à plusieurs clients de se connecter simultanément.

haut de page

 9 5 1999

Mots Clés : compilateur, compilateur.

Je vous ai causé hier d'un programme C, mais je ne vous ai pas expliqué comment le compiler et l'exécuter, et ceci m'amène donc à vous parler de compilateurs.  

Pour introduire les compilateurs, d'abord deux trois mots sur ce qu'est vraiment un programme. Un programme est une suite d'instructions qui s'exécutent séquentiellement sur un microprocesseur. Un microprocesseur est un circuit électronique assez complexe qui produit une action différente suivant les signaux électriques qu'on lui fournit. Basiquement tout est codé sous la forme de 1 et de 0, c'est-à-dire de présence ou d'abscence de signal électrique.  

Chaque microprocesseur a ses caractéristiques propres et possède un certain nombre de fonctions prédéfinies formant le langage machine. Pour créer de nouveaux programmes exécutables sur un microprocesseur particulier il faut en produire le code en langage machine, c'est-à-dire le listing hexadécimal représentant le code binaire. Si au début de l'informatique cela se faisait, la complexité des instructions ont vite poussé à utiliser le langage assembleur ou les instructions ne sont plus écrites en binaire mais avec des mots clés correspondants aux différentes instructions. Mais l'assembleur reste d'un niveau très bas, extrêmement proche du microprocesseur, et difficile à manier. De ce fait sont apparus des langages de niveau supérieur qui rendent la programmation beaucoup plus simple et moins dépendante du microproce! ! ! ! ! ! ! ! ! ! sseur.  C'est alors au compilateur de se charger de transformer votre programme en C, C++, Pascal, Fortran, Perl, Python, Tcl ou autre en langage machine, avec quelques optimisations au passage si possibles.  

Pour les programmes écrits en C et C++, gcc, (GNU CC) est très courant, de même qu'egcs.  

Pour ne pas perdre de temps et aller à l'essentiel, la commande de base pour compiler et lier un programme avec gcc est :  
gcc -o nom_de_l_executable nom_du_programme_source.c...

haut de page

 10 5 1999

Mots Clés : gcc (vue générale).

Toujours enrhumé, ça me gave... Enfin... Bon, rapide parce qu'il est tard : la génération d'un exécutable à partir d'un code source passe par 4 grandes étapes bien distinctes:
Le traitement par le préprocesseur.
La compilation.
L'assemblage.
L'édition de liens.

Le traitement par le préprocesseur.
Celui-ci consiste à une première lecture du source avec traitement de directives qui influenceront par la suite la compilation, par exemple l'exclusion de certaines parties du code si une variable existe ou pas, la définition de macro permettant de faciliter l'écriture du code, ou la définition de certains symboles.

La compilation. Celle-ci transforme le code résultant du traitement par le préprocesseur en code assembleur, i.e. en suite d'instructions du microprocesseur, mais en utilisant des mnémoniques rendant la lecture (techniquement) possible.

L'assemblage. Transforme le code assembleur en binaire, c'est-à-dire en instructions directement compréhensibles par le microprocesseur. Généralement la compilation et l'assemblage se font dans la foulée, sauf si on spécifie explicitement que l'on veut le code assembleur.

L'édition de liens. Une fois chaque code source indépendamment assemblé (un programme est souvent séparé en plusieurs fichiers sources, pour des raisons de clarté mais aussi parce que des bibliothèques de fonctions standard déjà écrites peuvent être utilisées), il faut lier entre eux les différents objets (c'est le nom donné aux fichiers compilés mais pas encore liés), ce dont se charge l'éditeur de liens.

Et une fois tout cela terminé et bien normalement on a déjà passé deux bonnes heures à corriger toutes les erreurs de syntaxe du code source, et maintenant on peut se lancer dans les joies du debugage, des segmentation fault et autres core dump, mais ça, c'est une autre histoire...

haut de page

 16 5 1999

Mots Clés : week-end.

Yep, de retour de ce loooong week end... Qui fut bien chargé... Je voulais paufiner mon début de présentation de gcc et ajouter quelques commentaires sur le préprocesseur et ce genre de trucs... Mais tout s'est passé d'une façon telle que rien n'a marché correctement et, hormis le fait de m'avoir énervé passagèrement, a fait en sorte que je n'ai pas eu une seconde de libre...

Attention, récit du week-end, ceux qui n'en ont absolument rien à faire peuvent aller faire un tour, de toute façon c'est juste pour réhabituer mes doigts à taper :-) (bien qu'en fait j'ai pas vraiment pris des vacances de ce côté là)... Bon déjà mercredi soir c'est clair que je ne pouvais rien faire, je suis rentré à 23h, le temps d'installer la babasse, de configurer le réseau, de virer tous les services de NIS et autres NFS qui plantaient il était déjà bien tard... Jeudi avait bien commencé, somme toute, un petit tour de vélo dans l'après midi, ça faisait bien longtemps, mais rien de méchant, juste pour le fun, dans les 40 bornes, 800 mètres et quelque de dénivellé, pour oublier les ennuis du matin après mes vaines tentatives pour installer la RedHat 6 à partir d'un CD gravé en Joliet issu du téléchargement sur le web (cdrom, puis FTP, NFS... rien n'a marché...).

Tiens le soir un petit ciné pour oublier, un peu, la babasse, et se rendre compte que finalement ce n'est pas (trop) grave...Sheakspeare in love (Damned, un bout de chocolat coincé sous la touche inférieure de mon clavier, galère...), je l'ai vu en français, dommage, mais cependant c'est bien gentil, rien de formidable, mais c'est mignon comme tout...

Mais bon, cela n'arrange pas mon problème de RedHat... Encore la galère... Vendredi, pas cool, TOUT foire, je sais pas pourquoi, pas le temps de lire mon mail, pas le temps d'écrire quoi que ce soit, pas le temps d'aller faire du vélo... GALERE totale, incroyable, pourtant je m'acharne jusqu'à 2h30 pour installer cette foutue redhat sur l'ordi de mes parents (en m'apercevant au passage que les 32 meg de RAM que j'ai ajouté merdent royal (tous ces foutus Segmentation Fault ne venaient pas d'un conflit de bibliothèques, somme toute))...

Samedi se passe un peu mieux finalement... Gnome n'est pas si mal finalement, une fois bien configuré, rien de catastrophique... Par contre j'ai eu des problèmes assez balèzes avec le serveur S3 d'XFree86, qui plantait régulièrement jusqu'à je trouve enfin le bon convertisseur digital analogique, que Xconfigurator n'a pas trouvé de lui-même d'ailleurs, il a fallu que je démonte pour regardé les références, mais ce n'est pas très grave de toute façon avec la mémoire qui merdait la pauvre babasse est restée à l'air pendant deux jours... Pas de quoi prendre un coup de Soleil cependant, parce que finalement il n'a fait vraiment beau que jeudi et dimanche, et avec toutes ces histoires j'ai pas beaucoup profité du Soleil, tant pis...

Et voilà voilà, de retour chez les barges, je compile les noyaux 2.2.9 et 2.3.2 pour voir ce que ça donne... Il me semble que j'ai quelques blèmes de mémoire avec le 2.2.7, mais pas le temps de chercher, on verra avec le 2.2.9...

Aller, c'est reparti pour un tour...

haut de page

 17 5 1999

Mots Clés : gcc (commandes générales).

Alors, bon, après tous ces évennements, reprenons calmement. Donc gcc est un compilateur, c'est-à-dire un programme permettant de générer à partir du code C ou C++ des exécutables (mais qui l'a compilé, le compilateur ? Hé Hé ! Personne, enfin, disons qu'à la base, un compilateur est un peu de code assembleur qui permet de compiler certains trucs qui permettent à leur tour de compiler plus de trucs et basta, le tour est joué).

Différents types de fichiers
Comme je vous l'ai déjà dit, la génération d'un exécutable passe par 4 étapes et on peut retrouver à chaque étape un fichier, qui peut être utilisé pour l'étape suivante. gcc se base sur le suffixe du nom du fichier pour identifier le contenu, à défaut il faut lui préciser manuellement (option -x LANGAGE). Les extensions par défaut sont :
toto.c : fichier source C qui doit passer par le préprocesseur.
toto.i : fichier source C qui ne doit pas passer par le préprocesseur.
toto.ii : code C++ n'ayant pas besoin de passer par le préprocesseur.
toto.h : fichier d'entête, euh, ben on y fait rien à ceux là, si quoi, on les inclut dans les fichiers sources, yep, c'est ça, on les inclut...
toto.cc, toto.cxx, toto.cpp, toto.C : fichiers sources C++ qui doivent passer par le préprocesseur.
toto.s : code assembleur.
toto.S : code assembleur qui doit passer par le préprocesseur.

Options permettant d'obtenir les différents type de fichiers
-c : compile et assemble le fichier mais ne crée pas les liens, reste au stade d'objet. Le fichier resultant est le code machine correspondant au fichier source (le nom de sortie standart est le nom du fichier de départ avec l'extension .o) mais sans liens vers les fonctions définies ailleurs. Ce qui est logique, somme toute, puisque justement, les liens, on les a pas fait :-).
-S : sort le code assembleur, si vous voulez voir ce que c'est... Intéressant aussi pour voir les optimisations que gcc peut faire à votre code.
-E : arrête après le préprocesseur.

Vous pouvez à chaque fois changer le nom par défaut de sortie avec l'option -o nom_de_fichier_bidon_rien_qu_a_moi.

haut de page

 18 5 1999

Mots Clés : bc.

Bon gcc c'est bien sympa mais tous les jours ça gave un peu, alors pause... Surtout que je vous cause de gcc alors que si ça se trouve vous ne savez même pas programmer en C... Ce qui est bien bête, je le consens... L'idéal serait que je couple quelques bases de C avec le compilo...Pfff, ça me fatigue rien que d'y penser...  Mais il est vrai que ce serait quand même super coolos... Je vais y réfléchir... J'ai un autre sujet qu'est pas mal aussi, comment recevoir des fax sous Linux, ou des appels téléphoniques (genre au boulot :Ho damned, j'ai oublié la super image mega top que je dois ABSOLUMENT envoyer à tous mes potes avant qu'un autre ne le fasse, vite, je me connecte chez moi grace au modem du labo, je rappatrie l'image par le GSM avec la carte modem PCMCIA puis je transfère tout ça via wavelan sur l'autre babasse pour faire croire que je fais des tests...)... Je sais pas encore faire ça, enfin, disons que j'ai bien une vague idée de quoi mettre où, mais pas dans les détails, ça serait l'occas d'éclaircir la chose.

En fait, quand j'y réfléchi, l'idéal comme langage à connaître, c'est C, java, script shell, perl, python, et un peu sed et awk, avec ça on peut s'en sortir...(marrant le type, genre c'est sûr que si tu masterises tous les langages de la Terre ya plutôt intétêt à ce que tu t'en sortes, où c'est que vraiment la vie n'est pas tendre avec toi :-). J'ai pas mis C++, bof, disons que c'est sûr que si vous voulez programmer des applications aujourd'hui, c'est le langages privilégié, mais pour les concepts, mieux vaut faire du java, plus clean, et pour les trucs plus bas, rien ne vaut le bon vieux C.

Le mardi n'a jamais été mon fort et ne le sera sans doute jamais, alors autant ne pas agir contre le sort, le mardi c'est pourri et c'est comme ça, on n'y peut rien, même avec toute la volonté du monde tout foirera lamentablement, pas productif, fatigué, plein de trucs pas cool, c'est comme ça, c'est la vie.

Java, tiens c'est vrai, faudrait que je cause de java, et en plus ça me permettrait de m'y remettre un peu parce que depuis 3 mois c'est plutôt la glande de ce côté là... Mais maintenant que j'ai commencé gcc il faut que je finisse... Bon, ben alors on se tapera un peu de C et après on fera du Java, on enverra quelque fax, puis allez, foly, on se lance dans le perl, python et autre sed, tant qu'à faire on se fait un parser avec yacc et lex... Enfin on verra quoi...

Je vous ai déjà parlé de bc (réflexion interne : regarde dans l'index blaireau ! Ha ouais t'as raison :-) )?... bc est un petit truc qui permet de faire des calculs, c'est vrai qu'il existe xcalc, mais c'est lourd, faut bouger la souris avec ses mains et tout... pfff, fatigue... Heureusement bc existe, alors on tape bc tout simplement, puis, se retrouvant dans un environnement bc, on peut taper rapidos son addition qu'on aurait dix fois eu le temps de faire de tête mais bon, faut profiter du progrès... On peut surement faire d'autre truc avec, mais je ne me suis jamais penché sur la question... Pour quitter taper quit... L'avantage de bc par rapport au capacité de calcul du shell (en tapant $((calcul compliqué))) c'est que ça marche avec des réels aussi...  On peut faire ça avec python aussi je crois... Yep, ça marche aussi avec python, mais bon c'est un peu dommage de lancer python pour faire des calculs bidons... Quoique, après tout, on fait ce qu'on veut...

haut de page

 20 5 1999

Mots Clés : programmation.

La programmation, quand on y pense, est ouverte à tous, il suffit d'avoir une babasse et un compilo. Ce qui est plus dur, c'est de BIEN programmer, parce qu'après tout, connaître la syntaxe, ça n'a rien d'extraordinaire, c'est peut être embettant à mourir, paraître illogique, impossible à mémoriser ou donner très très mal à la tête, mais à vrai dire ce n'est pas très important, n'importe quel bouquin de référence est là pour vous la rappeler. Par contre savoir bien programmer, c'est pas la même paire de manches.

Les machines et les architectures étant différente entre elles, quand on écrit un programme qui touche un peu au matos, inévitablement on doit prendre en compte des caractéristiques propres à ce matériel. Mais cependant je ne pense pas qu'il soit préférable de commencer par programmer sur un processeur particulier, mieux vaut je pense acquérir un bon schéma de pensée dans un contexte général, et on sera toujours à temps de faire des exceptions plus tard. D'autre part la nature même du langage peut privilégier certaines implémentations à d'autres. Mais d'une façon générale je pense tout de même qu'il faut plus apprendre à penser son programme qu'à le coder.  

Je suis loin d'être une brutasse en programmation, et je n'ai pas la prétention de vous apprendre à programmer, juste, peut-être, vous donnez quelques bases et les pièges à éviter...

En ce moment je suis de plus en plus à la bourre et je ne sais pas trop si je pourrais continuer cette chronique dans le futur, en tout cas au moins pour un certain temps, mais bon...

Alors pour illustrer un peu tout ça, je me baserai principalement sur C et Java, d'une part parce que ça me permet d'avoir un langage procédural assez souple et ouvert et un autre orienté objet plus strict, et d'autre part parce que je ne maîtrise pas assez d'autres langages pour me la jouer « je cause fortran, basic, perl, cobol et lisp sans aucun problème »... Quoique... je pourrais faire un peu de prolog ça pourrait être cool car le prolog est vraiment sympa pour apprendre les concepts... Le caml aussi... Mais malheureusement je n'ai pas vraiment le temps de me replonger dans ces jolis langages :-).

Alors suffit les bavardages, c'est partie pour un (long) voyage dans le monde (merveilleux) du codage... Le but de la programmation est de faire un machin qui fait des trucs, et contrairement à ce que vous pouvez penser, il n'y a PAS forcément quelqu'un qui a déjà dû résoudre votre problème avant vous, il y a de fortes chances, c'est vrai, mais peut-être dans un contexte un peu différent qui fait que certes, jeter un coup d'oeil à ce qui existe déjà est un bon réflexe, mais que cela ne vous empêche pas de coder vous même une solution peut-être différente, peut-être basique, mais peut-être nouvelle et originale. Ne vous sous-estimez pas (rêvez pas non plus, un système d'exploitation ne se code PAS en une semaine).

Il faut bien voir que quel que soit le langage, au final vous obtiendrez la même chose, un programme qui va s'exécuter sur votre processeur, les différents types de langages apportent seulement une approche différente.

Tiens ben de l'affaire il est plus très tôt maintenant... Encore une journée loose tiens... Décidemment, il ne fera jamais beau par ici... À croire que le mauvais sort me poursuit...

haut de page

 21 5 1999

Mots Clés : programmation (exemple basique C et java).

Alors bon, aujourd'hui, pas violent, juste un petit exemple en C et la même chose en java...

Voilà un programme en C des plus classique (program.c) :
int main(){
    printf(Coucou\n);
    return 0;
}   
Que l'on compile en tapant gcc -o test program.c, et exécute en tapant test. Un programme C, par défaut, commence par exécuter la fonction main(). Une fonction, généralement, retourne une valeur  (par exemple la fonction cos(x) retourne le cosinus de x) et il faut comprendre la notion de fonction de la même manière que cos, sin ou autre log. Cependant le type de retour peut être extrêmement varié, c'est pour cela que je précise que ma fonction main retourne un entier (int est l'abréviation de integer), et je retourne explicitement (avec la ligne return 0) un entier à la fin de la fonction.  De plus ma fonction main utilise une autre fonction, printf, qui est standard en C, et qui imprime sur la sortie standard (stdout), le texte passé en argument (man 3 printf pour plus d'info). Cette fonction retourne le nombre de caractères écris, mais comme je m'en balance, je ne m'en sert pas. À remarquer que chaque instruction d'un programme C est terminée par un <;>. Le <\n> c'est pour aller à la ligne.

Alors si on jette un coup d'oeil au code assembleur (gcc -S program.c), on voit :
gcc2_compiled.:
.section        .rodata
.LC0:
        .string Coucou\n
.text
        .align 4
.globl main
        .type    main,@function
main:
        pushl %ebp
        movl %esp,%ebp
        pushl $.LC0
        call printf
        addl $4,%esp
        xorl %eax,%eax
        jmp .L1
        .align 4
.L1:
        leave
        ret
.Lfe1:
        .size    main,.Lfe1-main
        .ident  GCC: (GNU) 2.7.2.3            
Bon je ne rentre pas dans le détail (de toutes façons j'en suis bien incapable) mais en gros, on trouve la définition de la commande main, qui appelle la commande printf en lui passant en argument la chaine de caractère définit un peu avant en dur dans le code. On remarquera que le compilo fait un xorl (le l pour long) pour obtenir le 0 que la fonction retourne. De plus le code de la commande printf n'est pas inclu dans le code, c'est normal : d'une part les liens n'ont pas été faits, et en plus dans Linux existe la possibilité d'avoir des librairies de fonctions dynamiques, qui sont liées dynamiquement à l'exécution, c'est-à-dire que même votre programme final ne contient pas le code de printf, celui-ci est chargé à l'exécution.  

Bon et bien maintenant montons dans les hautes sphères de la programmation objet pour faire la même chose en java.
public class Test{
        public static void main(String argv[]){
                System.out.println(Coucou\n);
        }
}  
Alors ici l'optique est différente. Java est un langage objet, ce qui signifie que, si C est principalement basé sur des fonctions, java lui est basé sur des classes qui définissent des objects. Je déclare ici la classe Test. Une notion fondamentale à saisir est la notion d'existence de l'objet. Pour qu'un objet existe, il faut en créer un, c'est-à-dire quelque part en mémoire créer une instance de celui-ci. Ainsi un même objet peut-être créé plusieurs fois dans une même exécution sans qu'il y ait de problème, car si il n'y a qu'un seul fichier définissant la classe de l'objet, il y a en mémoire deux copies bien distinctes de l'objet.        

Il faut tout de même un objet principal pour lancer l'affaire. Mais alors comment créer le PREMIER objet. Ceci est possible grace à l'existence de méthodes statiques, c'est-à-dire qu'elles existent indépendamment des objects, ce sont des méthodes de classes. Comme en C, la première méthodes appelée est la méthode main, qui doit forcément être statique vu qu'aucun objet n'existe encore. Dans l'exemple proposé, en fait aucun object n'est créé, j'utilise simplement la méthode statique main qui appelle elle-même la méthode statique println de la classe System.out.  À aucun moment je n'ai créé d'objet, je me suis contenté de méthode de classes.

Alors pour compiler ce programme en java, appelé Test.java (le nom d'un fichier java doit être celui de la classe principale qu'il définit), il faut taper java Test.java si vous avez le JDK installé sur votre machine, ou guavac Test.java si vous utilisez le compilateur java de GNU. Ceci va générer le fichier Java.class, qui est le code assembleur de votre programme. Mais ce code assembleur n'est pas celui de votre procésseur, mais celui d'un processeur virtuel java. Et pour exécuter ce code il vous faut simuler une machine qui aurait ce processeur, c'est ce que fait le programme java (ou l'équivalent kaffe de GNU). C'est pour cela que l'on parle de machine virtuelle java et que le code des classes est portable sur toutes les architectures dans la mesure où une machine virtuelle java (qui elle est spécifique à chaque processeur) existe sur cette archit! ! ! ! ! ecture.

Pour exécuter ce programme java, il faut faire appel à la machine virtuelle en tapant java Test ou kaffe Test.

haut de page

 22 5 1999

Mots Clés : wget.

Les week-ends c'est cool mais quand on y pense finalement c'est encore plus crevant que la semaine, à croire qu'on se debrouille mal au niveau organisation et qu'au final on prend même pas le temps de se faire une bonne petite nuit... J'ai un peu bouquiné aujourd'hui, Linux device drivers d'Alessandro Rubini... Je crois que je ne suis pas encore prêt parce que j'en capte pas la moitié...Décidément les vacances c'est pas encore pour tout de suite...

Bon comme c'est le week-end, on va causer de truc pas trop prise de tête, coolos... Par exemple, vous est-il arrivé de devoir télécharger un gros trucs, genre StarOffice 5.1 par exemple, 70 megas, en une seule fois c'est un peu du suicide. Mais, heureusement, il existe des outils qui permettent de télécharger des fichiers de tailles conséquentes en plusieurs fois. C'est quand même super pratique et ça evite de devoir dormir avec le ronflement du ventilo (quoiqu'avec une batterie CMOS niquée on doit quand même se le taper mais bon :-)...

Plusieurs outils permettent de faire cela, même Netscape (parfois) reprend un téléchargement ou on l'a laissé (mais c'est assez aléatoire j'ai l'impression alors autant oublier). En ce qui me concerne j'utilise wget qui est souvent en standard avec la plupart des distribs, de toutes façons ce n'est pas bien gros et ça se télécharge en 5 minutes (enfin, je dis ça au pif mais c'est l'ordre d'idée).

wget est un petit programme qui marche en ligne de commande (il y a peut-être des front-ends mais je ne les connais pas) et qui permet de télécharger sans se fatiguer des pages html, des fichiers, mais aussi toutes une arborescence HTMl ou FTP en suivant les liens jusqu'à une profondeur donnée. Tout est bien entendu configurable, il supporte les proxy via les variables d'environnement ftp_proxy et http_proxy. Les principales options sont les suivantes (info wget pour les curieux) :
Syntaxe générale : wget [option] URL_complete
-b : passe en tâche de fond direct, vous permettant de vous déloguer pour aller manger un bout au chinois du coin.
-t n : spécifie le nombre maximal d'essais infructueux, 0 pour infini.
-c : l'option cool, continue le téléchargement du fichier ou de l'arborescence en reprenant là où il avait arrêté ; sans cette option les fichiers ne sont pas ecrasés (ça serait quand même bien dommage) mais les nouveaux ont un préfixe genre toto.html.1.
-nd : ne crée pas de répertoire dans le téléchargement, tous les fichiers sont copiés dans le répertoire en cours (surtout utile pour du FTP, moins pour une hiérarchie HTML).
-r : l'autre option cool, permet de télécharger récursivement tous les fichiers d'un répertoire et tous les sous répertoires jusqu'à la profondeur définie par l'option juste après.
-l n : profondeur maximale de récursion fixée à n.  

Bon et bien voilà en gros de quoi se donner un petit aperçu de ce que l'on peut faire sans trop se casser la tête avec wget.

haut de page

 23 5 1999

Mots Clés : Gestionnaire de fenêtres (Window Manager).

Arrgh... Je suis fatigué et j'ai mal partout et j'ai pas encore fini de lire ce bouquin (Linux Device Drivers) auquel je ne comprends rien (je DOIS le finir, c'est une question d'honneur, quitte à sauter toutes les pages)... J'ai l'impression d'avoir commencé ma journée il y a 10 minutes et pourtant il est 22h passé...

Finalement je reviens sur ce que j'avais dit il y quelques temps à propos de gnome et enlightenment qui me prenaient le chou, dans la RedHat 6.0 tout semble plutôt bien marcher, même pas mal en fait... Cependant enlightenment tout seul est pas mal non plus... Et faudrait pas enterrer fvwm2 trop vite même si j'ai encore cet insoluble problème de NumLock qui fait tout joyeusement planter... Alors comment faire ? Et bien jouez-vous la harem, après tout si on ne peut choisir autant tout prendre :-).

Pour cela rien de tel qu'un petit script bien cool qui tire un gestionnaire de fenêtres au hasard au démarrage... Celui que je vous propose ne marche pas du feu de Dieu, mais vous êtes toujours à temps de le personnaliser.

Le script principal s'appelle startwm, qui est vachement original comme nom. Le voici :

#!/bin/bash

PATH=$PATH:/usr/X11R6/bin:/opt/kde/bin:/usr/bin:/bin:/local/bin:/home/warly/local/bin
export PATH

n=`cat $1 | wc -l`
i=$RANDOM
j=$((i%n+1))
exec `head -n $j $1 | tail -n 1`

Rien de bien formidable, bon d'abord je dois déclarer le PATH sinon ça marche pas, je trouve pas ça super cool, mais bon, si vous avez une meilleure solution je suis preneur. Pour faire marcher ce script, il faut lui passer en paramètre le fichier où sont donnés les gestionnaires de fenêtres disponibles, par exemple :

/usr/X11R6/bin/fvwm2
/usr/X11R6/bin/afterstep
/usr/bin/enlightenment
/opt/kde/bin/startkde
/usr/bin/gnome-session
/usr/X11R6/bin/twm

Le script compte le nombre de gestionaires dispo, tire un nombre au hasard, fait le modulo nombre de gestionnaires et exécute le gestionnaire gagnant (Yeah ! ). Voilà, c'est tout.

Ensuite il faut mettre un appel à ce script dans votre .Xclient ou .xinitrc suivant votre config. Et vous voilà reparti pour une configuration incessante non pas d'un, mais 3, 4 ou même 10 gestionnaires de fenêtres, c'est il pas beau ça ? Je suis sûr que vous vous ennuyiez un peu le soir, alors voilà de quoi vous occuper ;-)...

haut de page

 24 5 1999

Mots Clés : Errata.

Ouais, je sais c'est pas cool, et je n'en suis pas fier, mais je me suis lourdé royal. Après tout c'est la vie, on n'a pas toujours raison, on peut se tromper... C'est vrai, mais c'est quand même la honte et l'humiliation totale, surtout que ce que j'avais dit était, quand on y réfléchit, profondément débile... Cela remonte au 1er mars, même pas le 1er avril, là j'aurai pu me défiler tranquillos, non, le 1er mars, troisième mois de l'année...

En ces temps obscurs, ma fougue du débutant m'a fait partir dans de bien grands discours que je ne maîtrisai point, et, pris dans un élan d'orgueil, ne voit-il pas que j'affirme haut et fort qu'une bzImage est identique à une zImage si ce n'est qu'elle est compressée avec bzip2 ! Ah mais quelle folie ! Je ne mérite que le fouet et votre éternel mépris ! Je vous prie de revevoir mes plus plates excuses. Voilà une rectification, que j'espère plus proche de la réalité.

Les processeurs Intel, autrement appellés x86, possèdent une compatibilité ascendante, qui est l'une des priorités des ingénieurs de chez Intel. Ceux-ci sont initialisés dans un mode appelé mode réel, qui remonte au temps sacré du 8086. En ces temps reculés, le processeur ne pouvait pas adresser plus de 640 Ko de mémoire, cela n'était pas un blème terrible à l'époque, mais malheureusement avec votre nouveau Pentium !!! (vous avez remarqué, ce sont des points d'exclamations qui font le III, ça veut dire qu'il faut le crier très très fort ;-), et bien celui-ci s'initialise toujours en mode réel, autrement dit avec 640 Ko de mémoire adressable, ce qui est quand même sacrément lourd, soit dit en passant.

Le but du jeu est donc de réussir à booter sur votre noyau avec 640 Ko de mémoire. C'est pour cela que votre noyau compressé (zImage) ne doit impérativement pas dépasser cette taille. Dans le processus de boot, le processeur passe ensuite en mode protégé où toute la mémoire est accessible et le noyau est décompressé au delà du premier méga. Jusque là rien de contradictoire avec ce que j'avais dit. Là où j'ai lourdé c'est à propos de bzImage. En fait le <b> de bzImage signifie big. Le processus du chargement d'une bzImage est un peu différent dans le sens où, a priori, celle-ci ne tient pas dans les 640 Ko du mode réel. Alors c'est une feinte utilisant une fonction du BIOS qui permet de copier l'image compressée dans la mémoire supérieure par petits bouts pour ensu! ! ! ite la d écompresser.

Voilà qui devrait être un peu plus proche de la réalité que mon délire sur bzip2...

Accessoirement j'ai aussi un petite erreur dans le script d'hier, il faut lire exec `head -n $j $1 | tail -n 1` et non pas exec `head -n $j .wm | tail -n 1`. Quoique je me demande si le exec est bien nécessaire tiens... À voir... Enfin, c'est moins grave que l'erreur d'avant...

haut de page

Mots Clés : StarOffice 5.1.

À part rien faire, j'ai aussi installé StarOffice 5.1 ce week-end. Pas de quoi pavanner de toutes  façons vu que l'install est bien faite et tout s'installe hyper clean en 5 min chronos, lecture de la doc comprise. La version 5.0 ne marchait plus sur ma machine depuis que j'avais upgradé mes libs (oups, pardon, bibliothèques). La 5.1 s'installe sans trop raler (elle dit juste que j'ai pas la glibc-2.0.7, mais avec la glibc-2.1 je me suis dit que ça valait qu'on tente le coup).

En tant qu'utilisateur il faut encore une petite install, dommage que le répertoire ne soit pas par défaut $HOME/Office ou un truc dans le genre plutôt que $HOME/Office51, ce qui signifie qu'il faut à la main transférer son ancienne arborescence $HOME/Office50. Quoiqu'il y a peut-être un truc pour le faire mais pas cherché... Enfin, le bureau ne change pas trop par rapport à la version précédente. Ça a l'air de marcher pas trop mal même si je ne me suis pas attardé dessus, assez complet, ça fait du texte (encore un peu de mal avec certains fichier word quand même, mon CV plante royal), des tableaux, des présentations, du web, des dessins... Bref, plein de trucs.

Maintenant est-ce que ça vaut la peine de télécharger 70 megas, soit à peu près 30 balles en communication ; ma foi si ça peut m'éviter de rebooter sous windows une fois par mois c'est pas cher payer (surtout que j'ai même pas Office). On peut aussi l'acheter pour $40 avec des docs, c'est honnête et franchement ça les vaut, comparé aux 2000 balles de Microsoft Office...  

Bref, j'en dirai pas plus vu que j'en sais pas plus (ce qui se vaut comme argument). Ah! j'oubliais, il existe une version française, ce qui est quand même appréciable, malgré tout.

haut de page

 25 5 1999

Mots Clés : programmation.

Très mauvaise journée, je me suis demandé toute la journée pourquoi le sort s'acharnait, et ce n'est que maintenant, 22h et quelques, que je réalise : c'était mardi, forcément, je ne pouvais pas m'attendre à des miracles... Cela dit la journée s'est un tout petit peu mieux terminée, mais rien de fabuleux.

Bon, je vais encore un peu parler de programmation... Alors l'autre jour, j'ai causé de comment faire un petit programme C qui affiche <coucou> et de son équivalent en java, alors aujourd'hui on va simplement faire un petit truc un petit peu plus compliqué, mais pas trop.


int f(int , int );

int main(int argc, char *argv[]){
        int a,b;
        if (argc == 3){
                a = atoi(argv[1]);
                b = atoi(argv[2]);
                printf(Résultat : %d\n,f(a,b));
        }else printf(Usage : plus a b\n);
        return 0;
}

int f(int a, int b){
        return a+b;
}

Que l'on compile avec gcc -o plus plus.c et que l'on utilise avec plus 3 4 ce qui donne: Résultat : 7...   
Alors plusieurs choses. Il est possible de passer des arguments au programme, c'est la fonction main qui les récupère. La forme de main est toujours la même, c'est-à-dire int main(int argc, char *argv[]). La variable argc contient le nombre d'arguments qui ont été passés au programme (nom du programme y compris) et argv est un tableau qui contient tous les arguments. À ce niveau une petite explication est nécessaire : char est le type correspondant aux caractères. Quand on veut créer un tableau, on utilise les crochets. Par exemple char tab[10] définit en mémoire un endroit pour stocker 10 caractères.  

En C une chaîne de caractèrse est une suite de caractères terminée par <\0;>. Comme toutes les chaînes se terminent par <\0;>, seule l'adresse en mémoire du premier caractère est suffisante, après il n'y a plus qu'à parcourir la mémoire jusqu'à trouver un <\0;> (d'où son importance, sinon votre programme va continuer à parcourir la mémoire dans des endroits où on ne sait pas trop ce qu'il y a, et c'est pas super conseillé). Alors pour avoir l'adresse en mémoire d'une variable, on utilise <&>. Par exemple &tab donne l'adresse de tab, c'est-à-dire l'adresse du premier caractère de la chaîne formée des différents éléments du tableau jusqu'au <\0;> (qui DOIT être un des éléments). Il faut savoir qu'en C le premier élément d'un tableau a l'! ! index 0  et le dernier l'index taille-1.

Les problèmes de gestion de mémoire sont fondamentaux en C, et il faut absolument les comprendre. Quand vous déclarez une variable alpha, un emplacement en mémoire est réservé pour cette variable, cet emplacement a la taille adaptée au type de la variable. Avec l'opérateur <&;> vous pouvez avoir l'adresse de cette variable. Il existe en C un type particulier de variable, ce sont les pointeurs, un pointeur est une variable qui contient une adresse mémoire. Ceux-ci se déclarent avec l'opérateur <*>. Par exemple char *c n'est pas un caractère mais une variable qui contient l'adresse mémoire d'une variable qui est un caractère. Mais attention, si l'emplacement en mémoire pour contenir cette variable c est initialisé quand on la déclare... Tiens vous savez ce que c'est que déclarer ? Houla je le sens mal cet article, je m'embrouille ! ! dans tou t ce que je dis parce que je veux parler de tout en supposant que vous savez rien et c'est la totale galère... Je ne suis pas sûr que ce soit bien bien pensé tout ça...  

Bon et ben alors je fais quoi là, je me barre ou je continue ? Tiens ben je sais pas... Bon ben de toutes les façons vous n'avez qu'à exécuter le programme vous verrez que ça marche et basta...

C'est un peu vache quand même de faire ça, ça me fout des complexes tiens... Bon je vais reprendre d'une façon plus logique et je rentrerai dans les détails petits à petits, voire demain ou plus tard s'il le faut. Tiens non demain je serai sûrement pas là, et la fin de semaine va être short, alors plus tard quoi...

int f(int,int) : Cette ligne s'appelle un prototype, là je dis au compilateur : « Et mon brave, tu vois f ? et bien c'est une fonction qui retourne un entier et qui a comme arguments 2 entiers, mais, bon, comment dire, là c'est pas trop le moment pour te dire ce qu'elle fait alors je te le dirai un peu après, hein, ça marche comme ça ? ». Et chose promise chose due, vous trouvez effectivement un peu plus tard dans le code la définition de la fonction f, qui n'est pas EXTRÊMEMENT compliqué, c'est vrai... Bon je vais pas vous causer de trucs évidents comme  « Mais pourquoi dans la définition les arguments ils ont un nom et pas dans le prototype ? », je vous laisse trouver tout seul...
Ensuite vient ma fonction principale main qui reçoit en argument d'une part le nombre d'éléments dans la ligne de commande (argc) et d'autre part l'adresse du premier élément d'un tableau dont chaque élément est une chaîne de caractères représentant un des arguments. Ce tableau n'a pas de taille spécifiée car on ne la connait pas d'avance.
Je déclare ensuite deux entiers, a et b, qui, si le nombre d'arguments est égal à 3 (le nom du programme plus deux nombres), recoivent la conversion en entier des chaines de caractères représentant les arguments 1 et 2 (avec la fonction atoi). Et puis j'affiche le résultat grâce à la fonction printf. printf affiche des chaînes de caractères formatées. Le <%d> signifie : « He, bon, tu me mets pas %d là à l'écran, hein, déconne pas, tu me mets un entiers, d'accord, bon, je te le file juste après. ». Et effectivement l'argument suivant de ma fonction printf est l'entier que je veux afficher.

Bon ben je crois que je vais m'arrêter par là et pas m'enliser plus encore, ça suffit comme ça... Quoique j'avais pas fini sur les pointeurs... Bon, un pointeur est une adresse mémoire, simple, donc dedans je mets des adresses, par exemple un pointeur sur des char et bien dedans je peux mettre &tab de mon tableau de tout à l'heure, et dans ce cas mon pointeur donne l'adresse du premier élément de la chaine de caractères contenue dans tab. La déclaration char *argv[] définit un tableau de pointeurs sur des char. Chacun de ses éléments contient donc l'adresse d'un char, et pour peu que ce char soit en fait le premier élément d'un tableau de caractères, c'est-à-dire d'une chaîne, et bien j'ai un tableau dont chaque élément est l'adresse d'une chaîne de caractères, et voilà j'ai mes argumenets... Bon là je! me cass e pour de bon...

haut de page

 30 5 1999

Mots Clés : programmation (java, programmation (java.

Un petit break, ça ne peut pas faire de mal... Alors quoi de neuf? et bien pas grand chose me semble t'il, l'été approche, et forcément l'été ce n'est pas une période très très dynamique, c'est plutôt relax... Et il se pourrait que moi aussi je me la joue relax en prenant un peu de vacances, enfin on verra.

Bon l'été est, c'est vrai, un moment bien sympa pour le Soleil, la plage, les nanas et tout et tout, certes, mais c'est surtout le moment idéal pour enfin pouvoir babasser comme on le veut, aux heures qu'on veut et sur les sujets que l'on veut, et ça c'est cool ! Je sais pas encore trop ce que je vais faire, probablement un peu de java et un peu approfondir au niveau du noyau, mais rien de sûr (je sens bien la glande profonde ;-)...

Alors la dernière fois je vous avais (difficilement) causé d'un petit exemple de programme C ou je m'étais lamentablement embourbé... Et je n'avais dans l'affaire pas causé de l'équivalent en java, alors bon, comme il est de bonne augure de finir ce qui est commencé, et bien je vais vous filer deux programmes qui font une chose équivalente, mais avec une approche fondamentalement différente, mais comme il y a pas mal de concepts et que je ne veux pas me la jouer kamikaze en essayant (vainement) de tout décrire d'un coup, on va y aller progressif...



public class Plus {

        static int plus(int a, int b){
                return a+b;
        }

        public static void main(String argv[]){
                if (argv.length == 2){
                        System.out.println(Résultat : +  
                                        plus((new Integer(argv[0])).intValue(),
                                             (new Integer(argv[1])).intValue()));        
                } else System.out.println(Usage : java Plus a b);
        }
}

Voilà donc une première façon d'aborder les choses, et en voilà une deuxième :

public class Plus2 {

        int a,b;

        Plus2(int a, int b){
                this.a = a;
                this.b = b;
        }

        int plus(){
                return a+b;
        }

        public static void main(String argv[]){
                if (argv.length == 2){
                        Plus2 p = new Plus2((new Integer(argv[0])).intValue(),
                                             (new Integer(argv[1])).intValue());  
                        System.out.println(Résultat : + p.plus());
                } else System.out.println(Usage : java Plus2 a b);
        }
}

La façon d'aborder les choses dans ces deux programmes est assez opposée et en fait dépend de ce que l'on attend de notre objet. Bon là il fait beau alors je vais faire un tour, on en reparle après, OK ?

haut de page

 31 5 1999

Mots Clés : Haute Voltige.

Et bien oui que voulez-vous, parfois il faut savoir se laisser submerger et contrôler par la pseudo culture amerloc, c'est comme cela, on ne peut pas lutter contre l'appel des sens (enfin JE ne peux pas lutter, chacun son truc). Que dire de ce film, et bien peu de chose si ce n'est le manque de réalisme/intrigue/scénario/originalité/imagination... La nana est pas mal, mais bon, 50 balles pour voir une nana se la jouer en faisant la kéké au milieu des rayons, c'est quand même cher payé... Cela dit ça passe le temps, c'est sûr.

Je ne dis pas que le film est nul, non, c'est sympa, mais sans plus... Disons que c'est bien quand on a 15 ans, mais c'est vrai que là c'est peut-être un peu banal comme film... C'est un film d'action, certes, mais cela n'excuse pas le fait d'avoir pas mal d'invraissemblances et parfois quelques longueur... Bon ce que j'en dis au final c'est que, ouais, bon, sans plus quoi...  

haut de page

Mots Clés : programmation (java, programmation (java.

Dernier jour du mois de mai 1999, j'espère que vous en avez bien profité, de ce mois de mai 1999, parce qu'il n'y en aura plus jamais, fini, terminesh le mois de mai 1999.

Bon, pfff, hier j'ai balancé comme ça deux chti prog java sans commentaires (gonflé le gars) alors ça serait quand même coolos de ma part d'en dire deux mots.  Comme vous l'avez surement remarqué si vous avez compilé et exécuté ces programmes, ils font la même chose, mais l'approche est différente.  Tout d'abord un mot sur la déclaration de la méthode main, public void main(String argv[]) ; cette ligne ressemble pas mal à celle déjà citée du prog C d'il y a quelques jours. Elle fait en gros la même chose, c'est-à-dire que le tableau de chaîne de caractères (String est l'objet qui correspond à une chaîne de caractères) argv contient les paramètres de la ligne de commande, mais, contrairement à C, le nom du programme ne fait pas partie du tableau, c'est-à-dire que si je tape java Plus 3 4 pour lancer le programme, le tableau argv contiendra 3 en 0 et 4 en 1.

Le premier programme utilise un méthode statique plus, classique, cette méthode peut être appellée sans créer d'objets en mémoire, c'est une méthode de classe, qui existe indépendamment de toute instance de cette classe. On appelle instance d'une classe tout objet qui a été créé en mémoire à partir de cette classe. C'est ce qui arrive dans le second exemple. En effet la méthode plus de cette classe n'est pas déclarée statique, ce n'est donc pas une méthode de classe mais une méthode d'instance, c'est-à-dire qu'il faut créer un objet en mémoire pour pouvoir utiliser cette méthode. Ce que fait la méthode main avec la ligne Plus2 p = new Plus2((new Integer(argv[0])).intValue(), (new Integer(argv[1])).intValue());. Cette ligne déclare un nouvel objet de type Plu! s2  et passe en paramètre les deux arguments de la ligne de commande. Quand un objet est créé, son constructeur est appelé, le constructeur d'un objet est la méthode qui porte le même nom que la classe, Plus2 en l'occurence. Il peut y avoir plusieurs constructeurs avec des paramètres différents dans un même objet.

Le constructeur de la classe Plus2 initialise ses deux variables a et b (remarquez au passage l'utilisation de this qui est une référence à l'objet courant, pour ne pas confondre les variables a et b de la classe Plus2 et les variables a et b qui sont les paramètres du contructeur Plus2 et qui n'existe qu'à l'intérieur de celui ci. Il peut être judicieux de les appeler avec des noms différents pour éviter les problèmes, personnellement je mets souvent le même nom, c'est un choix, je dis pas que c'est le mieux, mais bon, hein, faut bien avoir des petites manies dans la vie...

Le deuxième programme fait ensuite appel à la méthode plus de l'objet p, qui est de type Plus2 et possède bien une méthode plus. Voilà un autre exemple de programmes ressemblant au précédent mais avec deux trois trucs en plus pour (j'espère) rendre les choses un peu plus claires.



public class Plus2 {

        int var1,var2;

        Plus2(int a, int b){
                var1 = a;
                var2 = b;
        }

        int plus(){
                return var1+var2;
        }

        int moins(){
                return var1-var2;
        }

        public static void main(String argv[]){
                if (argv.length == 2){
                        Plus2 p = new Plus2((new Integer(argv[0])).intValue(),
                                             (new Integer(argv[1])).intValue());  
                        Plus2 q = new Plus2(10,5);
                        System.out.println(Résultat de l'objet p : + p.plus()+ et de l'objet q : +q.plus()+  et de la différence entre les deux fontions moins de ces deux objets : +(p.moins()-q.moins()));
                } else System.out.println(Usage : java Plus2 a b);
        }
}

Bon et bien je vous laisse un peu méditer là-dessus, parce qu'il faut savoir aussi un peu réfléchir de temps en temps :-).

haut de page

Mois suivant

Valid HTML 4.0!

Warly Home Page   Generated 2000-07-02, 11h31   Mail
Copyright © 1999,2000 Florent Villard (warly@bigfoot.com)
This site was created with daily (tar.gz, rpm)