Verständisfrage zu Pointern und char[]

Schnelle objektorientierte, kompilierende Programmiersprache.
Zenerid
Beiträge: 38
Registriert: Do Feb 05, 2015 4:15 pm

Verständisfrage zu Pointern und char[]

Beitrag von Zenerid » Mi Apr 20, 2016 1:57 am

Ich habe ein kleines Verständisproblem mit Pointern und auch mit dem char Array (char[]) und würde das gerne mal anhand von Beispielen ein wenig hier durchsprechen, falls das für euch okay ist. Soweit ich das ja verstanden habe ist ein Pointer, egal von welchem Typ ein Zeiger auf eine Speicheradresse und wen man nur ptr schreibt kriegt man das, was sich in der Speicheradresse befindet, also bspw. so einen Pointer hier hat:

Code: Alles auswählen

char *ptr = "hello"
dann würde man ja wenn man das mit

Code: Alles auswählen

printf("%s", ptr);
ausgibt hello erhalten und wenn man ansatt von ptr *ptr schreibt die Speicheradresse als Ausgabe erhalten, das ist doch soweit schon einmal richtig oder?

Was ich jetzt aber bei einigen Beispielen die ich gefunden habe oder bei Codestücken die ich gefunden habe nicht ganz verstehe, ist z.B

Code: Alles auswählen

if(*buffer == '\0')
    return 0;
Man hat dann also einen buffer wo irgendetwas aus einer Datei steht aber kann man echt so prüfen, ob da in dem Sinne überhaupt etwas drinsteht, also sprich ein leerer String an der Speicheradresse oder ein einfach Null-terminierter String oder was bewirkt die Zeile sonst? Hier auch bspw. wieder so eine Zeile, wo eine Datei geparst wird:

Code: Alles auswählen

while(*buffer && isspace(*buffer))
    ++buffer;
Dadurch wird dann ja geprüft ob der Buffer nicht NULL ist und sich an der aktuellen Position im Buffer ein Leerzeichen befindet und falls das der Fall ist, geht man im Buffer weiter oder liege ich damit falsch? Darf man das dann so verstehen, dass das dann wie ein Array im Prinzip fungiert oder wie kann man das erklären, also das da dann (sozusagen) buffer steht? Ansonsten verstehe ich echt nicht, was der Code bewirken soll.

Auch noch einmal zu dem char Array:
Soweit ich das auch verstanden habe, sollte man aber auch eigentlich einen String in C mit einem char Arrray definieren aber wieso sieht man dann dennoch oft ein char * als String? Ist das weil es manche vielleicht auch nicht besser wissen? Irgendwie verstehe ich auch noch nicht ganz, wann man besser was benutzen sollte. Ein Pointer ist ja read-only, während man ein Array ja verändern kann, wie in jeder anderen Sprache oder ist der wesentliche Vorteil von Pointern das man den Speicher dynamisch assozieren kann, während man bei einem Array ja immer die Größe mit angeben muss?

Ich würde mich daher falls ich falsch liegen sollte oder falsch man das so nicht sagen kann, sehr über eine Antwort freuen, wie man das ganze dann richtig erklären könnte bzw. wie man das dann richtig ausdrücken würde.

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8859
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Verständisfrage zu Pointern und char[]

Beitrag von Xin » Mi Apr 20, 2016 9:01 am

Zenerid hat geschrieben:Ich habe ein kleines Verständisproblem mit Pointern und auch mit dem char Array (char[]) und würde das gerne mal anhand von Beispielen ein wenig hier durchsprechen, falls das für euch okay ist. Soweit ich das ja verstanden habe ist ein Pointer, egal von welchem Typ ein Zeiger auf eine Speicheradresse und wen man nur ptr schreibt kriegt man das, was sich in der Speicheradresse befindet, also bspw. so einen Pointer hier hat:

Code: Alles auswählen

char *ptr = "hello"
dann würde man ja wenn man das mit

Code: Alles auswählen

printf("%s", ptr);
ausgibt hello erhalten und wenn man ansatt von ptr *ptr schreibt die Speicheradresse als Ausgabe erhalten, das ist doch soweit schon einmal richtig oder?
Nicht ganz. ptr ist ein (char *) und "hello" ist ein (char const *), weswegen die Zuweisung schon nicht klappt: char const * ptr = "hello" geht.
ptr ist die Variable, die die Adresse beinhaltet. *ptr ist der Inhalt der Adresse und an der Adresse liegt ein (char const) - und zwar das erste von "hello", das 'h'.
Wenn Du die Adresse als String begreifst (also als char const *), dann kannst Du sie mit printf() als String ausgeben. Wenn Dich der Pointer interessiert, kannst Du die Adresse als Pointer ausgeben:

Code: Alles auswählen

printf("%p\n", (void*) ptr );
Zenerid hat geschrieben: Was ich jetzt aber bei einigen Beispielen die ich gefunden habe oder bei Codestücken die ich gefunden habe nicht ganz verstehe, ist z.B

Code: Alles auswählen

if(*buffer == '\0')
    return 0;
Man hat dann also einen buffer wo irgendetwas aus einer Datei steht aber kann man echt so prüfen, ob da in dem Sinne überhaupt etwas drinsteht, also sprich ein leerer String an der Speicheradresse oder ein einfach Null-terminierter String oder was bewirkt die Zeile sonst? Hier auch bspw. wieder so eine Zeile, wo eine Datei geparst wird:

Code: Alles auswählen

while(*buffer && isspace(*buffer))
    ++buffer;
Dadurch wird dann ja geprüft ob der Buffer nicht NULL ist und sich an der aktuellen Position im Buffer ein Leerzeichen befindet und falls das der Fall ist, geht man im Buffer weiter oder liege ich damit falsch? Darf man das dann so verstehen, dass das dann wie ein Array im Prinzip fungiert oder wie kann man das erklären, also das da dann (sozusagen) buffer steht? Ansonsten verstehe ich echt nicht, was der Code bewirken soll.

Oder-Fragen sind schlecht mit "Richtig" oder "Falsch" zu beantworten. ;)

Die if-Abfrage prüft, ob das Zeichen, auf das buffer zeigt ein Nullbyte ist. (NULL ist als Nullpointer definiert, das ist auch 0, aber halt ein Pointer und kein einzelnes Byte).

Die Schleife guckt, ob an der Position, auf die buffer zeigt kein Nullbyte liegt und ein Whitespace liegt (Leerzeichen, Tab...). Die Abfrage "*buffer" (kein Nullbyte) ist überflüssig, denn wenn da ein White-Space ist, ist da kein Nullbyte.

Zenerid hat geschrieben:Auch noch einmal zu dem char Array:
Soweit ich das auch verstanden habe, sollte man aber auch eigentlich einen String in C mit einem char Arrray definieren aber wieso sieht man dann dennoch oft ein char * als String? Ist das weil es manche vielleicht auch nicht besser wissen? Irgendwie verstehe ich auch noch nicht ganz, wann man besser was benutzen sollte.

Ein (char*) ist (fast) das gleiche wie ein (char []). Beides zeigt auf ein Array von Chars. Bei (char *) legt man aber nur den Zeiger an, bei (char[]) auch den Platz für den String. Den (char*) kann man auf einen anderes Char-Array zeigen lassen. Beim (char[]) geht das nicht, denn diese Variable ist fest mit einem Stück Speicher verknüpft.

Zenerid hat geschrieben:Ein Pointer ist ja read-only, während man ein Array ja verändern kann, wie in jeder anderen Sprache oder ist der wesentliche Vorteil von Pointern das man den Speicher dynamisch assozieren kann, während man bei einem Array ja immer die Größe mit angeben muss?

Die Pointer-Variable ist nur dann read-only, wenn sie als "const" definiert sind: (char * const). Hier darf die Zeigervariable nicht verändert werden, aber die Buchstaben, auf die er zeigt. Der String ist nur dann read-only, wenn die Buchstaben read-only sind: (char const *).

Zenerid hat geschrieben:Ich würde mich daher falls ich falsch liegen sollte oder falsch man das so nicht sagen kann, sehr über eine Antwort freuen, wie man das ganze dann richtig erklären könnte bzw. wie man das dann richtig ausdrücken würde.

Hoffe geholfen zu haben. Ansonsten frag halt weiter. :)
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Zenerid
Beiträge: 38
Registriert: Do Feb 05, 2015 4:15 pm

Re: Verständisfrage zu Pointern und char[]

Beitrag von Zenerid » Mi Apr 20, 2016 6:07 pm

Hmm .. dann habe ich das ja komplett verwechselt. Wenn ich also einen Pointer habe, dann ist ptr die SPeicheradresse und *ptr der Wert von dem Pointer, also dass was dann dementsprechend ebend an der Speicheradresse liegt, aber ebend nur das erste Zeichen aber man kann mit ++ dann auch wie in einem Array zeichenweise weitergehen, richtig? :shock:

Könnte ich denn aber auch nicht, wenn es sich um einen char * handelt mit

Code: Alles auswählen

printf("%s", *ptr);
den ganzen Pointer oder was an der Speicheradresse liegt als String ausgeben oder würde das so nicht gehen? Das mit dem ausgeben der Speicheradresse bzw. dem Pointer ist ja auch interessant aber könnte man das nicht einfach nur mit

Code: Alles auswählen

printf("%p\n", ptr );
machen oder muss man das unbedingt casten? Das ist doch ein cast?
Xin hat geschrieben:Oder-Fragen sind schlecht mit "Richtig" oder "Falsch" zu beantworten. ;)

Die if-Abfrage prüft, ob das Zeichen, auf das buffer zeigt ein Nullbyte ist. (NULL ist als Nullpointer definiert, das ist auch 0, aber halt ein Pointer und kein einzelnes Byte).

Die Schleife guckt, ob an der Position, auf die buffer zeigt kein Nullbyte liegt und ein Whitespace liegt (Leerzeichen, Tab...). Die Abfrage "*buffer" (kein Nullbyte) ist überflüssig, denn wenn da ein White-Space ist, ist da kein Nullbyte.
Hehe, ja das stimmt schon. Habe ich das denn dann auch richtig verstanden, das man mit

Code: Alles auswählen

if(*buffer == '\0')
und

Code: Alles auswählen

if(*buffer)
auf dasselbe prüft, also ob da NULL steht als auch ob da ein \0 steht? \0 steht doch eigentlich für das Ende eines Strings oder nicht und ist somt auch nicht dasselbe wie NULL oder liege ich da jetzt komplett falsch und beides ist identisch?

Der Code mit der Schleife stammt nicht von mir aber danke für die Erklärung soweit schon einmal! Deine Erkärung hat mir bis jetzt schon sehr viel weiter geholfen und ich möchte mich auch demnächst noch weiter mit C beschäftigen, aber nur mit c und nicht mit c++ ;)
Xin hat geschrieben:Ein (char*) ist (fast) das gleiche wie ein (char []). Beides zeigt auf ein Array von Chars. Bei (char *) legt man aber nur den Zeiger an, bei (char[]) auch den Platz für den String. Den (char*) kann man auf einen anderes Char-Array zeigen lassen. Beim (char[]) geht das nicht, denn diese Variable ist fest mit einem Stück Speicher verknüpft.

Die Pointer-Variable ist nur dann read-only, wenn sie als "const" definiert sind: (char * const). Hier darf die Zeigervariable nicht verändert werden, aber die Buchstaben, auf die er zeigt. Der String ist nur dann read-only, wenn die Buchstaben read-only sind: (char const *).

Hoffe geholfen zu haben. Ansonsten frag halt weiter. :)
Ah gut, dann hatte ich das mit dem char * ja doch schon richtig verstanden. Wenn man dann auch noch etwas bei dieser Speicheradresse speichern will, dann müsste man ja erst welchen freigeben, mit malloc oder calloc z.B. ?
Ein char Array oder generell ein Array reserviert ja selbständig den benötiigten Speicher aber was ich ja dann nicht ganz verstehe, ist wann man was verwendet. Warum wird dann bspw. für einen Buffer, wo man etwas aus einer Datei einliest oft ein char * verwendet und kein Array?

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8859
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Verständisfrage zu Pointern und char[]

Beitrag von Xin » Mi Apr 20, 2016 6:41 pm

Zenerid hat geschrieben:Hmm .. dann habe ich das ja komplett verwechselt. Wenn ich also einen Pointer habe, dann ist ptr die SPeicheradresse und *ptr der Wert von dem Pointer
ptr ist die Bezeichnung für eine Speicherstelle, wo der Inhalt von ptr liegt. ptr ist ein (char *), also ein Pointer.
Bei int i; gibt es eine Speicherstelle irgendwo im Speicher, die Du im Programm 'i' nennst. Wenn Du 'i' schreibst, wird der Inhalt der Speicherstelle benutzt.
Wenn Du ptr eingibst wird der Inhalt der Speicherstelle verwandt, die Du eben mit "ptr" bezeichnest. Statt eines integers, hast Du in der Speicherstelle die Adresse einer anderen Speicherstelle stehen. Damit zeigt "ptr" auf eine andere Adresse.
*ptr geht nun hin und nimmt den Inhalt der Speicherstelle, die Du "ptr" nennst, worin sich eben die Adresse einer anderen Speicherstelle befindet. Diese andere Speicherstelle wird nun mit '*' dereferenziert. Statt also die andere Speicherstelle anzugucken, guckst Du nun auf die Daten, die an der anderen Speicherstelle liegen, was bei einem (char const *) eben als ein (char const) interpretiert wird.
Zenerid hat geschrieben:, also dass was dann dementsprechend ebend an der Speicheradresse liegt, aber ebend nur das erste Zeichen aber man kann mit ++ dann auch wie in einem Array zeichenweise weitergehen, richtig? :shock:
ptr++ nimmt die Daten aus der Speicherstelle, die Du ptr nennst, was eine Adresse auf eine andere Speicherstelle ist, und erhöht dieses Datum um 1. Die erhöhte Adresse der anderen Speicherstelle wird dann in ptr, also an der Speicherstelle, die Du "ptr" nennst, wieder gespeichert.
Genau wie bei i++.
Zenerid hat geschrieben:Könnte ich denn aber auch nicht, wenn es sich um einen char * handelt mit

Code: Alles auswählen

printf("%s", *ptr);
den ganzen Pointer oder was an der Speicheradresse liegt als String ausgeben oder würde das so nicht gehen?
Es gibt keine halben Pointer. Ein Pointer ist eine Zahl - eben die Nummer der Speicherstelle. Du kannst die Nummer mit %p ausgeben oder mit %s behauptest Du, dass da, wohin ptr zeigt, ein String wäre, den man ausgeben kann.
Zenerid hat geschrieben:Das mit dem ausgeben der Speicheradresse bzw. dem Pointer ist ja auch interessant aber könnte man das nicht einfach nur mit

Code: Alles auswählen

printf("%p\n", ptr );
machen oder muss man das unbedingt casten? Das ist doch ein cast?
%p ist eine Formatierungsvorschrift. Da kommt eine Zahl und die soll so ausgegeben werden, dass es wie eine Adresse aussieht. Bei %s läuft ein ganz anderes Programm ab - da wird an die Adresse geguckt und Buchstabe für Buchstabe ausgegeben, bis ein Nullbyte ankommt. Das ist kein Cast.

Das Casting, was ich mit (void*) eingefügt habe, dient dazu, den Compiler zu beruhigen, der bei %p bei mir die Warnung gibt, dass er ein (void *) wünscht. C++ castet nicht mehr automatisch nach (void*). Um die Warnung zu unterdrücken, bestätige ich mit dem Cast nach (void *), dass ich weiß, was ich da tue.
Zenerid hat geschrieben:Hehe, ja das stimmt schon. Habe ich das denn dann auch richtig verstanden, das man mit

Code: Alles auswählen

if(*buffer == '\0')
und

Code: Alles auswählen

if(*buffer)
auf dasselbe prüft
Die beiden Zeilen sind semantisch identisch, aber
Zenerid hat geschrieben:, also ob da NULL steht als auch ob da ein \0 steht? \0 steht doch eigentlich für das Ende eines Strings oder nicht und ist somt auch nicht dasselbe wie NULL oder liege ich da jetzt komplett falsch und beides ist identisch?
Es wird nur geprüft, ob das erste(!) Zeichen des Strings, also das auf das Buffer zeigt ein Nullbyte ist.
Falls buffer NULL ist, also ein Nullpointer, fliegt Dir das um die Ohren. Für beides wäre die Abfrage:

Code: Alles auswählen

if( buffer && *buffer )
Zenerid hat geschrieben:Ah gut, dann hatte ich das mit dem char * ja doch schon richtig verstanden. Wenn man dann auch noch etwas bei dieser Speicheradresse speichern will, dann müsste man ja erst welchen freigeben, mit malloc oder calloc z.B. ?
Schwierige Wortwahl. Du musst beschreibbaren Speicher haben und ein String im Quelltext, wie "Hallo Welt", ist nicht beschreibbar. Du kannst Dir entweder Speicher in einem Array geben lassen:

Code: Alles auswählen

char array[100];
oder Du kannst Speicher allozieren, auf den Du dann selbstverständlich auch schreiben darfst, diesen musst Du danach aber an das System zurückgeben, also aus Deiner Besetzung entlassen, umgangssprachlich: Den Speicher wieder freigeben. Das wäre dann mit malloc/calloc und free.
Zenerid hat geschrieben:Ein char Array oder generell ein Array reserviert ja selbständig den benötiigten Speicher aber was ich ja dann nicht ganz verstehe, ist wann man was verwendet. Warum wird dann bspw. für einen Buffer, wo man etwas aus einer Datei einliest oft ein char * verwendet und kein Array?
Nochmal: Ein char * zeigt wie ein char [] auf das erste Element des Arrays. Wie lang das Array ist, ist dabei eine andere Frage. Ein char single; und ein char array[1]; sind vom Prinzip das gleiche. Nur, dass Du beim array den Zeiger auf das erste Element hast, beim zweiten hast Du das char direkt. Ein Zeiger kann nun auf ein Element zeigen, zum Beispiel durch char * ptr = &single; oder durch char * ptr = array;
Greifst Du nun auf *ptr zu, wird entsprechend das char gelesen oder geändert, dessen Speicheradresse in ptr steht.

Wann nimmst Du was? Wenn Du weißt, wieviel Speicher Du brauchst und dass Du auch derjenige bist, der den Speicher wieder frei gibt, dann kannst Du ein Array verwenden: Weil der Speicher in deiner Funktion liegt. Du kannst Funktionen rufen und diesen Funktionen mit Hilfe eines Zeigers sagen, wo sie den Speicher finden. printf( "%s\n", array ) zum Beispiel.
Aber Du kannst das Array nicht an die Funktion geben, die Dich gerufen hat.

Wenn Du also nicht weißt, dass Du selbst (also die Funktion, die den Speicher gerade braucht) derjenige sein wird, der den Speicher wieder freigibt, dann musst Du alloc und free nehmen. Der Speicher liegt dann irgendwo im Computer und ist nicht von der Funktion abhängig.

Speicher anfordern kostet Zeit - wenn man drauf verzichten kann, nimmt man lieber ein Array. Wenn man Speicher anfordern muss, muss man eben Speicher anfordern.
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Zenerid
Beiträge: 38
Registriert: Do Feb 05, 2015 4:15 pm

Re: Verständisfrage zu Pointern und char[]

Beitrag von Zenerid » Sa Apr 23, 2016 6:33 pm

ptr ist die Adresse und *ptr war der Inhalt, so stiimmt das ja also. Ein Pointer kann ja auch wieder auf einem Pointer zeigen, dann mit **, soweit ich weiß?

Zu dem ++:
Also im Prinzip wie bei einem Array oder nicht, bloß das der Zeiger nun eins weiter geht.

Mit dem %s kann man also auch versuchen das was an der Speicherstelle steht auszugeben aber wenn da kein String steht, dann gibt es halt einen Fehler?

Zu dem wann verwendet man was:
Was meinst du denn mit dem freigeben, wenn man ein char Array verwendet? Der Speicher wird doch dann automatisch freigegeben oder nicht? Nach dem verlassen des Blocks oder habe ich das falsch verstanden?

Noch einmal eine Frage zu den Abfragen:
Bei C muss mann dann ja auch umdenken, weil ja eine int Funktion im Erfolgsfall 0 zurückgibt und nicht 1? Das finde ich ja auch irgendwie sehr komisch aber warum ist das bei c eigentlich so? Eigentlich richtet man sich ja dann bei der Erstellung von eigenen Funktionen danach aber irgendwie schon komisch false anstatt true zurückzugeben, anstatt wie bei anderen Sprachen true und false.

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8859
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Verständisfrage zu Pointern und char[]

Beitrag von Xin » Sa Apr 23, 2016 6:53 pm

Zenerid hat geschrieben:ptr ist die Adresse und *ptr war der Inhalt, so stiimmt das ja also. Ein Pointer kann ja auch wieder auf einem Pointer zeigen, dann mit **, soweit ich weiß?
Richtig.
Zenerid hat geschrieben:Zu dem ++:
Also im Prinzip wie bei einem Array oder nicht, bloß das der Zeiger nun eins weiter geht.
Ich sehe den Vergleich zum Array nicht... von daher... keine Ahnung... ^^
Zenerid hat geschrieben:Mit dem %s kann man also auch versuchen das was an der Speicherstelle steht auszugeben aber wenn da kein String steht, dann gibt es halt einen Fehler?
Kommt drauf an, was Du unter "Fehler" verstehst... %s sagt, dass was an der Speicherstelle steht, als String ausgegeben wird. Vermutlich willst Du das nicht lesen. Vermutlich kannst Du es nicht lesen. Und wenn die Speicherstelle nicht im erreichbaren Bereich liegt, dann knallt es.
Zenerid hat geschrieben:Zu dem wann verwendet man was:
Was meinst du denn mit dem freigeben, wenn man ein char Array verwendet? Der Speicher wird doch dann automatisch freigegeben oder nicht? Nach dem verlassen des Blocks oder habe ich das falsch verstanden?
Richtig verstanden.

Was Du mit malloc alloziiert() hast, musst Du mit free() wieder freigeben.
Zenerid hat geschrieben:Noch einmal eine Frage zu den Abfragen:
Bei C muss mann dann ja auch umdenken, weil ja eine int Funktion im Erfolgsfall 0 zurückgibt und nicht 1? Das finde ich ja auch irgendwie sehr komisch aber warum ist das bei c eigentlich so?
Ein Programm gibt Fehlercode 0 zurück, um Erfolg zu signalisieren.
Was eine Funktion zurückgibt, ist eine andere Sache, das entscheidest Du. 0 wird als "falsch" verstanden. Entsprechend für Konstrukte wie

Code: Alles auswählen

if( funccall() ) ...
darf die Funktion im Erfolgsfall eben nicht 0 zurückliefern.

Das ganze hat nichts mit C zu tun. Das gilt für alle Programme, die dem OS "Erfolg" melden wollen, egal mit welcher Sprache sie kompiliert werden.
Zenerid hat geschrieben:Eigentlich richtet man sich ja dann bei der Erstellung von eigenen Funktionen danach aber irgendwie schon komisch false anstatt true zurückzugeben, anstatt wie bei anderen Sprachen true und false.
Du kannst bei Funktionen zurückgeben, was immer Du willst. true und false gibt es in C nicht (erst in C++). In C gibt es nur 0 (false) und Nicht-0 (true).
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Zenerid
Beiträge: 38
Registriert: Do Feb 05, 2015 4:15 pm

Re: Verständisfrage zu Pointern und char[]

Beitrag von Zenerid » So Apr 24, 2016 2:06 am

Xin hat geschrieben:Kommt drauf an, was Du unter "Fehler" verstehst... %s sagt, dass was an der Speicherstelle steht, als String ausgegeben wird. Vermutlich willst Du das nicht lesen. Vermutlich kannst Du es nicht lesen. Und wenn die Speicherstelle nicht im erreichbaren Bereich liegt, dann knallt es.
Jo, das meinte ich ja. Das wollte ich einfach nur noch einmal klarstellen. Dann habe ich das ja bis jetzt alles richtig verstanden. :lol:
Xin hat geschrieben:Ein Programm gibt Fehlercode 0 zurück, um Erfolg zu signalisieren.
Was eine Funktion zurückgibt, ist eine andere Sache, das entscheidest Du. 0 wird als "falsch" verstanden. Entsprechend für Konstrukte wie

Code: Alles auswählen

if( funccall() ) ...
darf die Funktion im Erfolgsfall eben nicht 0 zurückliefern.

Das ganze hat nichts mit C zu tun. Das gilt für alle Programme, die dem OS "Erfolg" melden wollen, egal mit welcher Sprache sie kompiliert werden.

Du kannst bei Funktionen zurückgeben, was immer Du willst. true und false gibt es in C nicht (erst in C++). In C gibt es nur 0 (false) und Nicht-0 (true).
Ja, da hast du natürlich auch wieder recht aber ich habe es jetzt in C doch schon öfter gesehen, das Funktionen in dem Bereich von -1 bis + 1 Werte zurückgeben, wie z.B strcmp, welches mit 0 als erfolgreich, also die Strings sind gleich zurückgibt.

Es empfiehlt sich dann aber wohl bei 0 für false zu bleiben und für 1, bei Erfolg oder nicht? Ich glaube mal, das ich lieber dabei bleibe. :D Es stimmt natürlich schon, dass ein Programm den Fehlercode 0 zurückgibt, das ist ja auch bei C# und vielen anderen Sprachen ebendso.

Danke noch einmal für die ganze Hilfe! Du hast mir auf jeden Fall sehr viel weiter geholfen. So eine kleine Beratung oder Hilfe hilft da ja doch immer schon mehr, finde ich. *thumbs up*

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8859
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Verständisfrage zu Pointern und char[]

Beitrag von Xin » So Apr 24, 2016 10:31 am

Zenerid hat geschrieben:Du kannst bei Funktionen zurückgeben, was immer Du willst. true und false gibt es in C nicht (erst in C++). In C gibt es nur 0 (false) und Nicht-0 (true).
Ja, da hast du natürlich auch wieder recht aber ich habe es jetzt in C doch schon öfter gesehen, das Funktionen in dem Bereich von -1 bis + 1 Werte zurückgeben, wie z.B strcmp, welches mit 0 als erfolgreich, also die Strings sind gleich zurückgibt.[/quote]
Ja, gerade strcmp ist auf den ersten Blick so ein Sonderfall... aber man muss sich halt auch angucken, was strcmp zurück gibt. Es geht nicht um den Erfolgsfall, sondern um die Unterschiedlichkeit. Bei -1 ist der linke String kleiner als der Rechte, bei +1 ist der Rechte kleiner als der Linke und bei 0 gibt es keine Unterschiede.
Zenerid hat geschrieben:Es empfiehlt sich dann aber wohl bei 0 für false zu bleiben und für 1, bei Erfolg oder nicht? Ich glaube mal, das ich lieber dabei bleibe. :D Es stimmt natürlich schon, dass ein Programm den Fehlercode 0 zurückgibt, das ist ja auch bei C# und vielen anderen Sprachen ebendso.
Das empfielt sich nicht sehr deutlich, da die if- und while-Abfragen nunmal genauso funktionieren und in C++ false auch mit 0 definiert ist. Änderst Du das, wird Dein Code unverständlich.
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Zenerid
Beiträge: 38
Registriert: Do Feb 05, 2015 4:15 pm

Re: Verständisfrage zu Pointern und char[]

Beitrag von Zenerid » So Apr 24, 2016 3:42 pm

Als ich mir das dann angeguckt habe, ist es mir dann ja auch klar geworden, bzw. als du es weiter oben geschrieben hast. Ich war irgendwie erst verwirrt und dachte dann, das es bei C so üblich ist aber da habe ich mich wohl vertan.
Xin hat geschrieben:Das empfielt sich nicht sehr deutlich, da die if- und while-Abfragen nunmal genauso funktionieren und in C++ false auch mit 0 definiert ist. Änderst Du das, wird Dein Code unverständlich.
Ich meinte ja nicht das ich dann alles umdrehe, also für den Erfolgsfall dann 0 (false) zurückgebe und für den Fehlerfall 1 (true), sondern ebend wie es normal üblich ist, also 1 für true und 0 für false. Das habe ich ja auch nicht so geschrieben, das ich das umändern wollte, wie es eigentlich unüblich ist oder wolltest du das nur noch einmal klarstellen?

P.S: Das erste Zitat ist wohl etwas zu früh geschlossen. ;)

Zenerid
Beiträge: 38
Registriert: Do Feb 05, 2015 4:15 pm

Re: Verständisfrage zu Pointern und char[]

Beitrag von Zenerid » Fr Apr 29, 2016 8:26 am

Ich hätte noch zwei Fragen, die mir einfach keine Ruhe lassen, falls das okay ist. Das Zitat was du zuerst gemacht hast, ist übrigens nicht ganz vollendet. Im Text steht dann noch einmal quote. ;)
Zuerst einmal die Frage wann man denn eigentlich Speicher für einen Pointer freigeben muss:
Wenn ich bspw sage:

Code: Alles auswählen

char *ext = strrchr(path, '.');
Dann muss ich ja keinen Speicherbereich freigeben aber warum? Strrchr gibt ja keinen Speicher frei, den ich dann sogar vielelicht noch hätte freigeben müssen aber woher weiß man dann eigentlich genau, wenn man denn dann Speicher freigeben muss? Das ist mir irgendiwe noch nicht ganz klar.

Zuletzt noch eine Frage und zwar was passiert wenn ich einen Pointer an eine Methode übergeben, also so:

Code: Alles auswählen

char *temp;
str_to_upper(temp);

Code: Alles auswählen

int str_to_upper(char * buffer) {
    while ( *buffer ) {
	*buffer = toupper(*buffer);
	++buffer;
    }
    return 0;
}
Dann ist das doch kein Call by reference, sondern einfach nur ein Call by Value oder nicht? Der ursprüngliche pointer wird doch dann nicht verändert, es sei denn ich füge das & Zeichen bei dem Methodenaufruf mit ein, sprich er soll das an der Speicheradresse speichern?
str_to_upper(&temp);[/code]

Antworten