[c] enum

Pagina: 1
Acties:

  • intrix
  • Registratie: November 2002
  • Laatst online: 04-12-2023
nou had ik een topic geplaatst waarin ik vroeg hoe enum precies werkt

de enige reactie die ik daarop kreeg was 'doe je boek open'

nou sorry maar dit HAD ik al gedaan en ik was er niet uit gekomen

mijn probleem was dat ik voor school een programma moest maken waarin de volgende dingen moesten worden opgenomen:

autonr (gewoon int)
autotype (pb,vw,va,vo,pw)
van (A,B,C,D)
naar (A,B,C,D)

nou heb ik onwijs lopen kloten en doen .. maar dat met enum wilde niet lukken
het was mijn id dat ik daarmee dus gewoon scanf("..",&autotype); kon doen
en vervolgens "pb" kon ingeven en dan ook met printf("..",autotype); dit kon laten afdrukken

mijn problemen was dat ik niet wist welk type ik eigenlijk moest scannen %d / %s (je weet wel) en laten printen

nu heb ik het tijdelijk maar opgelost door gewoon integers te gebruiken

en een global array te maken die er zo uitziet:

type[][2]={"pb","vw","va","vo","pw"};

en als ik dan afdruk welk type het is doe ik dus nu maar
printf("%s",type[autotype]);

volgens mij moet het anders kunnen maar aangezien ik mijn vraag niet goed had uitgeschreven, was het resultaat dat mijn topic is gesloten wegens het feit dat ik zelf "niet in mijn boek had gekeken" nou bij deze mijn excuses hoor _/-\o_ the rules

[ Voor 7% gewijzigd door intrix op 18-01-2003 20:23 ]

welcome my son, welcome to the machine


  • Dash2in1
  • Registratie: November 2001
  • Laatst online: 19-08 23:13
Voorbeeldje met enums, denk dat het genoeg zegt:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
enum day_e {Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday};

typedef enum day_e DayOfWeek;

int main()
{
  DayOfWeek today;

  today = Saturday;

  ...
  ....
  return 0;
}

[ Voor 4% gewijzigd door Dash2in1 op 18-01-2003 20:49 ]


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 16:18

.oisyn

Moderator Devschuur®

Demotivational Speaker

Het probleem is dat je strings niet zero-terminated zijn, waardoor het afdrukken verkeerd gaat. Bovendien is het gebruik van enums wel netter, en die kun je ook gewoon casten van en naar int

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Verwijderd

.oisyn schreef op 18 January 2003 @ 20:52:
Het probleem is dat je strings niet zero-terminated zijn, waardoor het afdrukken verkeerd gaat. Bovendien is het gebruik van enums wel netter, en die kun je ook gewoon casten van en naar int
In C zijn enums gewoon ints, toch (in runtime)?...

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 24-08 23:08
Verwijderd schreef op 18 januari 2003 @ 22:03:
In C zijn enums gewoon ints, toch (in runtime)?...
At run time, EN at compile time. In C++ zijn 't at run time ook ints, maar bij het compileren nog aparte types. (Het zou trouwens nog kunnen dat niet gespecificeerd is wat voor type int 't is.)

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 16:18

.oisyn

Moderator Devschuur®

Demotivational Speaker

Verwijderd schreef op 18 januari 2003 @ 22:03:

In C zijn enums gewoon ints, toch (in runtime)?...


wat het zijn doet er niet echt toe, het gaat erom dat bij gebruik van enums het ten eerste netter programmeren is, en ten tweede fouten eruit kan halen (je hebt immers maar keuze uit een bepaalde set constanten... een andere constante assignen aan een enum variabele levert een compile error op)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 24-08 23:08
.oisyn schreef op 19 January 2003 @ 12:22:
(je hebt immers maar keuze uit een bepaalde set constanten... een andere constante assignen aan een enum variabele levert een compile error op)
Echt niet! Hoe kom je daar bij?

Even verduidelijken: wat betreft het 'netjes en duidelijk programmeren' heb je gelijk. Maar de C compiler doet niets om dat te forceren. De proef op de som:
C:
1
2
3
4
5
6
7
int main()
{
        enum flags { AAP = 1, NOOT = 2, MIES = 4 };
        enum test { EEN=1, TWEE, DRIE };
        enum bla { WOEI = 5 } x = TWEE * NOOT;
        return x;
}

Levert met GCC en -Wall (zoals ik al zei) geen enkele warning op, hoewel het duidelijk NIET netjes is.

[ Voor 46% gewijzigd door Soultaker op 19-01-2003 13:01 ]


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 21-08 17:14
.oisyn schreef op 19 januari 2003 @ 12:22:
wat het zijn doet er niet echt toe, het gaat erom dat bij gebruik van enums het ten eerste netter programmeren is, en ten tweede fouten eruit kan halen (je hebt immers maar keuze uit een bepaalde set constanten... een andere constante assignen aan een enum variabele levert een compile error op)
enum xs { read = 1, write = 2 };

xs file = read|write; /* Legaal, maar geen constante met naam */

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 16:18

.oisyn

Moderator Devschuur®

Demotivational Speaker

Soultaker schreef op 19 January 2003 @ 12:57:
[...]

Echt niet! Hoe kom je daar bij?

Even verduidelijken: wat betreft het 'netjes en duidelijk programmeren' heb je gelijk. Maar de C compiler doet niets om dat te forceren. De proef op de som:
C:
1
2
3
4
5
6
7
int main()
{
        enum flags { AAP = 1, NOOT = 2, MIES = 4 };
        enum test { EEN=1, TWEE, DRIE };
        enum bla { WOEI = 5 } x = TWEE * NOOT;
        return x;
}

Levert met GCC en -Wall (zoals ik al zei) geen enkele warning op, hoewel het duidelijk NIET netjes is.
"ComeauTest.c", line 5: warning: enumerated type mixed with another type
enum bla { WOEI = 5 } x = TWEE * NOOT;
maar goed, het blijkt idd een legale constructie. I stand corrected. Ik was waarschijnlijk in de war met C++, waarin het niet is toegestaan

[ Voor 5% gewijzigd door .oisyn op 19-01-2003 20:39 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

Verwijderd schreef op 18 januari 2003 @ 22:03:
In C zijn enums gewoon ints, toch (in runtime)?...
Niet per definitie, dit is een compiler setting meestal. BCB gebruikt default de setting 'use smallest possible size to represent enum', oftewel een enum met values 0 tot 5 zal als char gecompileerd te worden. In VC bestaat dezelfde setting maar staat ie default andersom.

* curry684 weet dit uit ervaring omdat ie er eens een paar dagen aan kwijt was om te debuggen waarom een BCB-progsel met een VC-dll soms met hele vreemde resultaten op de proppen kwam.

Professionele website nodig?


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 21-08 17:14
.oisyn schreef op 19 januari 2003 @ 20:29:

originele quote:
--------------------------------------------------------------------------------
.oisyn schreef op 19 January 2003 @ 12:22:
(je hebt immers maar keuze uit een bepaalde set constanten... een andere constante assignen aan een enum variabele levert een compile error op)
--------------------------------------------------------------------------------
...
[...]
maar goed, het blijkt idd een legale constructie. I stand corrected. Ik was waarschijnlijk in de war met C++, waarin het niet is toegestaan
Het zit je niet mee, he. Ik denk dat je hier weer een bijna correcte redenatie hebt. C en C++ verschillen op een paar kleine puntjes. TWEE en NOOT in je voorbeeld hebben geen enumerated type in C; het zijn echte 100% ints. In C++ heeft TWEE als type [enum] test, en NOOT heeft als type [enum] bla. De reden is dat C++ overloading heeft, en enums apart overloaden. Daarom is de vermenigvuldiging illegaal in C++.

Maar in beide talen kun je een variabele van enumerated type een waarde geven die niet overeenkomt met een gedefineerde naam. x=6 zou legaal zijn in C en C++

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 24-08 22:38
C++:
1
2
3
4
5
6
7
8
9
10
typedef enum _test { BLAAT1=0,BLAAT2=1,BLAAT3=2 } test;

int main()
{
    test x;

    x=10;

    return BLAAT1;
}


Levert in VC++ 6 dit op:
Compiling...
main.cpp
F:\Projects\Work\Test\main.cpp(276) : error C2440: '=' : cannot convert from 'const int' to 'enum _test'
Conversion to enumeration type requires an explicit cast (static_cast, C-style cast or function-style cast)
Error executing cl.exe.
Zonder explicit cast ( wat dus een bug introduceert ) mag het niet in C++. ( Van VC6 anyway, maar ik ben geneigd te zeggen dat C++ hetzelfde zegt )

[edit]

Je kan kennelijk wel een enum impliciet casten naar een int, aan de retval van main te zien.
De andere kant op ligt iets moeilijker, wat ikzelf wel plausibel vind.

[ Voor 16% gewijzigd door farlane op 20-01-2003 08:51 ]

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Verwijderd

farlane schreef op 20 januari 2003 @ 08:49:
Zonder explicit cast ( wat dus een bug introduceert ) mag het niet in C++. ( Van VC6 anyway, maar ik ben geneigd te zeggen dat C++ hetzelfde zegt )

[edit]

Je kan kennelijk wel een enum impliciet casten naar een int, aan de retval van main te zien.
De andere kant op ligt iets moeilijker, wat ikzelf wel plausibel vind.
Hier zie je dus dat C++ heel anders met enums omgaat dan C. Juist bij enums verschillen de twee talen sterk. In C++ is het zelfs zo dat je ook van enums de operators kunt overloaden, zij worden namelijk beschouwd als "user defined types" in C++.

Dat je in C++ een enum gemakkelijker naar een int kan casten dan andersom, is nogal logisch, aangezien een enum een type is die een integerwaarde kent en dit andersom niet geldt... Hoe je het ook kunt zien: elke enum-waarde moet in een integer kunnen passen, maar andersom kun je dit niet stellen.

[ Voor 16% gewijzigd door Verwijderd op 20-01-2003 13:01 ]


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 16:18

.oisyn

Moderator Devschuur®

Demotivational Speaker

MSalters schreef op 20 januari 2003 @ 08:24:
Maar in beide talen kun je een variabele van enumerated type een waarde geven die niet overeenkomt met een gedefineerde naam. x=6 zou legaal zijn in C en C++


het spijt me zeer, maar het stukje code:

C++:
1
2
3
enum bla { E1, E2 };

bla b = 4;


Compileert zo:

VC++ 7.1:
error C2440: 'initializing' : cannot convert from 'int' to 'bla'
Conversion to enumeration type requires an explicit cast (static_cast, C-style cast or function-style cast)


GCC 3.2:
bla.cpp:3: invalid conversion from `int' to `bla'


Comeau 4.3.0.1:
error: a value of type "int" cannot be used to initialize
an entity of type "bla"
bla b = 5;

Zie ook 7.2.8 van de C++ standaard

En dat van die operator overloading is natuurlijk een beetje een flauwe opmerking

[ Voor 3% gewijzigd door .oisyn op 20-01-2003 11:09 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 16:18

.oisyn

Moderator Devschuur®

Demotivational Speaker

* omhoog *

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 24-08 23:08
Waarom??

en zo help ik je ook nog eens!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 16:18

.oisyn

Moderator Devschuur®

Demotivational Speaker

ik wil weten of ik er naast zit :)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 21-08 17:14
Snelle kick zeg. Ben jij blij dat er geen modjes voorbij kwamen. :)

Maar je hebt gelijk, ik was te lui met typen. Er moet inderdaad een cast in. Dus:
De constante '(enum bla)6' mag je wel assignen aan een variabele van type enum bla, alhoewel het niet uit de "bepaalde set constanten" komt.

Uit 5.19/1, over "integral contant expression"s, volgt dat '(enum bla) 6' een echte constante is, en uit 7.2 blijkt dat variabelen van type 'enum bla' die daarmee geinitialiseerd zijn dus de waarde 6 hebben.

Maar het meest duidelijk is 7.2/6:
For an enumeration where emin is the smallest enumerator and emax is the largest, the values of the enumeration are the values of the underlying type in the range bmin to bmax, where bmin and bmax are, respectively, the smallest and largest values of the smallest bit-field that can store eminand emax . (81) It is possible to define an enumeration that has values not defined by any of its enumerators.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • intrix
  • Registratie: November 2002
  • Laatst online: 04-12-2023
ehm.. maar stel nou ik doe :

enum auto_t {pb, pw, vw, vo, va};

typedef enum auto_t CarType;

int main()
{
CarType Car;

Car = random( * );

wat moet er dan op de plek van de * ?
moet daar dan een getal dus eh (even denk pb = 0 ) dus eh random(4);
of moet daar dan random(va);

ik heb het over C dus gewoon turbo C compilertje

en hoe zorg ik er dan voor dat er tijdens het afdrukken va of pb op het scherm komt
want printf("%s",Car); doet ie echt niet hoor!

welcome my son, welcome to the machine


  • intrix
  • Registratie: November 2002
  • Laatst online: 04-12-2023
ik heb het idee dat enums wel heel mooi zijn enzo maar dat ze alleen intern in je programma lekker werken en niet echt handig als input output zijn of ligt dat aan mij?

welcome my son, welcome to the machine


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

Da's het hele idee ja, extern zijn het gewoon integers.

Ter voorbeeld wat C++:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
void MyCar::Brake()
{
switch(m_CurrentState)
  {
  case e_Stopped:
    // Already standing still, no effect
    break;
  case e_Driving:
    // Lower speed
    m_Speed *= 0.9;
    break;
  case e_Racing:
    // Start skidding, and harder to brake
    Skid(m_Speed);
    m_Speed *= 0.95;
    break;
  case e_Skidding:
    // When braking in a skin procedure the brakes lock up and you rotate
    // Speed does not degrade
    Rotate(m_Speed);
    m_BrakeSystem->Lock();
    break;
  }
}

Dit voorbeeld was veel minder duidelijk geweest als er achter die cases de waardes 0 tot 3 hadden gestaan, wat ze in feite wel zijn. Enums zijn fantastisch voor 'exclusive states' oftewel zoiets als dit (1 state kan tegelijkertijd aanwezig zijn), of 'object properties' zoals MyApplication->RunMode = Console.

Het is ten allen tijde onmogelijk om op runtime te achterhalen wat de text-waarde van een bepaalde enumval is tenzij je daar expliciet faciliteiten voor aanlegt zoals:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
String MyCar::StateAsString(t_CarState p_State)
{
switch(p_State)
  {
  case e_Stopping:
    return "Stopping";
  case e_Driving:
    return "Driving";
  ...
  default:
    return "Unknown state";
  }
}

Professionele website nodig?


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 24-08 22:38
Wat jij wil is een tekstrepresentatie van je enum.

Je kunt daarvoor een const char * enum_desc [] maken die voor alle enum waarden de beschrijving bevatten, en die indexeren met je enum var.

Zoiets:
C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
typedef enum _test
{
    TEST_BOF=-1,
    FIRST = 0,
    SECOND = 1,
    TEST_EOF
} test;

const char * test_desc[] = 
{
    "EERSTE",
    "TWEEDE"
};

void print_test_desc( test val )
{
  if( val > TEST_BOF && val < TEST_EOF )
      printf("%s", test_desc[ val ] );
}


int main()
{
    test x = FIRST;
    print_test_desc( x );
    getchar();  
    return 0;
}

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.

Pagina: 1