[Technique]Adressage C avec Xlib

dmo95

Membre actif
24 Mai 2007
584
14
Bonjour,

Voilà je me pose une question qui remet en cause les fondement même de l'allocation mémoire en C, ceci étant je ne suis pas un expert, et il est vraisemblable que quelque chose m'échappe.

Je débute en développement C avec l'utilisation de la Xlib. Un petit exercice en TP était de filtrer les événements clavier et de récupérer les keysym/keycode pour comprendre le fonctionnement. Après quelques test/recherche sur le net j'ai réussi à faire fonctionner un code qui me semble mysterieux mais somme toute très basique.

Voici mon code, je vous passe la structure habituelle d'un programme Xlib :
Bloc de code:
KeySym touche;
for(;;){
        XEvent ev;
        char mot[25];
        int nbre;
        
        XNextEvent(dpy, &ev);          //Attrape l'evenement
        
        switch(ev.type) {                  //Condition sur l'evenement
            case KeyPress        : {
                nbre = XLookupString(&ev, mot, sizeof(mot), &touche, 0); //Saisie du KeySym
                
                if(touche==XK_Return) {
                    printf("Touche Return\n");
                }
                else if(touche==XK_space) printf("Touche Space\n"); 
                else {
                    printf("Touche %s\n", &touche);
                }
            }
            break;
        }

Ce programme que fait-il ?

Il traite l'événement clavier et affiche dans la console "Touche a" si la saisie faite a été le caractère "a"... "Touche Space" dans le cas de la saisie sur l'espace et "Touche Return" pour le retour chariot.

Mais quelque chose cloche (ou pas ?!?!?), en effet le professeur souhaitait juste un comportement simplifié qui afficherait le keysym en remplacant l'instruction du dernier else par :
Bloc de code:
 printf("Touche %d\n", touche);

Sachant que touche est de type KeySym mais correspond en realité a un entier lorsque l'on consulte X11/keysym.h.

Mon idée étant que si l'on remplace donc touche par &touche, alors le programme va aller chercher dans la mémoire à l'emplacement qui correspond à la valeur du KeySym, par ailleurs une correspondance du KeySym et de la table ASCII a probablement été faite... d'ou ce comportement.

Mais selon mon prof l'adressage d'une variable de type KeySym ne peut afficher un caractère, du moins selon ces connaissances puisque cela se produit bien !!

Quelqu'un serait il en mesure de m'expliquer le pourquoi du comment, ou tout simplement d'affirmer ma proposition, en le justifiant pour pouvoir m'eclaircir un peu et ainsi que je puisse argumenter mon explication par la suite.

Merci ;)
 

Didier Guillion

Membre expert
Club MacG
20 Juillet 2001
3 244
164
59
Toulouse
www.myriad-online.com
Bonjour,

Je ne connait pas XLib, mais a mon avis le programme que tu propose n'est pas correct.
Si KeySym est un entier, il doit "ruser" en considérant que l'entier est codé sur deux octets, poids faible, poids fort, et que la valeur tient sur un seul octet.
Le deuxieme octet est donc a zéro, on obtient donc le couple ASCII+/000 qui peut s'afficher comme une chaine de caractere par transtypage de l'entier en chaine.

Ce genre d'horreur mérite le détour. Pour l'éviter.

Utilise simplement

printf("Touche %c\n", touche);

Cordialement
 

dmo95

Membre actif
24 Mai 2007
584
14
Effectivement tu as raison le KeySym est codé sur deux octets puisque les plus grande valeurs sont de l'ordre de 0xff40. Puis ta proposition fonctionne tout aussi bien !! Mais...

Si j'ai bien compris, l'utilisation de %s (pour les string) prend en compte les deux octets, mais lorsque je fais l'adresse de ma variable, il comprend qu'il y a que les bits de poid fort qui sont réellement utilisés.

En revanche le %c (caractère -> un octet), prend uniquement les 8 premiers bits et affiche le caractère, grâce au transtypage de l'entier en caractère.

Je suis encore un peu confus, et je ne serais pas bien expliquer la situation... mais c'est déjà une avancée !

Merci ;)
 

Didier Guillion

Membre expert
Club MacG
20 Juillet 2001
3 244
164
59
Toulouse
www.myriad-online.com
En C les chaines sont codées sous forme de valeurs de 1à 255, la valeur 0 indique une fin de chaine.

Les variables de type short sont codées sur deux octets, en mémoire on peut avoir des valeurs de 0x0000 à 0xFFFF.

Dans ton exemple, tu a simplement eut de la chance que le processeur de ton ordinateur code Poids Faible puis Poids Fort.

Un appui sur la touche espace va donner 32 (0x20) et va etre mémorisé par 0x2000.

Demander d'afficher ceci par %s va afficher l'espace, puis trouver le zero et s'arreter, mais c'est uniquement un coup de bol.

Je te conseille de bien comprendre la différence entre "ce qui pointe" et "ce qui est pointé par...", la différence entre variable et adresse de variable, ce sont des notions essentielles.

Cordialement