char-array mit pointer durchlaufen
-
int main (int argc, char **argv) { std::cout << "Matheaufgabe eingeben: "; char keyboard_input[512]; std::string keyboard_input_string; getline(std::cin , keyboard_input_string); std::cout<<"eingelesen wurde: "<<keyboard_input_string.length()<<std::endl; int i; for(i=0; i < keyboard_input_string.length(); i++) keyboard_input[i] = keyboard_input_string[i]; keyboard_input[i] = '\0'; //Mein Problem while(*keyboard_input != '\0') { keyboard_input++; std::cout<<"klick"<<std::endl; }
hab hier diesen code, der sinn des ganzen sei hier mal außenvor, ich hab mich darin verbissen über pointerschreibweise die elemente in keyboard_input zu durchlaufen bis zum nullbyte das angefugt ist und dafür jedes mal ein "klick" auszugeben.
nur irgendwas stimmt da nicht so ganz, wenn ich das ganze mit Xcode unter OS-X kompiliere sagt er mir als Fehlermeldung "invalid lvalue assignment"ich bin mir aber relativ sicher das es am kompilier liegt, weil ich mitterlweile in code-beispielen nachgeschaut hab, die ich früher mal auf andere Betriebssystem mit anderen kkompilern erstellt hab.
kann mir wer sagen was daran falsch ist, der kompilier unterstütt scheinbar auch nur einen älteren standard, den das deklarieren von variablen innerhalb von for-schleifen mag er auch net....
-
Schau dir Zeile 19 an, dann Zeile 4, und dann erkläre bitte, was Zeile 19 bewirken soll.
-
zeile 4 definiert ein array mit 512 bytes, keyboard_input zeigt dabei auf das erste element von keyboard_input.
in zeile 19 zähle ich die einzelnen byteshoch, nach dem ersten ++ steh ich vor dem zweitem byte von keyboard_input
oder nicht? damit durchlufe ich das array
-
ich verstehs nicht warum das nicht funktioniert. das ging doch sonst immer....
-
squis schrieb:
keyboard_input zeigt dabei auf das erste element von keyboard_input.
Und bei diesem Satz wirst du nicht stutzig?
-
camper schrieb:
squis schrieb:
keyboard_input zeigt dabei auf das erste element von keyboard_input.
Und bei diesem Satz wirst du nicht stutzig?
Oder um noch ein wenig eindeutiger zu werden:
- keyboard_input ist das Array, das durchlaufen werden soll
- ... und wo ist der Pointer, der es (auch gemäß Deinem Threadtitel) durchlaufen soll ?
Gruß,
Simon2.
P.S.: Ganz verkneifen kann ich' mir nicht:
- Bleib doch bei std::string (tu ich auch) und
- kopieren muss man nicht mit Schleife - dafür gibt's Funktionen (std::copy() in C++, strcpy() in C). Wenn man sowas selbst macht, gewinnt man nichts, läuft aber Gefahr,"off-by-one"- oder andere Zugriffsfehler einzubauen.
-
Ha, das Problem kenn ich, da hats bei mir auch nicht gleich "klick" gemacht
Es ist schon richtig, das keyboard_array ein Pointer ist, der auf das erste Element des Feldes zeigt. Allerdings ist keyboard_array gleichzeitig auch konstant. Deswegen darfst du es logischerweiße auch nicht als lvalue (wie in keyboard_array=keyboard_array+1) verwenden. Natürlich kannst du es aber einem andern Pionter zuweisen...
-
ah ok, danke.
Richtig gedacht nur falsch gemacht. Hab das mit dem durchaufn von Arrays bisher auch nur innerhalb von funktionen bzw. methoden gemacht. Da hat das wegen der von dir erwähnten zuweisung an einen neuen pointer, der lokaln kopie, funktioniert...
danke, man lern nie aus
-
Fledi schrieb:
Es ist schon richtig, das keyboard_array ein Pointer ist
nein, nein und nochmals nein.
-
Es ist schon richtig, das keyboard_array ein Pointer ist
nein, nein und nochmals nein.doch, doch und nochmals doch.
die daten liegen auf dem stack und ein array ist nur ein konstanter zeiger darauf
char daten1[8]; char const *daten2 = daten1;
beide sind intern identisch
für den compiler sind sie vllt. verschieden aber auf assemblerebene ist das gleich
-
camper schrieb:
Schau dir Zeile 19 an, dann Zeile 4, und dann erkläre bitte, was Zeile 19 bewirken soll.
camper schrieb:
squis schrieb:
keyboard_input zeigt dabei auf das erste element von keyboard_input.
Und bei diesem Satz wirst du nicht stutzig?
camper schrieb:
Fledi schrieb:
Es ist schon richtig, das keyboard_array ein Pointer ist
nein, nein und nochmals nein.
Diese Hinweise helfen nicht!
-
zeigerle schrieb:
Es ist schon richtig, das keyboard_array ein Pointer ist
nein, nein und nochmals nein.doch, doch und nochmals doch.
die daten liegen auf dem stack und ein array ist nur ein konstanter zeiger darauf
char daten1[8]; char const *daten2 = daten1;
beide sind intern identisch
für den compiler sind sie vllt. verschieden aber auf assemblerebene ist das gleich
Was soll das denn sein: intern, assemblerebene? Und was hat das mit dem Problem zu tun?
keyboard_input ist kein Zeiger, sowenig wie es daten1 ist. Der ++ Operator benötigt als Argument ein modifizierbares skalares lvalue. keyboard_input ist zwar modifizierbar und ein lvalue, aber kein Skalar und kann auch nicht implizit in ein solches umgewandelt werden.xxyyzz schrieb:
camper schrieb:
Schau dir Zeile 19 an, dann Zeile 4, und dann erkläre bitte, was Zeile 19 bewirken soll.
camper schrieb:
squis schrieb:
keyboard_input zeigt dabei auf das erste element von keyboard_input.
Und bei diesem Satz wirst du nicht stutzig?
camper schrieb:
Fledi schrieb:
Es ist schon richtig, das keyboard_array ein Pointer ist
nein, nein und nochmals nein.
Diese Hinweise helfen nicht!
Das könnte stimmen, oder auch nicht. Jedenfalls ist es allemal besser als immer wieder den gleichen Unfug (Array=Zeiger) zu verbreiten. Das wird durch Wiederholung auch nicht richtiger.
-
Wieso gibt es eigentlich diese Unterscheidung? Das ist mir irgendwie bis heute noch nicht so ganz klar.
Ich persönlich finde irgendwie, dass dies nur die Verwendung der Arrays verkompliziert. Ok, vielleicht in C++ klug, damit die Leute den std::vector verwenden, aber das wird wohl kaum der Grund sein
Grüssli
-
Dravere schrieb:
Wieso gibt es eigentlich diese Unterscheidung?
Weil es sich um völlig verschiedene Dinge handelt, und wir Dinge dann nicht gleich bezeichnen, wenn es auf diese Unterschiede ankommt.
Umgekehrt ist mir nicht klar, wie man auf die Idee kommen kann, dass es sich um das Gleiche handelte.
Sicherlich wirst du anerkennen, das es einen Unterschied gibt zwischen deiner Wohnung und der Adresse dieser Wohnung. Natürlich gibt es zwischen beiden einen Zusammenhang und es kann auch vorkommen, dass man an Stelle des einen das andere verwenden kann, z.B. könntest du auf die Frage, wo du wohnst, mit der Angabe der Adresse antworten oder aber, wenn sie denn in Sichtweite ist, einfach darauf zeigen.
Ein Array ist ein Objekt, das aus einzelnen gleichartigen Subobjekten besteht. Objekte sind zusammenhängende Speicherbereiche. Jedem solchen Speicherbereich ist eine (Anfangs-)adresse zugeordnet. Ein Zeigerwert stellt eine typisierte (indem der Typ des Objektes an dieser Stelle Teil des Zeigertyps ist) Adressinformation dar.
Zeigerobjekte sind Objekte, die diese Adressinformation speichern können.
Diese beiden Dinge (Array, Zeiger) zusammenzuwerfen ergibt hinten und vorne keine Sinn.
-
Zeigerobjekte sind Objekte, die diese Adressinformation speichern können.
Der Feldname speichert die Adresse des ersten Feldelementes. Wieso ist er da kein Zeiger??
-
camper schrieb:
Diese beiden Dinge (Array, Zeiger) zusammenzuwerfen ergibt hinten und vorne keine Sinn.
Ich weiss, dass es zwei grundsätzlich völlig unterschiedliche Dinge sind. Grundsätzlich haben sie nichts miteinander zu tun, da geb ich dir definitiv auch recht. Aber das ist die Theorie. In der Praxis wäre es äusserst angenehm, wenn diese Unterscheidung nicht stattfinden würde. Oder empfindest du es als praktisch, solche Dinge zu machen?
&array[0];
Wenn noch der Fall wäre, wie in Java, dass das Array ein Length Attribute hätte, dann wäre für mich die Unterscheidung auch in der Praxis verständlich. Aber tatsächlich hast du ein Array, welches sich fast 1:1 wie ein Zeiger verhält und trotzdem keiner ist.
Ich sehe in der Praxis einfach den Vorteil dieser Unterscheidung nicht. Vielleicht arbeite ich aber auch zu wenig mit C-Arrays, um den Vorteil zu sehen.
Grüssli
-
Fledi schrieb:
Zeigerobjekte sind Objekte, die diese Adressinformation speichern können.
Der Feldname speichert die Adresse des ersten Feldelementes. Wieso ist er da kein Zeiger??
Weil du "speichern" in einem völlig anderen Sinn gebrauchst.
Zwar gehört zum Arrayobjekt eine Adresse, aber diese Adressinformation existiert nicht selbst im Speicher und ist daher auch nicht adressierbar.Man könnte genauso gut fragen, wieso
5++
nicht funktioniert.
-
freut mich das meine einfache frage ( ich dachte zumindest sie sei einfach ) so eine angeregt diskussion gefördert hat :-).
mir wurde das im studium so vermittelt (oder ich habs so verstanden) das ein variable die ein char array ist
char mein_array[5];
ein Zeiger auf die speicheradresse von mein_array[0] ist. Den Fehler den ich gemacht hab kam dadurch zu stände das ich bisher immer nur in funktionen bzw. methoden mit den arrays über pointer gearbeitet hab, weswegen ich nie in ds loch mit dem 'konstanten' Zeiger gefallen bin.
eig. muss das auch ein zeiger sein, sons würde sowas doch gar nicht funktionieren:
void copy(char * a, char * b); int main(int argc, char **argv) { char in[6] = {'H','a','l','l','o','\0'}; char out[6]; copy(in, out); return 0; } void copy (char * a, char * b) { while(*b++ = *a++); }
Die Funktion erwartet eine pointer, wäre das array kein pointer würd das schon beim kompilieren gegen di wand rennen oder nicht ?
-
@squis,
char array1[] = "Hallo"; // Dann ist array1, ca. gleichwertig zu: char* const array2 = "Hallo";
Und einen konstanten Zeiger darf man auch kopieren, solange der Zeiger selbst nicht verändert wird.
Aber eben, grundsätzlich muss man es differenzieren, das eine ist ein Array und das andere ein konstanter Zeiger. Es macht in meinen Augen nicht all zu viel Sinn, aber was solls.Grüssli
-
Dravere schrieb:
@squis,
char array1[] = "Hallo"; // Dann ist array1, ca. gleichwertig zu: char* const array2 = "Hallo";
Und einen konstanten Zeiger darf man auch kopieren, solange der Zeiger selbst nicht verändert wird.
Aber eben, grundsätzlich muss man es differenzieren, das eine ist ein Array und das andere ein konstanter Zeiger. Es macht in meinen Augen nicht all zu viel Sinn, aber was solls.Grüssli
Die Gemeinsamkeiten von Zeigern und Adressen versteht ihr, aber macht Euch den Unterschied zwischen Zeiger und Adressen klar!
Zeiger sind lvalues - Adressen sind rvalues!
Mit dem Adressoperator kann man Zeigern Adressen von Variablen zuweisen oder Adressen repraesentieren
- Ausnahme bilden Arrays, der Arrayname seht für die Adresse des ersten Arrayelements (&array[0]).#include <iostream> using namespace std; int main() { char array1[] = "Hallo"; // array1 (= null-terminierte Zeichenkette) liegt auf dem Stack! if (array1 == *&array1 && array1 == &array1[0]) cout << "array1 repraesentiert die Adresse von array1[0]( &array1[0] bzw. *&array1 !)" << endl; char* const array2 = "Hallo"; // array2 (Zeiger auf konstante null-terminierte Zeichenkette). Die liegt im schreibgeschuetzten Bereich! array1[0] = 'B'; // ok! cout << array1 << endl; array2[0] = 'B'; // Fehler, weil Zugriffsverletzung beim Schreiben! return 0; }
mfg