Warum und wie funktioniert ein char pointer?
-
Schreibe ich
int * p = 10;
Erhalte ich vom Compiler eine Fehlermeldung. Das geht nicht. Schreibe ich aber
char * c = "C++";
erhalte ich keine Fehlermeldung vom Compiler.
Das ist für mich ein Paradox, wenn
int * p
nicht funktioniert,char *c
hingegen funktioniert. int * p kann nur dann funktionieren, wenn eine Adresse (&-Operator) angegeben wird. Warum klappt es beichar * c
ohne Angabe einer Adresse?
-
Offensichtlich hast du meine Antwort nicht ordentlich durchgelesen.
Sonst wüsstest du nämlich, dass "" ein Stringliteral ist (const char[1]), und somit in einen Pointer zerfallen kann. Du versuchst hier zwei völlig unterschiedliche Dinge - ein char Literal wäre 'a'.int* p = 5; // Geht nicht char* c = 'c'; // Auch nicht
-
Weil "C++" ein Stringliteral vom Typ const char[] ist...
-
Mit "" erzeugst du einen Pointer, dessen pointee ein Char-Array mit Zeichen im ASCII-Wert und einem folgenden Null-Terminator ist.
"C++"
Ist also ein Zeiger auf folgendes:
0xad4f849 67 // Das ist die Adresse von "C++" selbst! 0xad4f84a 43 0xad4f84b 43 0xad4f84c 0
Beispielsadressen (!).
Wenn du mit einem Char-Array Pointer so zugreifst:
const char* ptr = "C++"; ptr[2]; //<<= Hier
Verwandelt sich das zu
*( ptr + 2);
Und das heißt, dass man die Adresse von ptr um zwei erhöht (jetzt ist es 0xad4f84b) und dann dereferenziert.
Deswegen kannst du auch sowas schreiben:2["C++"] "C++"[2] MeinPtr[2] 2[MeinPtr]
-
Hacker schrieb:
Mit "" erzeugst du einen Pointer, dessen pointee ein Char-Array mit Zeichen im ASCII-Wert und einem folgenden Null-Terminator ist.
"C++"
Ist also ein Zeiger auf folgendes:
0xad4f849 67 // Das ist die Adresse von "C++" selbst! 0xad4f84a 43 0xad4f84b 43 0xad4f84c 0
Beispielsadressen (!).
Nicht ganz.
"C++"
ist genau dieses Array und kein Zeiger drauf. Ein Stringliteral ist ein lvalue vom Typconst char[
n]
und keinconst char*
(Beweis: Lass dir malsizeof("hello, world")
ausgeben). Allerdings können Arrays in C++ implizit in Pointer auf das erste Element umgewandelt werden.
-
Erklär mir bitte, wieso das geht:
*"C++"
Und was genau der Unterschied zwischen den beiden ptr's ist (also den Typen der Identifier).
const char ptr[5];
und
const char* ptr;
ist (außer, das man beim zweiten noch Speicherplatz zuweisen müsste).
-
Hacker schrieb:
Erklär mir bitte, wieso das geht:
Weil ein Array in einen Zeiger zerfallen kann? Ich denke das solltest du schon mal bemerkt haben.
Hacker schrieb:
Und was genau der Unterschied zwischen den beiden ptr's
Es sind komplett unterschiedliche Typen?
"lol"++; // Autsch
-
Hacker schrieb:
Erklär mir bitte, wieso das geht:
*"C++"
Weil das Stringliteral ein Array ist und das kann implizit in einen Pointer gewandelt werden...
Hacker schrieb:
Und was genau der Unterschied zwischen den beiden ptr's ist (also den Typen der Identifier).
const char ptr[5];
const char* ptr;
ist (außer, das man beim zweiten noch Speicherplatz zuweisen müsste).
Das erste ist ein Array, das zweite ist ein Pointer. Frag mal was sizeof(ptr) dazu meint
-
R- und L-Value ist das Stichwort. Einfach bisschen googeln! Jetzt hab ich es verstanden. Danke euch.
-
Bis jetzt habe ich verstanden, dass es mit den r- und l-values zusammenhängt. Wo ist definiert, dass
const char []
l-value ist und z.B. einint
ein r-value? In C++ muss ja irgendwo definiert sein, dassconst char []
ein l-value ist, also "hey, const char [], du bist ein r-value".
-
inc7 schrieb:
Wo ist definiert, dass
const char []
l-value ist und z.B. einint
ein r-value?Hmmm?
int
ist ein lvalue.const int
ist ein rvalue.
-
LValues und RValues haben mit Typen nichts zu tun. Es gibt ints sowohl als LValues, als auch als RValues.
int i = 42; // 42 ist ein RValue, i aber ein LValue
Grundsätzlich gilt: Alles, was einen Namen hat, ist ein LValue. Umgekehrt ist aber nicht alles, was keinen Namen hat, ein RValue.
-
Dann würde sich aber deine Aussage mit folgendem Code wiedersprechen:
cout << &"Test" << endl; cout << &10 << endl;
Geändert wurde nur der Typ von string nach int.
-
Nein, das widerspricht sich eben genau nicht. Stringliterale sind LValues.
-
314159265358979 schrieb:
Es gibt ints sowohl als LValues, als auch als RValues.
Kannst du mir Beispielcode zeigen, wo ein int als LValue verwendet wird?
314159265358979 schrieb:
Stringliterale sind LValues.
Und wo ist das in C++ definiert? Irgendwo muss ja (in der Headerdateien oder so?) stehen "stringliterale = LValue"
-
inc7 schrieb:
Kannst du mir Beispielcode zeigen, wo ein int als LValue verwendet wird?
i = 42;
inc7 schrieb:
Und wo ist das in C++ definiert? Irgendwo muss ja (in der Headerdateien oder so?) stehen "stringliterale = LValue"
camper wirds dir sicherlich gleich nachschlagen. Kannst ja im Standard nachsehen.
-
inc7 schrieb:
Kannst du mir Beispielcode zeigen, wo ein int als LValue verwendet wird?
inc7 schrieb:
314159265358979 schrieb:
Stringliterale sind LValues.
Und wo ist das in C++ definiert?
Im Standard?
ISO/IEC 14882 third edition [expr.prim.general] 5.1.1.1 schrieb:
A literal is a primary expression. Its type depends on its form (2.14). A string literal is an lvalue; all other literals are prvalues.
-
*loschmich*
-
314159265358979 schrieb:
Grundsätzlich gilt: Alles, was einen Namen hat, ist ein LValue.
Hm...
enum { ich_bin_ein_rvalue }; template<int ich_auch> struct s {};
Und this ist auch ein r-value.
-
Dann eben: Alles, was einen Namen hat und Stück Speicher zur Laufzeit bezeichnet, hat einen Namen.