Frage zu Zeigern
-
Gast321 schrieb:
1. Wo ist der Unterschied zwischen diesen Schreibweisen?
main() { char* str="Mein Text"; char *str2="Mein Text"; char str3[]="Mein Text"; }
Schreibweisen 1 und 2 sind identisch, wo die Leerzeichen stehen ist egal. Achtung: Bei
int* a,b;
ist a ein Zeiger auf int und b ein int, was bei dieser Schreibweise für Uneingeweihte nicht offensichtlich ist.str3 ist hier ein char-Array mit 10 Elementen, kein Zeiger auf ein solches, sondern es ist das Array und die Werte der Elemente sind 'M', 'e', i', usw.
str und str2 hingegen sind von Typ Zeiger auf char und zeigen auf ein Zeichenkettenliteral, welches irgendwo anders steht und den Inhalt "Mein Text" hat. Achtung: Aus historischen Gründen ist es einem char* erlaubt auf ein Zeichenkettenliteral zu zeigen, aber das heißt nicht, dass man dieses verändern darf! In der Regel wird dies auch schiefgehen. Man sollte str und str2 daher so behandeln, als wären sie vom Typ
const char*
(d.h. ein (veränderlicher) Zeiger auf eine Konstante vom Typ char) oder besser: Gleich richtig machen und diesen Typ benutzen.2. Ich habe zwei Funktionen:
char* fkt1(char* str) { ... return str; } main() { char *test; char text="Hallo"; test=fkt1(text); }
Dies ist kein gültiges Programm. Ich könne zwar spekulieren, was du meinen könntest, aber korrigiere das lieber erst einmal selber.
Hierbei würde die Adresse der Variablen text an die fkt1 übergeben werden.
Nein, Parameterübergaben an Funktionen sind immer Kopien von Werten. Es gibt eine semi-Ausnahme: Wenn eine Funktion einen Zeiger auf etwas erwartet, dann kann man auch ein Array auf diesen Typen angeben, welcher dann als ein Zeiger auf das erste Element dieses Arrays angesehen wird. Und dieser Zeiger wird dann kopiert.
Fkt1 macht dann irgendwas und gibt als ergebnis str zurück. Dieses wiederum wird in test gespeichert. Ist es hierbei möglich, dass fkt1 eine andere string variable außer str zurückgibt? Jede andere Variable wäre doch nur lokal verfügbar? Kann man in so einer Situation also entweder nur str oder eine globale Variable zurückgeben?
Es kann ja auch noch alle möglichen anderen Quellen für das Ergebnis geben. Einen Zeiger auf etwas lokales solltest du auf keinen Fall zurück geben, das ist richtig. Wenn fkt1 aber wirklich nur diesen einen Parameter hat und du keine Seiteneffekte zulässt (was auch gut ist), dann kommt tatsächlich nur etwas in Frage, was irgendwie aus str gebildet wurde.
-
str und str2 sind identisch. Du hast jeweils einen Zeiger und das Stringliteral.
Beides braucht Speicher.
Die Zeiger kannst du auch ändern, also woanders hinzeigen lassen.
Die Stringliterale selbst kannst du aber nicht verändern.Bei str3 hast du ein Array. Dieses Array hat einen Namen (eben str3).
Dies ist kein Zeiger, denn dieser Name belegt keinen Speicher und ist fest mit dem Array verbunden.
Dafür kannst du den Inhalt des Arrays ändern.Bei deinem 2. Beispiel hast du wohl noch einen Schreibfehler (da fehlt der * oder [])
char *text="Hallo"; oder char text[]="Hallo";
Das hast du richtig erkannt.
So machen es auch die Standardfunktionen wie strcpy oder strcat.
-
sacridex schrieb:
Zum ersten Beispiel, alle drei Formulierungen sind identisch!
Nein!
-
[quote="SeppJ"]
sacridex schrieb:
Zum ersten Beispiel, alle drei Formulierungen sind identisch!
Nein!
Oder
#include <stdio.h> int main() { char *str1 = "Hallo Welt!"; char str2[] = "Hallo Welt!"; printf("%s %s\n", str1, str2); str1 = "Bye Bye"; str2 = "Bye Bye"; printf("%s %s\n", str1, str2); }
Was kommt da raus?
#include <stdio.h> int main() { char *str1 = "Hallo Welt!"; char str2[] = "Hallo Welt!"; printf("%s %s\n", str1, str2); *str1 = '1'; *str2 = '2'; printf("%s %s\n", str1, str2); }
Und was passiert hier?
-
Gast321 schrieb:
Hallo,
ich habe folgende Fragen zu Zeigern und hoffe Ihr könnt mir helfen:
1. Wo ist der Unterschied zwischen diesen Schreibweisen?
main() { char* str="Mein Text"; char *str2="Mein Text"; char str3[]="Mein Text"; }
den inhalt von str3 darfst du direkt ändern, z.b. durch
str3[0] = 'K';
das würde bei str und str2 zum absturz führen und nur per umweg über ne os-api funktion gehen.
btw. ist str3 kein zeiger, sondern ein char array.
-
zum gefühlt 1000. Mal:
Ein Zeiger ist kein Array.
Ein Array ist kein Zeiger.Es gibt 4 Sonderfälle gemäß C Standard, in denen ein Array nicht zu einem Zeiger mutiert.
Ein Array ist ein unmodifizierbarer Lvalue; dem Array selbst kann nichts zugewiesen werden (außer bei Initialisierung im Rahmen der Definition), nur Array-Elementen kann etwas zugewiesen werden.
Die Tatsache, dass der Subscript-Operator [] für Arrays und Zeiger verwendet werden kann, heißt nicht, dass Array und Zeiger das Gleiche sind.
-
Hallo,
vielen Dank für eure Antworten. Das hat mir sehr zum Verständnis geholfen.
Eine Frage habe ich aber noch:
#include <stdio.h> int main() { int i; char zk1[13]="Zeichenkette"; char *pzk; pzk=zk1; for(i=0;*pzk;i++) printf("\n%c %p",*pzk++,pzk); }
Der Zeiger *pzk zeigt auf zk[0]. Wie ist es möglich, dass die for-Schleife somit weiß, dass diese "am Ende" ist? Gibt es hier C-intern eine Funktion die auf '\0' prüft?
-
Gast321 schrieb:
Gibt es hier C-intern eine Funktion die auf '\0' prüft?
Nein. Die die Bedingung steht im Bedingungsteil der for-Schleife. Beschreib mal mit dem, was du gelernt hast, was
*pzk
ist. Beachte auch, dass pzk sich in der Schleife ändert. Geh das Programm ruhig mal in Gedanken durch und sag für jeden Durchlauf an, was bei der Bedingung heraus kommt (und frag uns im Zweifelsfall, ob deine Interpretation auch richtig ist).Wenn du das gemacht hast, dann macht es hoffentlich Klick und du hast C-Strings verstanden.
P.S.: Es ist übrigens undefiniert, ob das printf hier den Wert des Zeigers vor der Ausgabe oder den um 1 erhöhten Wert ausgibt.
-
seppj meint bestimmt: die bedingung, welche die for-schleife laufen lässt, steht im bedingungsteil ...
wenn die bedingung bool-mäßig betrachtet 0 ist, wird sie beendet.
-
Na dann probier ichs mal mit eigenen Worten:
*pzk ist ein Zeiger auf zk1.
Dieser Zeiger wird mittels *pzk++ jeweils an die nächste Position innerhalb von zk1 geschoben. Bei der For-Schleife wird geprüft ob an dieser Position ein Wert steht. Wenn ja wirs die Schleife weiter durchlaufen, wenn nein (Wert=0) wird die Schleife beendet.
Ist das so korrekt?
-
Gast321 schrieb:
Ist das so korrekt?
Ja.
Jetzt rate mal, welchen Wert '\0' wohl hat.
-
TS, achte einfach nicht drauf was SeppJ schreibt. Ist halt ein Newbie..
-
Gast321 schrieb:
Na dann probier ichs mal mit eigenen Worten:
*pzk ist ein Zeiger auf zk1.
Nö. pzk ist ein Zeiger, *pzk ist der Wert, der dort steht, wo pzk hinzeigt.