Verwirrung beim Bitschreiben

OP #974593
Lesenswert?

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.)
#974615
Lesenswert?

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.
#974816
Lesenswert?

> 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.
#974896
Lesenswert?

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.
#974902
Lesenswert?

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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren