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
voidbit_write(int*var,intbit,int1val){
3
if(val)var|=(1<<bit);
4
elsevar&=~(1<<bit);
5
}
6
7
//Hauptprogramm:
8
voidmain(){
9
bytevarible=0;
10
bitvke=TRUE;
11
byteselect=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
intbit_write(int*var,intbit,int1val){
3
if(val)var|=(1<<bit);
4
elsevar&=~(1<<bit);
5
returnvar;
6
}
7
8
//Hauptprogramm:
9
voidmain(){
10
bytevarible=0;
11
bitvke=TRUE;
12
byteselect=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.
Stimmt ja.
Im HP muss ich die Adresse übergeben und im UP mit *var arbeiten.
Der CCS-Compiler ist ein wenig verwirren. Mit Feldern funktioniert das
so wie im oberen Programm.
> 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.
Das hat mit dem konkreten Compiler nichts zu tun; mit einem Array
funktioniert es, weil der Variablenwert eines Feldes bereits ein Zeiger
(auf den ersten Wert des Feldes) ist.
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 = ...