champs de bits, need help

champs de bits, need help - C - Programmation

Marsh Posté le 12-12-2003 à 19:09:21    

salut.
 
toujours plongé dans mon bouquin sur le langage C, je suis vraiment bloqué sur le chapitre concernant les champs de bit.
j'ai essayé un petit programme, et je ne comprend vraiment pas ce qui cloche, quelqu'un pourrait il m'expliquer?
 

Code :
  1. int N_BITS_JOURS = 5; //constantes definissants la taille en bits des valeurs jour, mois, année
  2. int N_BITS_MOIS = 4;
  3. int N_BITS_ANNEE = 23;
  4. // 5+4+23 = 32bits soit un int
  5. //definission de mon champ de bits
  6. struct anniversaire{
  7.        int jour : N_BITS_JOURS;
  8.        int mois : N_BITS_MOIS;
  9.        int annee : N_BITS_ANNEE;
  10.        };


 
 
lorsque je compile mon code (l'encadré ci dessus n'est qu'une partie du code biensur) j'obtiens les erreurs suivant, et la vraiment je pige pas ce qui cloche  :??: :

41 main.c
 bit-field `jour' width not an integer constant


pourtant ma constante N_BITS_JOURS est bien un integer  :??:  
 
voila pour ce qui etait de ma principale question je vais créé un autre post pour une autre question bien distincte et relative a tout ca.

Reply

Marsh Posté le 12-12-2003 à 19:09:21   

Reply

Marsh Posté le 12-12-2003 à 19:10:45    

j'imagine que le pb vient que c'est une variable et non un litteral

Reply

Marsh Posté le 12-12-2003 à 19:13:09    

Code :
  1. enum
  2.   {
  3.     N_BITS_JOURS = 5,
  4.     N_BITS_MOIS = 4,
  5.     N_BITS_ANNEE = 23
  6.   };
  7. struct anniversaire
  8. {
  9.   int jour : N_BITS_JOURS;
  10.   int mois : N_BITS_MOIS;
  11.   int annee : N_BITS_ANNEE;
  12. };

tadam [:kadreg]


Message édité par Taz le 12-12-2003 à 19:13:23
Reply

Marsh Posté le 12-12-2003 à 19:17:29    

voici ma deuxieme question, car mon livre ne donne aucun detail a ce sujet:
 
comment faire une entrée sur un bit du type scanf()?
 
 
j'ai mon idée la dessus, mais je ne peux pas la verifier a cause de mon probleme decrit dans le post ci dessus.
 
supposont que mon champ de bits "anniversaire" commence a l'adresse 1000
 
si je veux que l'utilisateur saisisse l'année je dois ecrire ceci :
 

Code :
  1. scanf("%7d",(&emplist[iX].anniv.annee+N_BITS_JOURS+N_BITS_MOIS) );


 
j'ai bon la ou je suis a l'ouest?
 
une fois de plus merci pour votre precieuse aide  :)


Message édité par giova le 12-12-2003 à 19:18:19
Reply

Marsh Posté le 12-12-2003 à 19:19:35    

heink ? ça n'est pas possible d'obtenir l'adresse d'un champ de bits. passe par des variable intermédaire

Reply

Marsh Posté le 12-12-2003 à 19:19:58    

ah je n'en suis pas encore au chapitre des enums.
 
les enums sont des constantes?
 
(dsl d'etre saoulant avec toutes mes questions de debutants :) )


Message édité par giova le 12-12-2003 à 19:21:13
Reply

Marsh Posté le 12-12-2003 à 19:24:42    

Code :
  1. int main()
  2. {
  3.   struct anniversaire b = {30, 4, 1983};
  4.   struct anniversaire a;
  5.   int j=0, m=0, y=0;
  6.   scanf("%d %d %d", &j, &m, &y);
  7.   a.jour = j;
  8.   a.mois = m;
  9.   a.annee = y;
  10.   printf("%d %d %d\n", a.jour, a.mois, a.annee);
  11.   printf("%d %d %d\n", b.jour, b.mois, b.annee);
  12.   return 0;
  13. }

Reply

Marsh Posté le 12-12-2003 à 19:24:58    

oui
et passe en unsigned


Message édité par Taz le 12-12-2003 à 19:26:03
Reply

Marsh Posté le 12-12-2003 à 19:32:36    

merci beaucoup taz c'est vraiment sympa.
merci aussi pour ton petit exemple, c'est justement ce que j'allais tenter apres avoir vu ta réponse

heink ? ça n'est pas possible d'obtenir l'adresse d'un champ de bits. passe par des variable intermédaire


 
c'est dommage que l'on ne puisse pas acceder a l'adresse d'un champ de bits :/

Reply

Marsh Posté le 12-12-2003 à 19:40:33    

c'est pas dommage, c'est normal. en C, le « byte » != octet != byte, est la plus petite unité adressable. sizeof(char)==1 par définition. toutes les variables qui sont adressables doivent être avoir une taille multiple de sizeof(char). C'est partout pareil en informatique. Nos mémoires sont mesurées en octets parce que c'est généralement la plus petite unité adressable sur le système considéré.
 
par contre fait une jolie fonction pour bien vérifier la saisie
 

Code :
  1. int CreerAnniversaire(struct anniversaire *a, unsigned d, unsigned m, unsigned y)
  2. {
  3.   if((d & ((1 << N_BITS_JOURS)-1))  != d)
  4.     {
  5.       return 0;
  6.     }
  7.   a->jour = d;
  8.   if((m & ((1 << N_BITS_MOIS)-1))  != m)
  9.     {
  10.       return 0;
  11.     }
  12.   a->mois = m;
  13.   if((y & ((1 << N_BITS_ANNEE)-1))  != y)
  14.     {
  15.       return 0;
  16.     }
  17.   a->annee = y;
  18.   return 1;
  19. }

si je ne me vautre pas sur les champs de bits et les masques

Reply

Marsh Posté le 12-12-2003 à 19:40:33   

Reply

Marsh Posté le 12-12-2003 à 20:50:26    

ok donc si je comprends bien, malgres que les adresses s'expriment en bits, les pointeurs ne peuvent pointer que sur des octets.

Reply

Marsh Posté le 12-12-2003 à 20:51:43    

giova a écrit :

ok donc si je comprends bien, malgres que les adresses s'expriment en bits, les pointeurs ne peuvent pointer que sur des octets.


faux, une adresse s'exprime en octet

Reply

Marsh Posté le 12-12-2003 à 20:58:10    

ok ceci explique cela merci les gars pour votre tolerance a mon ignorance ;)

Reply

Marsh Posté le 12-12-2003 à 23:37:21    

je passe un peu a du hors sujet mais vu que taz en a parler...
 
je viens de finir le chapitre sur les enums (qui fait 5 pages), et en faisant des essais je suis tombé sur une erreure.
 
 Je cherche a afficher la partie literrale d'une variable enum. J'ai pensé que l'on pouvait faire ca :
 

Code :
  1. enum listemois{
  2. Jan = 1,
  3. Fev,
  4. Mars,
  5. Avril,
  6. Mai,
  7. Juin,
  8. Juil,
  9. Aout,
  10. Sept,
  11. Oct,
  12. Nov,
  13. Dec}eMois;
  14. main()
  15. {
  16.   eMois = 2;
  17.   printf("%s",eMois);
  18. }


 
Mais ca me fait planté le programme (un access violation apparemment)
 
quelqu'un pourrait il me dire en gros pourquoi on ne peut pas, et quelle est la methode? :jap:  
 
si la réponse est : "on ne peut pas le faire", alors je ne vois pas pour le moment l'interet d'utiliser un enum sauf pour rendre le code plus lisible, mais au rique d'augmenter nos chances d'inclure des erreurs du type:  

Code :
  1. if(eMois =="jan" )


au lieu de:
 

Code :
  1. if(eMois=="Jan" )


 

Reply

Marsh Posté le 13-12-2003 à 00:20:42    

chrisbk a écrit :


faux, une adresse s'exprime en octet
 

en « byte »

Reply

Marsh Posté le 13-12-2003 à 00:21:52    

1) les enum sont de type entiers
2) ou t'as vu ce genre de comparaision
3) void main() ou int main(à

Reply

Marsh Posté le 13-12-2003 à 01:01:28    

pas de PB pour moi de savoir ce qu'est un bit et un byte (ou octet en FR) :)
 
1) oui en effet c'est ce que j'ai pu lire
2)oups dsl je me suis planté, il n'y a pas de double quote ce ne sont donc pas des strings mais des constantes enum (enfin si je ne suis pas encore ne fois a l'ouest)
3)je n'ai pas encore attaqué le chapitre des fonctions meme si j'en ai fait en java.
 
pour l'instant je crée (comme ds le livre)tous mes main() sans rien preciser devant. Donc je ne sais pas si implicitement c'est du void ou du int, je suppose du void car je ne retourne rien.
 
Du coup je me demande maintenant si on peut par rapport a mon enum de type "listemois", retourner via une fonction un string dont la valeur est le nom du champ ayant la valeur 1 (dans mon cas "Jan" ) :??:

Reply

Marsh Posté le 13-12-2003 à 01:06:01    

il n'y a pas d'implicite en C moderne
 
utlise des enum, qui à faire un tableau contenant les noms des mois

Reply

Marsh Posté le 13-12-2003 à 02:18:48    

les champs de bits, c'est très bien, certes, mais à moins d'être vraiment pressé par la place, un bon agencement de char, short et int (tout en unsigned) est plus efficace et sans limitations.
dans ton cas, t'arrive à faire tout tenir sur 32bits <=> sizeof(int) sur la majorité de nos sytèmes, c'est sans doute l'effet rechercher, et c'est un bon exemple d'utilisation (/3 par rapport à 3 unsigned)

Reply

Marsh Posté le 13-12-2003 à 11:23:03    

tout a fait d'ac avec toi, vu la taille des int (32bits) pour gagner de la place, on a polu vite fait d'utiliser des char ;)
surtout qu'a la lecture ecriture c'est un peu plus simple d'acces (beaucoup plus simple si le champs est une union).
 
enfin moi c'est ce que j'en ai retenu, ct un des chapitres du livre que je me devait de maitriser comme les autres.
 
bon par contre pour les enum j'ai pas tout compris, c'est un peu flou dans mon esprit, j'ai du mal a comprendre l'interret des enum (a part le fait que ce sont des constantes int).
 
Malheureusement le temps me presse, je me donne jusqu'a ce soir pour continuer a apprendre des choses, demain je revise tout ce que j'ai appris cette semaine. Et lundi je pleurs :'(

Reply

Marsh Posté le 13-12-2003 à 11:30:12    

ben les enum, l'intéret de pouvoir définir des constantes entières est énorme ! en fait on sert en majorité quand on veut quand on manipule des valeurs qualitatives, c'est à dire qui dont le nombre de valeurs est fixe et fini. Ex: jour de la semaine, {vert, orange, rouge}, etc. C'est utile, parce qu'au lieu d'avoir des chaînes pour représenter cela (auquel cas tu dois faire des vérifications, car tu n'es pas à l'erreur d'un pauvre frappe), tu as une vérification de valeur et de type à la compilation (évidemment en C ça veut pas dire forcément grand chose)

Reply

Marsh Posté le 13-12-2003 à 12:32:42    

ok je vois.
En fait la ou je bloque c'est en m'imaginant une solution a ca :
tu as une machine qui retourne sur 16bits son etat:
1000 => idle;
4500 => buzy;
etc...
imaginons qu'il y ait une centaine d'etats pas forcement a des valeurs successives (donc pas ideal pour un tableau ou il faudrait par rapport a mon exemple avoir 4500 index, alors qu'il n'y a que 100 etats utiles).
imaginons que l'on veuillent afficher sur l'interface utilisateur l'etat en language humain et donc litteral (buzy, IDLE, recording, etc...)
on peut donc alors imaginer un :

Code :
  1. enum state{
  2. IDLE = 1000,
  3. BUZY = 4500,
  4. RECORDING = 4700,
  5. etc...}machine1 ;


mais comment afficher BUZY, RFECORDING, etc...
avec un switch? ou peut on afficher le nom des constantes de l'enum?
ou il y a t'il une meilleur solution?

Reply

Marsh Posté le 13-12-2003 à 12:34:01    

ton enum est OK;
pour l'affichage, ben tu fais une fonction qui permet d'associer une valeur à ce que tu veux, le cas échéant une chaine de caractère.

Reply

Marsh Posté le 13-12-2003 à 12:38:00    

donc une fonction avec switch qui prend un integer et qui retourne un string?

Reply

Marsh Posté le 13-12-2003 à 12:39:44    

oui, par exemple

Reply

Marsh Posté le 13-12-2003 à 12:42:37    

ok merci.
au fait t'es toujours sur le forum, t'es relié par une perfusion USB ou ils t'ont développé en meme temps qu'ils ont developpé ce forum? :)

Reply

Marsh Posté le 13-12-2003 à 12:44:51    

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

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