Moin! Frage vorweg: wie heisst das, was man durch ein #define definiert? Frage hinterher: ich habe am Atmega einen Demux angeschlossen, der 3 Adress-Eingänge besitzt, welche an den Atmega-Ports hängen. A0 A1 A2 Y 0 0 0 0 1 0 0 1 0 1 0 2 1 1 0 3 0 0 1 4 Nun möchte ich gern durch ein einfaches #define dmux_input_(0-4) machen, dass die entsprechende Bitmaske gesetzt wird. Ich kenne aber nur Maskierungen, bei denen gleichzeitig ein oder mehrere Bits gesetzt (bzw. gelöscht) werden, nicht aber gesetzt UND gelöscht. Wie tut Mann das?
Stephan R. schrieb: > ... bei denen gleichzeitig ein oder mehrere Bits gesetzt (bzw. gelöscht) ... Dann mach das doch: #define SET_MUX(x) do { PORTX=(PORTX & ~0x07)|(x) } while (0) und falls es ohne klammer gehen soll: #define SET_MUX_1 SET_MUX(1) Stephan R. schrieb: > Frage vorweg: wie heisst das, was man durch ein #define definiert? "Makro". ist eine reine Text-Ersetzung, die noch VOR dem Kompilieren ausgeführt wird.
Dacht ich auch zuerst, aber der restliche Port wird auch verwendet, es dürfen also nur PORTC0 bis PORTC3 verändert werden.
Stephan R. schrieb: > Dacht ich auch zuerst, aber der restliche Port wird auch verwendet, es > dürfen also nur PORTC0 bis PORTC3 verändert werden. Genau das macht das Makro doch. Zuerst wird 0x07 invertiert, ergibt eine Bitmaske 0b11111000. der PORTC-Zustand wird damit ver-UND-et, d.H. alle bits bis auf die untersten drei bleiben wie sie sind. Danach wird der Makro-Parameter dazu ver-ODER-t, es werden also zusätzlich wieder bits gesetzt. Solange X keine bits anfasst, die es nicht darf, bleibt der Rest von PORTC also unverändert. Wenn du dir selbst nicht traust, kann das Makro das auch erzwingen:
1 | #define SET_MUX(x) do { PORTX=(PORTX & ~0x07)|((x) & 0x07); } while (0)
|
Das ist grad mal harter Tobak für mich! Ich hatte mich (gerade aus dem Bascom-Lager kommend) schön an die PORTC |= (1 << PC2) Schreibweise gewöhnt. Ich verstehe die Funktion der (x)- Klammer nicht. Steht die nur zur Anschauung da oder kann ich die ins Programm übernehmen?
Stephan R. schrieb: > Ich verstehe die Funktion der (x)- Klammer nicht. Steht die nur zur > Anschauung da oder kann ich die ins Programm übernehmen? Das ist ein Parameter. Wenn du im Programm später
1 | SET_MUX(42); |
schreibst, sieht der Compiler:
1 | do { PORTX=(PORTX & ~0x07)|((42) & 0x07); } while (0); |
und macht Das Richtige™
Okay, das leuchtet ein, ist halt ne "normale" Funktion. Braucht die denn auch einen Prototypen? Noch was: mein Compiler (Programmers Notepad) formatiert das Makro nicht farbig wie in deinem Beispiel sondern nur braun. Warum des?
Anscheinend nicht, zumindest klappts auch so! Schönen Dank, darfst Dir ein Bier nehmen!
Stephan R. schrieb: > Okay, das leuchtet ein, ist halt ne "normale" Funktion. Braucht die denn > auch einen Prototypen? Das ist ein Irrtum. Es sieht nur so aus. Lies nochmal, was Ernst B* oben schrieb (Textersatz). Jockel
Stephan R. schrieb: > Okay, das leuchtet ein, ist halt ne "normale" Funktion. Braucht die denn > auch einen Prototypen? Du brauchst ganz, ganz, ganz dringend ein C-Buch. Das anlassbedingte Zusammentragen von Halbwissen in einem Forum funktioniert einfach nicht, wenn man eine Programmiersprache wie C lernen will.
Gibt es einen Grund dafür das Ganze in eine "Schleife" zu packen, warum reicht nicht nur die Zuweisung ?
Verwirrter schrieb: > Gibt es einen Grund dafür das Ganze in eine "Schleife" zu packen, warum > reicht nicht nur die Zuweisung ? in dem Fall würde es ohne das "while"-Konstrukt auch gehen. bei "#define ABC(x) a=(x); b=(x)+2" z.B gäbe es aber ein Problem bei Verwendungen wie: if (a==23) ABC(42); (Textersetzung mal von Hand durchführen, wenn das Problem nicht offensichtlich ist) durch das "do-while"-Konstrukt wird das umgangen. Preprozessor-Makros sind da immer etwas eigen. Anfängern würde ich vorschlagen davon ganz die Finger zu lassen, und normale C-Funktionen zu verwenden. Wenn man die "Verstanden" hat, kann man sich immer noch Makros zur "Optimierung" erlernen.
Stephan R. schrieb: > Noch was: mein Compiler (Programmers Notepad) formatiert das Makro nicht > farbig wie in deinem Beispiel sondern nur braun. Warum des? Das nennt sich Syntax-Highlighting und die Farben sind in jedem Editor entweder anders oder einstellbar...
Karl heinz Buchegger schrieb: > Das anlassbedingte Zusammentragen von Halbwissen Oder auch learning by doing find ich eigentlich ganz praktisch. Was ich nicht brauch, verlern ich gern schnell wieder. Karl heinz Buchegger schrieb: > Du brauchst ganz, ganz, ganz dringend ein C-Buch. Da hinten in der Schublade liegt´s! DUCK UND WEG
Danke mit so etwas hatte ich gerechnet, bei manchen Compilern kann man das auch einfach in geschweifte Klammern { .... } packen. Solche kleineren Blöcke stören dann nicht weiter. Zumindest solange man keine, dadurch lokalen, Variablen anlegt.
(Ex-)Verwirrter schrieb: > Danke mit so etwas hatte ich gerechnet, > bei manchen Compilern kann man das auch einfach in geschweifte Klammern > { .... } packen. Solche kleineren Blöcke stören dann nicht weiter. > Zumindest solange man keine, dadurch lokalen, Variablen anlegt. Nicht immer: ;)
1 | #define TEST(X) do { printf("%d\n",(X)); } while(0)
|
2 | |
3 | if (x) |
4 | TEST(x); |
5 | else
|
6 | TEST(x+x); |
funktioniert,
1 | #define TEST(X) { printf("%d\n",(X)); }
|
2 | |
3 | if (x) |
4 | TEST(x); |
5 | else
|
6 | TEST(x+x); |
Gibt nen Compiler-Fehler:
> »else« ohne vorheriges »if«
Stephan R. schrieb: > Karl heinz Buchegger schrieb: >> Das anlassbedingte Zusammentragen von Halbwissen > > Oder auch learning by doing find ich eigentlich ganz praktisch. Was ich > nicht brauch, verlern ich gern schnell wieder. Dazu musst du es aber erst einmal gelernt haben. Und gerade in C gibt es Unmengen an Fallen und 'Insider-Wissen', ohne das man nicht weit kommt. Und mit Verlaub: So toll ist deine C-Performance nicht. Sie zeigt eigentlich genau das Übliche, was man von einem Foren-Zusammenklauber erwarten würde: Er kann von allem ein bischen was, aber nichts richtig und manchmal einfach nur grundfalsch. Und da red ich noch nicht einmal von den wirklich komplizierten Dingen.
Also in meinem Buch steht, man solle es mit runden Klammern versuchen. #define QUADRAT(x) ((x)*(x))
Das stimmt natürlich- wenn man denn den Anspruch hat, C professionell zu beherrschen. Das Gute für mich daran: ich brauch mir nicht meine Brötchen damit verdienen sondern will nur ein kleines Uböötchen damit auslaufen lassen. Aber in der Aussicht, vielleicht mal in die Programmiererriege "meiner" Firma aufzurutschen, beleg ich nu ein, zwei Semsester lang "Programmieren". Vielleicht kann ich ja noch was lernen...
Ernst: > Wenn du im Programm später > SET_MUX(42); > schreibst, sieht der Compiler: > do { PORTX=(PORTX & ~0x07)|((42) & 0x07); } while (0); > und macht Das Richtige™ Nö, stimmt nicht ganz. er sieht um die 42 keine Klammern, die müsstest (und sollst) Du im Define angeben. Probier mal aus: #define QUAD1(x) (x*x) #define QUAD2(x) ((x)*(x)) das ist zwar auf den ersten Blick das selbe, aber beim Aufruf von z.B. QUAD(6 & 6); kommt für QUAD1 4 heraus und für QUAD2 36, denn der Compiler sieht bei QUAD1 (6 & 6 * 6 & 6) eben keine Klammern und rechnet 6 & (6*6) & 6 , weil & eine kleinere Hierarchiestufe als * hat. Typische C-Falle, auf die in jedem guten C-Buch hingewiesen wird.
schau genau schrieb: > Probier mal aus: > #define QUAD1(x) (x*x) > #define QUAD2(x) ((x)*(x)) > > das ist zwar auf den ersten Blick das selbe, aber beim Aufruf von z.B. > QUAD(6 & 6); .... Genauso bei QUAD( 6 + 1 ); (da ist es vielleicht offensichtlicher und im Kopf leichter zu verfolgen als mit einem binären und) Beliebt sind auch i = 7; j = QUAD( i++ ) (welchen Wert hat i nach der Operation und was ist das Ergebnis? Ist die Operation überhaupt definiert? Wenn ja: warum? Wenn nein: warum nicht?) > Typische C-Falle, auf die in jedem guten C-Buch hingewiesen wird. Ganz genau Dazu muss man aber erst einmal verinnerlicht haben, dass Makros einfach nur Textersetzung machen und nicht mehr. Aber auch das steht im besagten Buch. Zusammen mit ein paar Beispielen, die zeigen wie sich das auswirkt und was da im Präprozessor wirklich passiert.
Stephan R. schrieb: > Das stimmt natürlich- wenn man denn den Anspruch hat, C professionell zu > beherrschen. Eben nicht Ohne einen gewissen Grundstock kannst du auch als Amateur nicht sinnvoll programmieren. Von dem was dir jetzt kompliziert vorkommt, bis zu dem, was von einem Profi selbstverständlich erwartet und verlangt wird, ist noch ein weiter, weiter Weg. Da passt noch viel dazwischen. Egal ob du Amateur oder Profi- Radrennfahrer bist, Gleichgewicht halten müssen beide können. Und man kann sich bei einem Sturz nicht darauf rausreden, dass man eben kein Profi sei.
schau genau schrieb: > Ernst: >> Wenn du im Programm später > >> SET_MUX(42); > >> schreibst, sieht der Compiler: > >> do { PORTX=(PORTX & ~0x07)|((42) & 0x07); } while (0); > >> und macht Das Richtige™ > > > Nö, stimmt nicht ganz. er sieht um die 42 keine Klammern, die müsstest > (und sollst) Du im Define angeben. in dem Satz fehlt das "und hast" ... mein #define hat die extra-Klammerung um das "x", also selber "genau schau"en ;)
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.