S. Lonci schrieb:
> Wann ist der Pointer nicht mehr "true" bzw. wann ist er überhaupt
> "true"?
Wie Alram schon sagte, der Dereferenzierstern macht den Unterschied.
Hier wird also nicht der Pointer befragt, sondern das worauf der Pointer
zeigt.
In C gilt die Regel:
0 wird als logisch falsch gewertet, alles was nicht 0 ist gilt als
logisch wahr.
Und da kommt jetzt ins Spiel, wie in C Strings aufgebaut sind.
Strings sind nichts anderes als eine Abfolge von Zeichen (die in Form
ihres ASCII Code gespeichert sind, alles ist in einem Computer letzten
Endes immer nur eine Zahl), die mit einem 0-Byte abgeschlossen wird.
Hast du also den String
"Hallo World"
dann steht der so im Speicher
1 | +---+---+---+---+---+---+---+---+---+---+---+---+
|
2 | | H | a | l | l | o | | W | o | r | l | d |\0 |
|
3 | +---+---+---+---+---+---+---+---+---+---+---+---+
|
d.h. eigentlich steht er nicht so im Speicher, sondern die Zeichen
stehen in Form ihres ASCII Codes dort
1 | +---+---+---+---+---+---+---+---+---+---+---+---+
|
2 | | 48| 61| 6C| 6C| 6F| 20| 57| 6F| 72| 6C| 64| 00|
|
3 | +---+---+---+---+---+---+---+---+---+---+---+---+
|
und es ist genau dieses abschliessende Byte mit dem Wert 0x00 (in
C-Schreibweise als Zeichen '\0' geschrieben), welches dafür sorgt, dass
die Schleife hier
abbricht. Denn ein Wert von 0 (der ja im Speicher ganz hinten im String
steht und auf den der Pointer irgendwann mal zeigen wird, wenn er
laufend erhöht wird) gilt ja als logisch falsch. Man könnte die
Schleifenbedingung auch so formulieren
1 | while( *cData != '\0' )
|
2 | ...
|
das wäre genau dasselbe aussagt bzw. macht.
In C ist das oft eine Gratwanderung, ob man den Vergleich != 0 explizit
hinschreibt oder nicht, denn der ist bei der Auswertung eines Ausdrucks,
der als Bedingung für irgendwas benutzt wird, sowieso automatisch mit
drinnen.
BTW:
Teile dir deine Stringausgabefunktion auf
1 | void Disp_Char(char c)
|
2 | {
|
3 | PORTB = (1 << RS); // Data Mode vorbeireiten; setze RS high
|
4 |
|
5 | SPDR = c; // Starte übertragung
|
6 | while(!(SPSR & (1<<SPIF))); // Warte auf ende der Übertragung
|
7 |
|
8 | //Übertragung abschließen durch RS toggle
|
9 | PORTB &= ~(1 << RS); //low
|
10 | PORTB = (1 << RS); // high
|
11 | _delay_us(50); // warte auf Display
|
12 | }
|
13 |
|
14 | void Disp_String(char *cData)
|
15 | {
|
16 | while (*cData)
|
17 | Disp_Char( *cData++ );
|
18 | }
|
denn eine Funktion die ein einzelnes Zeichen ausgeben kann, ist genauso
nützlich, wie eine die einen String ausgeben kann.