Hallo Community, ich belese mich gerade zum Thema UART auf dieser Website. Dabei bin ich auf den Beispielcode zu uart_puts() und zu uart_putc() gestoßen. Dabei verstehe ich nicht, wozu man hierbei mit einem Zeiger arbeitet. >void uart_puts (char *s) >{ > while (*s) > { /* so lange *s != '\0' also ungleich dem "String-> >Endezeichen(Terminator)" */ > uart_putc(*s); > s++; > } >} Wenn man schon mit einem Zeiger arbeitet, so hätte ich jetzt erwartet, dass man diesem eine Speicheradresse zuordnet. Warum arbeit man also hier mit einem Zeiger? Welche Adresse wird ihm zugeordnet? Fg fragenkinsey
:
Bearbeitet durch User
Julian Kinsey schrieb: > Wenn man schon mit einem Zeiger arbeitet, so hätte ich jetzt erwartet, > dass man diesem eine Speicheradresse zuordnet. Warum arbeit man also > hier mit einem Zeiger? Welche Adresse wird ihm zugeordnet? Die Frage ist eher: Warum programmierst du in C, wenn du die einfachsten Grundlagen zur Stringverarbeitung, bzw. wie Arrays an Funktionen übergeben werden, nicht kennst?
1 | uart_puts( "hallo" ); |
und schon kriegt die Funktion ihren Zeiger übergeben. Du brauchst ein C-Buch. So hat das alles wenig Sinn.
Ich hatte mal ein Jahr lang C in der Schule. Ich hatte gehofft, dass mir die Kenntnisse von damals ausreichen würden, um zumindestens das Tutorial nachzuvollziehen. Das scheint aber nicht zu funktionieren. Müsste ich aber den Zeiger char *s nicht trotzdem z.B.: in int main () eine Adresse zuweisen, damit das Sinn ergibt. So wie ich das verstehe, wird jetzt "Hello" einfach auf den Zeiger char *s Hello übergeben. Diesem müsste ich doch aber vorher eine Speicheradresse für "Hello" zuweisen oder irre ich etwa? Danke!
Danke für den Link. Ich werde ihn mir mal durchlesen. FG fragenkinsey
Du hast einen String, der ist irgendwo gespeichert. Wo spielt keine Rolle. Du übergibst dann deiner Funktion einen Zeiger auf den Anfang deines Strings. Mit dem Zeiger kann die Funktion nun auf einzelne Elemente des Strings zugreifen (ein String ist ja nichts anderes als ein char Array) und so ihre Arbeit erledigen. Wenn du
1 | uart_puts( "hallo" ); |
schreibst, übergibst du der Funktionen einen Zeiger, der auf den String "hallo" zeigt. Wo "hallo" gespeichert wird, kann dir egal sein. Andere Möglichkeit:
1 | char MeinText[]="hallo"; |
2 | |
3 | uart_puts(MeinText); |
MeinText ist ein Zeiger auf das erste Element deines Strings. Man könnte auch schreiben:
1 | uart_puts(&MeinText[0]); |
Ist das selbe, aber unschön. Wie bereits erwähnt wurde: Karl Heinz schrieb: > Du brauchst ein C-Buch. So hat das alles wenig Sinn.
Und weils so schön ist noch eine Möglichkeit:
1 | char* MeinText = "hallo"; |
2 | |
3 | uart_puts(MeinText); |
Der String "hallo" liegt irgendwo im Speicher. Die Zeigervariable MeinText enthält die Adresse des ersten Zeichens (hier 'h'). Diese Adresse wird an die Funktion übergeben. Hier ist anders:
1 | char MeinText[] = "hallo"; |
2 | |
3 | uart_puts(MeinText); |
Es gibt ein Array (Speicherbereich) mit dem Namen MeinText, das 6 Byte groß ist. An diesem stehen die Zeichen "hallo" plus das Stringendezeichen '\0'. Wenn man MeinText an eine Funktion übergibt, wird allerdings nicht der Speicherinhalt zur Funktion kopiert, sondern der Compiler übergibt die Adresse des ersten Elements des Arrays (bzw. des ersten Zeichens des Strings). Das ist eine Besonderheit bei Arrays (und damit Strings) in C.
Guten Abend, ich glaube, dass ich es jetzt verstanden habe. Insbesondere dieser Satz Hans Dampf schrieb: > Das ist eine Besonderheit bei Arrays (und damit Strings) in C. hat es mir klar gemacht. Danach viel es mir einfacher die letzten beiden Beiträge nachzuvollziehen. In dem Tutorial sieht es ja so aus: >int main(void) >{ > char s[7]; > int16_t i = -12345; > > uart_init(); > > itoa( i, s, 10 ); // 10 fuer radix -> Dezimalsystem > uart_puts( s ); > .......} und >void uart_puts (char *s) >{ > while (*s) > { /* so lange *s != '\0' also ungleich dem "String->Endezeichen(Terminator)" */ > uart_putc(*s); > s++; > } >} ich war verwirrt, weil mir in der Hauptfunktion mindestens char *s[7] statt char s[7]; (also das Zeigersymbol) gefehlt hat. Ich meine, wenn die Definition der Funktion schon uart_puts (char *s) heißt, dann erwartet die Funktion einen Zeiger als übergebenes Argument. Das Array char s[7] muss aber nicht als Zeiger in int main() als Zeiger deklariert werden, weil es eine Sonderstellung hat. In C wird ein Array also quasi wie ein Zeiger betrachtet, sodass die Deklaration con char *s[7] bzw. "*" überflüssig wird - es reicht somit die Deklaration char s[7]. Über ein Feedback, ob ich das richtig verstanden habe, wäre ich erfreut. Danke euch beiden. FG fragenkinsey
Julian Kinsey schrieb: > als Zeiger deklariert werden, weil es eine Sonderstellung hat. In C wird > ein Array also quasi wie ein Zeiger betrachtet Vorsicht mit dieser Aussage. Viele Leute die so etwas oder etwas ähnliches sagen, meinen das Falsche. Ein Array degeneriert in manchen Situationen zur Startadresse des Arrays im Speicher. Zum Beispiel bei der Übergabe an eine Funktion. Normale Variablen werden per Value übergeben. D.h. die Funktion bekommt eine Kopie des originalen Wertes des Aufrufers. Wie zb
1 | void foo( int i ) |
2 | {
|
3 | ....
|
4 | }
|
5 | |
6 | int main() |
7 | {
|
8 | int j = 5; |
9 | |
10 | foo( j ); |
11 | }
|
wird die Funktion foo aufgerufen, dann wird der Wert von j hergenommen (die 5), und davon eine Kopie in der lokalen Variablen i der Funktion foo abgelegt. Arrays funktionieren anders. Steht der Name des Arrays alleine, dann degeneriert dieser zur Startadresse des Arrays im Speicher. Diese Startadresse wird dann für die Funktion in die Pointer Variable der Funktion kopiert.
1 | void foo( int * daten ) |
2 | {
|
3 | daten[0] = 5; |
4 | }
|
5 | |
6 | int main() |
7 | {
|
8 | int werte[8]; |
9 | |
10 | foo( werte ); |
11 | }
|
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.