Verwirrung beim Bitschreiben

OP #974593
Hallo!

Ich hab ein kleines Problem beim Schreiben eines Bits mit einem 
Unterprogramm, welches ich mir nicht erklären kann.

Ich wollte mir ein UP schreiben, welches mir in einer Variable ein 
bestimmtes Bit entweder auf 0 oder 1 setzt.
So sah dieses Prog. aus:
1
//Das Unterprogramm:
2
void bit_write(int *var, int bit, int1 val) {
3
  if(val) var|=(1<<bit);
4
  else var&=~(1<<bit);
5
}
6

7
//Hauptprogramm:
8
void main() {
9
byte varible=0;
10
bit vke=TRUE;
11
byte select=0;
12

13
bit_write(variable,select,val);
14
printf("%x\r\n",variable); //Ausgabe: 00 (sollte jedoch 01 sein)
15
}

So funtioniert das UP jedoch:
1
//Das Unterprogramm:
2
int bit_write(int *var, int bit, int1 val) {
3
  if(val) var|=(1<<bit);
4
  else var&=~(1<<bit);
5
  return var;
6
}
7

8
//Hauptprogramm:
9
void main() {
10
byte varible=0;
11
bit vke=TRUE;
12
byte select=0;
13

14
variable=bit_write(variable,select,val);
15
printf("%x\r\n",variable); //Ausgabe: 01
16
}

Könnt ihr mir das erklären?
(Achja, ich benutze den CCS-Compiler und den PIC18F8722.)
Das obere Programm würde schon funktionieren, wenn Du die "variable" als 
Zeiger übergeben würdest, wie es bit_write() erwartet:

bit_write(&variable,select,val);

Das obere Programm macht im Augenblick, was du ihm sagst: schreibe den 
Wert in Speicherzelle 0 (da variable=0). Abgesehen davon, daß sowas ins 
Auge gehen kann, liest du im weiteren Verlauf des Programms gar nicht 
mehr aus dieser Speicherzelle.
> Das obere Programm würde schon funktionieren, wenn Du die "variable" als
> Zeiger übergeben würdest, wie es bit_write() erwartet:

Nein, würde auch nicht funktionieren.
Das grundlegende Problem ist, dass er in bit_write das Bit im Zeiger 
verändert, und nicht im Wert, auf den er zeigt.
C. We. wrote:
> Warum muss man dann bei schon vom Kompiler vordefinierten Funktionen,
> wie z.B. BIT_SET(var,bit), diese Funktionen nicht mit &var aufrufen?

Weil das keine Funktionen sind, sondern Makros.
Und sie werden auch nicht vom Compiler definiert, sondern von der libc.
Das ist schätzungsweise keine Funktion, sondern ein Makro. Makros werden 
durch Code ersetzt, also z.B.

#define ADD(var1,var2) ( var1 += var2 )
ADD(x,5);
ADD(x,7);

Vor der Übersetzung macht der Compiler daraus:

(x += 5);
(x += 7);

Es ist also nicht nötig, eine Referenz zu übergeben und dennoch wird der 
Wert der Variablen verändert. Auch wenn es so ausschaut wie ein 
Funktionsaufruf. Wäre es eine Funktion:

void ADD(int var1, int var2)
{
   var1 += var2;
}
...
ADD(x,5);

So würde das nicht wie gewollt funktionieren, da nur var1 verändert 
wird, aber nicht x.


Der Einwurf von Stefan ist natürlich korrekt: in bit_write muss man var 
erst dereferenzieren: *var = ...

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 18 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.