String
-
char* andererString="Hallo"; arr[1]=andererString;geht auch nicht oder ?
-
Na ja, das Problem an deinem [3][6] ist ja auch, dass die Zuweisung an ein char[6] nicht geht. Du kannst das gleiche als char* ausdrücken und dann hättest Du einen Zeiger auf den char-String. Aber für Stringkopien musst Du eben strcpy nutzen, da gibt es keine Ausnahme.
Auch:
char* andererString="Hallo";macht keine Stringkopie. Du hast lediglich einen Zeiger auf die String-Konstante "Hallo" erstellt. Dann bleibt "Hallo" auch im Speicher irgendwo vertreten, da das eine ganz spezielle Initialisierung darstellt, aber Du kannst daran wiederum nichts ändern. Somit solltest du direkt
const char* andererString = "Hallo";schreiben, um das zu verdeutlichen.Also ich versuche das Mal irgendwie zusammenzufassen:
#include <iostream> int main() { const char* string = "Ein konstanter String"; char* string2 = "Wieder ein konstanter String, denn ändern darfste nicht"; char abc[3]; // ein String konstanter Länge von 3 char* pointers[3]; // drei Zeiger auf Strings char** pointerPointers; // das kann man zu drei Strings machen oder auch zu einer beliebig großen Anzahl von Zeigern auf Strings; dafür ist dann aber new[] usw. nötig // Zum Initialisieren von String-Konstanten kann man die = "..."-Zuweisung nutzen; in allen anderen Fällen ist strcpy nötig }Und via std::string:
#include <iostream> #include <string> using namespace std; int main() { string threeStrings[3] = {"Einer", "Noch einer", "Ein Dritter im Bunde"}; threeStrings[0] = "Doch lieber ein anderer."; return 0; }Daher ist string eine tolle Klasse. Da hat man mit dem Speichergedöns viel weniger Probleme.
-
blurry333 schrieb:
char arr[3][6]ich habe 3 strings mit jeweils der Länge 6 angelegt.
Je nach Definition von "string".
blurry333 schrieb:
Wieso geht das nicht.
arr[1]="Hallo";Es gibt keine Array-Zuweisung.
Eisflamme schrieb:
weil mit "Hallo" nur ein temporärer String angelegt wird, [...] Nach Zeilenende ist der temporäre Strings aber futsch
Da wird nichts temporär angelegt. String-Literale beziehen sich auf const-char-arrays mit statischer Lebenszeit.
Eisflamme schrieb:
Und dann zeigt arr[1] auf Unsinn
arr[1] ist kein Zeigerobjekt, welches eine Adresse speichert. arr[1] bezieht sich auf ein 6-elementiges char-Array. Das einzige, was arr[1] speichern kann, sind ein paar char-Werte. arr[1] kann man zwar in vielen Kontexten als Zeigerwert (also eine Adresse) verwenden. Aber die Adresse, die dabei rauskommt ist nicht änderbar.
Eisflamme schrieb:
[...] gibt es in [...] C++ die praktische Klasse string!
Die einzig vernünftige Bemerkung von Dir. Ich möchte "praktisch" nochmal betonen.
Ich schlage vor, ihr beide sucht mal nach ein paar der unzähligen Threads, in denen Zeiger, Arrays, Strings erklärt werden. Das wurde schon sehr oft durchgekaut, das Thema. Siehe zB hier:
http://www.c-plusplus.net/forum/p1994728#1994728kk
-
void funk1(char* str) void funk2(char** str)Für mich sind beide obigen Deklarationen äquivalent. Gibt es irgendwann einen Unterschied.
char* mystring; funk1(mystring); funk2(&mystring);
-
blurry333 schrieb:
void funk1(char* str) void funk2(char** str) // das *Für mich sind beide obigen Deklarationen äquivalent. Gibt es irgendwann einen Unterschied.
char* mystring; funk1(mystring); funk2(&mystring); //das &
-
int main(int arg,char** argv)Wieso also char** argv und nicht char* argv ??
-
Weils ein Array aus Strings ist?
-
blurry333 schrieb:
void funk1(char* str) void funk2(char** str)Für mich sind beide obigen Deklarationen äquivalent.
Sind sie aber nicht. Abgesehen vom Namen und fehlenden Semikolons, deklariert die erste Zeile, was vom Typ her etwas anderes ist, als das, was die zweite Zeile deklariert.
blurry333 schrieb:
Gibt es irgendwann einen Unterschied.
Ich verstehe diesen Satz nicht.
blurry333 schrieb:
char* mystring; funk1(mystring); funk2(&mystring);Und was willst Du uns damit sagen?
blurry333 schrieb:
int main(int arg,char** argv)Wieso also char** argv und nicht char* argv ??
Derjenige, der sich das ausgedacht hat, wollte nicht nur eine Zeichenkette, sondern beliebig viele Zeichenketten (argv[0], argv[1], ...) übergeben können.
-
blurry333 schrieb:
int main(int arg,char** argv)Wieso also char** argv und nicht char* argv ??
Weil argv nicht nur auf ein einzelnes Zeichen oder eine einzelne Zeichenkette zeigt, sondern potentiell auf mehrere.
-
Ja, tut mir Leid, da war einiges daneben. Aber ebenfalls vernünftig waren doch meine Hinweise, strcpy zu nutzen, um Strings zu kopieren, und dass all die ganzen Zuweisungen niemals Kopien machen. Egal, ist ja jetzt klar, danke.
-
meinst du mit mehreren Strings etwa sowas ?
char* array[5][];ein Zeiger kann doch immer nur auf eine einzige Adresse zeigen ?
-
blurry333 schrieb:
meinst du mit mehreren Strings etwa sowas ?
char* array[5][];ein Zeiger kann doch immer nur auf eine einzige Adresse zeigen ?
char**ist ein Zeiger auf einen Zeiger.charr**zeigt auf den Anfang eines Arrays aus Zeigern. Und jeder Zeiger in diesem Array zeigt auf einen String.
-
mein Compiler schluckt das problemlos.
void funk(char* x){} //main char* array[5][10]; funk(array);
-
blurry333 schrieb:
mein Compiler schluckt das problemlos.
void funk(char* x){} //main char* array[5][10]; funk(array);Kompilierst Du das als C-Code?
-
ja als C code mit Eclipse
-
blurry333 schrieb:
ja als C code mit Eclipse
Und warum fragst Du im C++-Forum? Nach knapp 450 Posts sollte man wissen, welches Forum man benutzt...
-
blurry333 schrieb:
meinst du mit mehreren Strings etwa sowas ?
char* array[5][];Das ist kein C++ (auch kein C).
blurry333 schrieb:
ein Zeiger kann doch immer nur auf eine einzige Adresse zeigen ?
Eine Zeigervariable speichert höchstens eine Adresse, ja.
#include <iostream> using namespace std; int main(int argc, char **argv) { for (int i=0; i<argc; ++i) { if (i>0) std::cout << ' '; std::cout << argv[i]; } std::cout << std::endl; }Speicherlayout (Beispiel mit sizeof(char*)==4):
Name: argc argv argv[0] argv[1] argv[2] Adresse: egal egal 152 156 160 +-------+ +-------+ +-------+-------+-------+ Inhalt: | 3 | | 152 | | 400 | 412 | 405 | +-------+ +-------+ +-------+-------+-------+ Adresse: 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ Inhalt: | w | h | a | t |\0 | f | * | c | k | ? | ! |\0 | t | h | e |\0 | +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+Ausgabe:
what the f*ck?!Man beachte: argv zeigt nicht auf (den Anfang) eine(r) Zeichenkette.
-
[quote="krümelkacker"]
blurry333 schrieb:
Man beachte: argv zeigt nicht auf (den Anfang) eine(r) Zeichenkette.
Da bekomm ich aber was anderes raus :
printf("Adresse in argv: %x\n",argv); printf("Adresse von argv[0]: %x",&argv[0]);Ausgabe:
Adresse in argv: 3e3c48
Adresse von argv[0]: 3e3c48
-
[quote="blurry333"]
krümelkacker schrieb:
blurry333 schrieb:
Man beachte: argv zeigt nicht auf (den Anfang) eine(r) Zeichenkette.
Da bekomm ich aber was anderes raus :
printf("Adresse in argv: %x\n",argv); printf("Adresse von argv[0]: %x",&argv[0]);Ausgabe:
Adresse in argv: 3e3c48
Adresse von argv[0]: 3e3c48Ersteres gibt nicht die adresse von argv aus, sondern die vom inhalt von argv. Das zweite ebenfalls. &argv ist die adresse von argv, weder argv noch &argv[0]
-
printf("Adresse in argv: %x -> %x\n",*argv, argv); printf("Adresse von argv[0]: %x\n",&argv[0]); printf("Adresse von argv[1]: %x",&argv[1]);Adresse in argv: 3e2441 -> 3e24c8 Adresse von argv[0]: 3e24c8 Adresse von argv[1]: 3e24ccgreetz KN4CK3R