Forum: Compiler & IDEs C - Hochzählen von defines


von C-user (Gast)


Lesenswert?

Guten Tag.

Eine kurze Frage zu C:


Ich binde eine externe Bibliothek in meinen Code ein, die mir Defines 
liefert wie:
1
#define MUX0   ((0<<MUX4) | (0<<MUX3) | (0<<MUX2) | (0<<MUX1) | (0<<MUX0))
2
#define MUX1   ((0<<MUX4) | (0<<MUX3) | (0<<MUX2) | (0<<MUX1) | (1<<MUX0))
3
#define MUX2   ((0<<MUX4) | (0<<MUX3) | (0<<MUX2) | (1<<MUX1) | (0<<MUX0))
4
...

Ich selber habe eine Zeitschleife, die jede 100µs aufgerufen wird.
In dieser wird eine Funktion aufgerufen, der ich je nach Zählerstand die 
obigen Defines weitergeben möchte. Gibt es eine schönere Möglichkeit das 
ganze zu programmieren wie diese?:
1
static uint8_t Cnt = 0;
2
3
if(Cnt == 0)
4
  func (MUX0);
5
if(Cnt == 1)
6
  func (MUX1);
7
if(Cnt == 2)
8
  func (MUX2);
9
...
10
11
Cnt++;

Man könnte natürlich auch func(0b00000), func(0b00001),...  schreiben, 
aber
ich würde schon gerne die defines aus der lib übernehmen.
Gibts da Möglichkeiten in C?

Ich danke im voraus! :)

von Marcel (Gast)


Lesenswert?

Schieb die Dinger doch in ein Array.

von Peter II (Gast)


Lesenswert?

C-user schrieb:
> Man könnte natürlich auch func(0b00000), func(0b00001),...  schreiben,
> aber

oder noch besser
1
func (cnt);



> ich würde schon gerne die defines aus der lib übernehmen.
> Gibts da Möglichkeiten in C?
mit den defines nicht.

von chris (Gast)


Lesenswert?

Ich finde die Macros cool, richtige obfuscations nett geschrieben, muss
ich mir merken. Was bzw wie ist MUX1, MUX0 usw definiert ?

#define MUX0   ((0<<MUX4) | (0<<MUX3) | (0<<MUX2) | (0<<MUX1) | 
(0<<MUX0))
#define MUX1   ((0<<MUX4) | (0<<MUX3) | (0<<MUX2) | (0<<MUX1) | 
(1<<MUX0))
#define MUX2   ((0<<MUX4) | (0<<MUX3) | (0<<MUX2) | (1<<MUX1) | 
(0<<MUX0))
...

Diese Macros rufen sich alle irgendwie gegenseitig auf und die 
eigentliche
Definition von MUX0, MUX1, MUX2 nach der Macroexpansion ist irgendwo 
anders.

Kannst du bitte mal mehr posten, mich wuerde dies echt interessieren.

von Oliver (Gast)


Lesenswert?

chris schrieb:
> Diese Macros rufen sich alle irgendwie gegenseitig auf und die
> eigentliche
> Definition von MUX0, MUX1, MUX2 nach der Macroexpansion ist irgendwo
> anders.

Glaub ich nicht. Das wurde schlicht vom TO falsch abgeschrieben.

Oliver

von Decius (Gast)


Lesenswert?

1
#define MUX0   ((0<<MUX4) | (0<<MUX3) | (0<<MUX2) | (0<<MUX1) | (0<<MUX0))
2
#define MUX1   ((0<<MUX4) | (0<<MUX3) | (0<<MUX2) | (0<<MUX1) | (1<<MUX0))
3
#define MUX2   ((0<<MUX4) | (0<<MUX3) | (0<<MUX2) | (1<<MUX1) | (0<<MUX0))
4
5
uint8_t daten[MUX2] = {MUX0,MUX1,MUX2};
6
7
void func(uint8_t value)
8
{
9
    //irgendwas
10
}
11
12
int main (void)
13
{
14
    uint8_t i;
15
16
    for(i=MUX0; i<MUX2; i++)
17
    {
18
        func(daten[i]);
19
    }
20
}

Wenn du denn die Defines benutzen möchtest. Allerdings stehen MUX0 
....MUX2 auch nur für die binären Werte 0...2. Liesse sich also alles 
einfacherer schreiben.
1
int main (void)
2
{
3
    uint8_t i;
4
5
    for(i=0; i<2; i++)
6
    {
7
        func(i);
8
    }
9
}

von Decius (Gast)


Lesenswert?

@chris
1
#define MUX0   ((0<<MUX4) | (0<<MUX3) | (0<<MUX2) | (0<<MUX1) | (0<<MUX0))
2
#define MUX1   ((0<<MUX4) | (0<<MUX3) | (0<<MUX2) | (0<<MUX1) | (1<<MUX0))
3
#define MUX2   ((0<<MUX4) | (0<<MUX3) | (0<<MUX2) | (1<<MUX1) | (0<<MUX0))

Zu  Defines. In der ersten Zeile sind MUX0 bis MUX4 nicht definiert. 
Nicht definierte Defines stehen für den Wert 0 --> MUX0=0.

In der Zweite ist nur MUX0 definiert. Für die anderen Defines gilt das 
im vorigen Abschnittgesagte. Allerdings ist MUX0 it 0 definiert --> 
MUX1=1

In der dritten Zeile sind nur MUX0=0 und MUX1=1 defniert. --> MUX2=2

und so weiter.

von Decius (Gast)


Lesenswert?

sorry ein fehler
1
#define MUX0   ((0<<MUX4) | (0<<MUX3) | (0<<MUX2) | (0<<MUX1) | (0<<MUX0))
2
#define MUX1   ((0<<MUX4) | (0<<MUX3) | (0<<MUX2) | (0<<MUX1) | (1<<MUX0))
3
#define MUX2   ((0<<MUX4) | (0<<MUX3) | (0<<MUX2) | (1<<MUX1) | (0<<MUX0))
4
5
uint8_t daten[MUX2+1] = {MUX0,MUX1,MUX2};

von Decius (Gast)


Lesenswert?

jedenfalls liessen sich diese 3 Zeilen so mit dem Keil Comppiler 
übersetzen.
1
#define MUX0   ((0<<MUX4) | (0<<MUX3) | (0<<MUX2) | (0<<MUX1) | (0<<MUX0))
2
#define MUX1   ((0<<MUX4) | (0<<MUX3) | (0<<MUX2) | (0<<MUX1) | (1<<MUX0))
3
#define MUX2   ((0<<MUX4) | (0<<MUX3) | (0<<MUX2) | (1<<MUX1) | (0<<MUX0))

von C-user (Gast)


Lesenswert?

Marcel schrieb:
> Schieb die Dinger doch in ein Array.

Hmmm. Ist zwar nicht zufriedenstellend, aber ist wohl der einzige 
Ausweg.

Oliver schrieb:
>> Diese Macros rufen sich alle irgendwie gegenseitig auf und die
>> eigentliche
>> Definition von MUX0, MUX1, MUX2 nach der Macroexpansion ist irgendwo
>> anders.
>
> Glaub ich nicht. Das wurde schlicht vom TO falsch abgeschrieben.

Oliver hat recht. Ich habe einfach falsch abgeschrieben.



Hier also nochmals in Reinform der Code:
1
#define MUX0    0
2
#define MUX1    1
3
#define MUX2    2
4
...
5
#define MUX_0   ((1<<MUX4) | (0<<MUX3) | (0<<MUX2) | (0<<MUX1) | (0<<MUX0))
6
#define MUX_1   ((0<<MUX4) | (1<<MUX3) | (0<<MUX2) | (1<<MUX1) | (1<<MUX0))
7
#define MUX_2   ((0<<MUX4) | (1<<MUX3) | (0<<MUX2) | (1<<MUX1) | (0<<MUX0))
8
...

Bitte beachten, dass MUX_0, MUX_1, MUX_2... nicht einfach mit 0,1,2... 
hochgezählt werden!!

Übrigens:
Es geht mir im Grunde auch nicht um eine Lösung für diese konkreten 
Defines hier, sondern allgemein für alle Defines. Ich bin schon öfters
vor dem Problem gestanden, dass ich paar defines hoch-/runterzählen 
musste.


Die einzige Lösung, die ich bis jetzt für möglich halte ist:
1
array[0] = MUX_0;
2
array[1] = MUX_1;
3
array[2] = MUX_2;
4
...
Oder habe ich noch eine Möglichkeit übersehen?

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Decius schrieb:
> Nicht definierte Defines stehen für den Wert 0

Nur im Präprozessor, also wenn sie innerhalb eines #if auftauchen.

Für den C-Compiler werden die nicht als Makros definierten Namen dann
1:1 als Text durchgereicht.

von Quack (Gast)


Lesenswert?

Decius schrieb:
> uint8_t daten[MUX2] = ...;

Welchen Wert hat denn deiner Meinung nach MUX2 hier?

von Decius (Gast)


Lesenswert?

Ist aber komisch das der Keil Compiler die Defines ohne die vorherige 
definition von MUX0, MUX1 und MUX2 akzeptiert. Eigentlich hatte ich da 
eine Fehlermeldung erwartet.

von Decius (Gast)


Lesenswert?

aufpassen das war der erste Post. MUX2=2 und das ist um eines zu klein

von Decius (Gast)


Lesenswert?

Ahh ok. Jetzt klärt es sich. Die erwarteten Fehlermeldungen kommen, wenn 
man versucht die Defines ohne die vorherige definition von MUX0, MUX1 
und MUX2 zu benutzen. Hätte mich jetzt auch echt gewundert. unhd stimmt 
an die Variantge das die Defines zunächst nur als Text interpretiert 
werden hab ich nicht gleich gedacht.

von chris (Gast)


Lesenswert?

Du kònntest hier auch , in diesem fiktiven Beispiel func(0),func(1); 
schreiben. In diesem Beispiel, wenn man auch nur eine kleine aenderung
macht an den Schiebeoperationen hat, durch die rekursive Einbindung
hat man dann einen defierte Initialisierung oder pseudo pnr.
Wenn ein Teil mit sowas arbeitet, und ein Teil mit defines, dann ist in
der Tat der Flow des Programmes nicht leicht nachzuvollziehen, speziell
wenn Variablen damit initialisiert werden und die Konstanten in 
FOR/While/IF verwendet werden. Der Compiler optimiert das alles 
automatisch weg, auch den Code mit eventuellen Decription Algorithm, 
welcher dann eigentlich nicht mal reinkompiliert wird und der 
eigentliche Key und
Algorithmus ist nur schwer rauszubekommen.


# 1 "x.c"
1
typedef unsigned char uint8_t;
2
enum
3
{ MUX0 = 9, MUX1 = 4, MUX2 = 5, MUX3 = 2, MUX4 = 12 };
4
5
6
7
8
9
uint8_t
10
  daten[((0 << MUX4) | (0 << MUX3) | (0 << MUX2) |
11
   (1 <<
12
    ((0 << MUX4) | (0 << MUX3) | (0 << MUX2) | (0 << MUX1) |
13
     (1 <<
14
      ((0 << MUX4) | (0 << MUX3) | (0 << MUX2) | (0 << MUX1) |
15
       (0 << MUX0))))) | (0 << ((0 << MUX4) | (0 << MUX3) | (0 << MUX2)
16
              | (0 <<
17
           ((0 << MUX4) | (0 << MUX3) |
18
            (0 << MUX2) | (0 << MUX1) | (1 <<
19
                       MUX0)))
20
              | (0 << MUX0)))) + 1] =
21
  { ((0 << MUX4) | (0 << MUX3) |
22
     (0 <<
23
      ((0 << MUX4) | (0 << MUX3) | (0 << MUX2) |
24
       (1 <<
25
  ((0 << MUX4) | (0 << MUX3) | (0 << MUX2) | (0 << MUX1) | (1 << MUX0)))
26
       | (0 << MUX0))) | (0 << ((0 << MUX4) | (0 << MUX3) | (0 <<
27
                   ((0 << MUX4) |
28
                    (0 << MUX3) | (0
29
                       <<
30
                       MUX2)
31
                    | (1 << MUX1) |
32
                    (0 << MUX0))) |
33
        (0 << MUX1) | (1 << MUX0))) | (0 << MUX0)),
34
((0 << MUX4) | (0 << MUX3) |
35
(0 <<
36
((0 << MUX4) | (0 << MUX3) | (0 << MUX2) | (1 << MUX1) |
37
(0 << ((0 << MUX4) | (0 << MUX3) | (0 << MUX2) | (0 << MUX1) | (0 << MUX0))))) | (0
38
                     << MUX1) | (1 << ((0 << MUX4) | (0 << MUX3) | (0 << ((0 << MUX4) | (0 << MUX3) | (0 << MUX2) | (1 << MUX1) | (0 << MUX0))) | (0 << MUX1) | (0 << MUX0)))), ((0 << MUX4) | (0 << MUX3) | (0 << MUX2) | (1 << ((0 << MUX4) | (0 << MUX3) | (0 << MUX2) | (0 << MUX1) | (1 << ((0 << MUX4) | (0 << MUX3) | (0 << MUX2) | (0 << MUX1) | (0 << MUX0))))) | (0 << ((0 << MUX4) | (0 << MUX3) | (0 << MUX2) | (0 << ((0 << MUX4) | (0 << MUX3) | (0 << MUX2) | (0 << MUX1) | (1 << MUX0))) | (0 << MUX0)))) };
39
40
41
void
42
func (uint8_t value)
43
{
44
  printf (" called with %d\n", value);
45
46
}
47
48
int
49
main (void)
50
{
51
  uint8_t i;
52
53
  for (i =
54
       ((0 << MUX4) | (0 << MUX3) |
55
  (0 <<
56
   ((0 << MUX4) | (0 << MUX3) | (0 << MUX2) |
57
    (1 <<
58
     ((0 << MUX4) | (0 << MUX3) | (0 << MUX2) | (0 << MUX1) |
59
      (1 << MUX0))) | (0 << MUX0))) | (0 << ((0 << MUX4) | (0 << MUX3) |
60
               (0 <<
61
                ((0 << MUX4) | (0 << MUX3)
62
                 | (0 << MUX2) | (1 <<
63
                      MUX1) |
64
                 (0 << MUX0))) | (0 <<
65
                      MUX1) |
66
               (1 << MUX0))) | (0 <<
67
                    MUX0));
68
       i <
69
       ((0 << MUX4) | (0 << MUX3) | (0 << MUX2) |
70
  (1 <<
71
   ((0 << MUX4) | (0 << MUX3) | (0 << MUX2) | (0 << MUX1) |
72
    (1 <<
73
     ((0 << MUX4) | (0 << MUX3) | (0 << MUX2) | (0 << MUX1) |
74
      (0 << MUX0))))) | (0 << ((0 << MUX4) | (0 << MUX3) | (0 << MUX2) |
75
             (0 <<
76
              ((0 << MUX4) | (0 << MUX3) | (0 << MUX2)
77
               | (0 << MUX1) | (1 << MUX0))) | (0 <<
78
                  MUX0))));
79
       i++)
80
    {
81
      func (daten[i]);
82
    }
83
84
  puts ("daten:");
85
  for (i = 0; i < 3; i++)
86
    {
87
      func (daten[i]);
88
    }
89
}

von C-user (Gast)


Lesenswert?

Interessiert noch irgendwen die ursprüngliche Fragestellung? :D

von chris (Gast)


Lesenswert?

Die wurde doch schon geklàrt.
Siehe untenstehenden Code.
Egal welche Werte MUXn hat, es wird neu definiert und abgesehen von
dem blòden Defines werden die neu umdefiniert.
Ein
#define MUX0 0
#define MUX1 1
#define MUX2 2
ist exact dasselbe als der orginale define Code.
Sinn muss/kann diese Neudefinition haben, da offensichtlich MUXn 
irgendwie
schon definiert ist, hier im Codebeispiel als Enum gemacht.
Ich wuerde dir die obige Definition zu Herzen legen, da sie viel 
uebersichtlicher ist, ist aber egal.

Das daten[3] wird auch immer mit { 0,1,2 } initialisert, allerdings die
For Schleife Zaehlt nur von 0 bis 1, da < 2 genommen wurde, kann ein
Tippfehler sein.
Anstelle von

    for(i=MUX0; i<MUX2; i++)
    {
        func(daten[i]);
    }
kannst du auch, bzw warscheinlich besser

    for(i=0; i<2; i++)
    {
        func(daten[i]);
    }
Wenn dies ein Tippfehler war, und es <=2 heissen sollte, dann koennte 
sowas
vorteilhaft sein, bzw wird oefter gemacht um bei Erweiterungen keine 
grossen Codeaenderungen zu haben.

    for(i=0; i<sizeof(daten)/sizeof(daten[0]); i++)
    {
        func(daten[i]);
    }

typedef unsigned char uint8_t;
enum { MUX0=9,MUX1=4,MUX2=5,MUX3=2,MUX4=12 };

#define MUX0   ((0<<MUX4) | (0<<MUX3) | (0<<MUX2) | (0<<MUX1) | 
(0<<MUX0))
#define MUX1   ((0<<MUX4) | (0<<MUX3) | (0<<MUX2) | (0<<MUX1) | 
(1<<MUX0))
#define MUX2   ((0<<MUX4) | (0<<MUX3) | (0<<MUX2) | (1<<MUX1) | 
(0<<MUX0))

uint8_t daten[MUX2+1] = {MUX0,MUX1,MUX2};


void func(uint8_t value)
{
   printf(" called with %d\n",value);
   //irgendwas
}

int main (void)
{
    uint8_t i;

    for(i=MUX0; i<MUX2; i++)
    {
        func(daten[i]);
    }

  puts("daten:");
    for(i=0; i<3; i++)
    {
        func(daten[i]);
    }
}

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.