www.mikrocontroller.net

Forum: Compiler & IDEs mal wieder eine ansi c frage...


Autor: Marcel... (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hi zusammen,

wie kann ich am einfachsten in einer 8bit variable ein einzelnes bit 
invertieren ohne die anderen bits zu verändern?

gruss und dank,
marcel

Autor: AndreasH (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Meiner Meinung nach müßte es mit Exclusiv-ODer gehen.

                                    BIT  76543210
Beispiel: Du hast in der Variable: 50h = 01010000b
Wenn Du jetzt das Bit6 invertieren willst, dann
exclusiv-oderiert mit 40h=0100000b. Damit ergibt sich für Deine Variable 
10h=00010000b. Das Bit 4 ist unverändert und die Bits, die 0 waren auch.

Vorausgesetzt Du weisst, welches Bit Du invertieren willst. D.h. es ist 
immer dasselbe. Sonst muss die Maske mit der Du invertieren willst, noch 
geschoben werden.

Oder habe ich das ganze falsch verstanden?

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bitmanipulationen schreibt man in C so:


#define mybit 1 // Bitnummer (0..7)

char myvar;

myvar |= 1 << mybit; // Setzen

myvar &= ~(1 << mybit); // Löschen

myvar ^= 1 << mybit; // Invertieren

if( myvar & (1 << mybit)) // Testen



Peter

Autor: Notker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> #define mybit 1 // Bitnummer (0..7)
> char myvar;
> myvar |= 1 << mybit; // Setzen
> myvar &= ~(1 << mybit); // Löschen
> myvar ^= 1 << mybit; // Invertieren
> if( myvar & (1 << mybit)) // Testen

So sieht es aus, wenn ein Assembler-Freak in C zu programmieren versucht 
;-)

Nichts für ungut, aber wieso soll ich den Prozessor jedes Mal damit 
bemühen, ein Bit um mehrere Stellen nach links zu schieben, wenn die 
Bitposition schon zum Übersetzungszeitpunkt klar ist? Was anderes wäre 
es, wenn mybit eine Variable wäre, dann würde ich diesen Aufwand als 
gerechtfertigt ansehen. Ihr Assemblerprogrammierer vergesst immer, dass 
der Assembler arithmetische Ausdrücke im Operanden zum Zeitpunkt der 
Assemblierung in einen festen Wert umsetzt. Bei C wird daraus 
Programmcode erstellt, der zur Laufzeit ausgeführt wird. Und sowas 
schafft nicht gerade effektiven Code.

Meine 0,02$ zum Jahreswechsel

Notker

Autor: Marcel... (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
erstmal danke peter für deinen antwort..habs so übernommen und es 
funzt...

aber wie wäre dann deine lösung notker?

bei mir handelt es sich um io ports wo ich aber nur ein bit invertieren 
will

Autor: Sascha Weitkunat (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dank #define übernimmt der Compiler das einsetzen in den Code und hat 
somit konstante Statements die sofort ausgerechnet werden...

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Notker:

So denkt nur einer, der sich wohl noch nie den Assemblercode nach dem 
Compilieren angesehen hat ;-)

Das #define ist schon ne gute Sache, macht es doch den Code 
übersichtlicher und leichter, z.B. auf Hardwareänderungen (anderer 
Portpin) zu reagieren.


Wie schon Sascha sagte, ist es so, das ein C-Compiler alle konstanten 
Ausdrücke schon vom Präprozessor ausrechnet und nicht etwa unnützen 
Programmcode generiert.


Also so lange es der besseren Lesbarkeit und universelleren 
Anwendbarkeit dient, ist es durchaus sinnvoll es so hinzuschreiben.

Besonders größere Programme strotzen nur so von #define.

Eine Variante wäre noch folgende:

#define mybit 1 // Bitnummer (0..7)
#define mymask (1 << mybit)

char myvar;

myvar |= mymask; // Setzen


Ist aber für den Compiler keinerlei Unterschied.


Peter

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.