const char*



  • Guten Tag,

    zur Zeit beschäftige ich mich mit der WinAPI. Dabei ist mir aufgefallen, dass Funktionen wie z.B. rename() als Parameter const char* benötigen.

    Ich wüsste gerne etwas genauer was ein const char* ist, mit anderen Worten ein Pointer auf einen konstanten Char.

    Habe ich einen String, muss ich diesen erst zu einem Low-Level-String im C-Stil konvertieren, danach kann ich einem Objekt vom Typ const char* diesen zuweisen.

    Wenn ich das richtig verstanden habe wird also ein Array aus Chars mit einem konstanten Pointer erzeugt?! Wieso funktioniert das ganze nicht auch einfach mit einem c_string bzw. String?

    Beste Grüße und vielen Dank

    Dryn


  • Mod

    Du kannst zu einem string einen entsprechenden C-String (das heißt einen Pointer auf ein nullterminertes Array von const chars) mittels c_str() erhalten. Dieser ist so lange gültig, bis du gewisse Aktionen auf dem String ausführst (welche genau ist bei c_str() dokumentiert).

    Das ganze hat den Sinn (oder Unsinn), dass man in C Zeichenketten als ein Feld von chars betrachtet, da es in C keine Klassen gibt, die so eine Funktionalität kapseln. Aufgrund gewisser Eigenschaften von rohen Feldern in C und C++ werden Felder wenn sie an Funktionen übergeben werden zu Zeigern auf das erste Element. Damit eine Funktion das Ende einer solchen Zeichenkette finden kann, ohne dass man dauernd die Länge mit übergeben muss, ist das Ende mit einem Nullzeichen (Zeichen '\0', numerischer Wert 0) markiert. Wenn die Funktion nichts an der Zeichenkette ändert, macht sie dies deutlich, indem sie einen Pointer auf const chars erwartet.
    Die WinApi ist eine C-Schnittstelle, darum macht sie das so.



  • Dryn schrieb:

    Ich wüsste gerne etwas genauer was ein const char* ist, mit anderen Worten ein Pointer auf einen konstanten Char.

    Genau das, normalerweise unausgesprochen mit der Annahme, dass ab der Adresse, auf die der Zeiger zeigt, ein Array von Zeichen liegt, das durch ein Null-Zeichen ( '\0' ) abgeschlossen wird.

    Habe ich einen String, muss ich diesen erst zu einem Low-Level-String im C-Stil konvertieren, danach kann ich einem Objekt vom Typ const char* diesen zuweisen.

    Genau.

    Wieso funktioniert das ganze nicht auch einfach mit einem c_string bzw. String?

    Weil die Winapi eine C-API ist. BTW rename ist zwar keine Winapi-Funktion, sondern eine Standardfunktion von ANSI-C, aber das ganze verhielte sich genauso, wenn dein Beispiel eine Winapi-Funktion gewesen wäre.



  • Du kannst die WinAPI - Funktion, die einen const char* erwartet, so aufrufen:

    #include <string>
    
    ...
    std::string str("Mein String");
    
    WinAPIFunktion(str.c_str(), ... evtl. weitere Parameter);
    

    weil die Methode

    c_str()
    

    einen

    const char*
    

    liefert. Btw. kannst Du die Funktion auch mit einem

    char*
    

    aufrufen.
    Würde sie allerdings einen

    char*
    

    erwarten, könntest Du sie nicht mit einem

    const char*
    

    aufrufen, mithin können solche Funktionen nicht mit

    ....c_str()
    

    aufgerufen werden.



  • Hallo!

    Der Standardbezeichner "const" bedeutet, dass man den nachfolgend deklarierten Parameter nur initialisieren, aber nicht ändern kann. Es wird durch "const" also festgelegt, dass lediglich ein Wert an die Funktion übergeben wird (Werte-Parameter). Bei Zeiger-Parametern ist auch der umgekehrte Weg möglich (Referenzparameter), wenn man "const" nicht verwenden würde.

    Aus historischen Gründen wird bei alten C-Funktionen char* als String-Typ verwendet. Die von dir genannten String-Typen sind später entstanden.

    Gruß, Lothar.


  • Mod

    Sowada schrieb:

    Der Standardbezeichner "const" bedeutet, dass man den nachfolgend deklarierten Parameter nur initialisieren, aber nicht ändern kann. Es wird durch "const" also festgelegt, dass lediglich ein Wert an die Funktion übergeben wird (Werte-Parameter). Bei Zeiger-Parametern ist auch der umgekehrte Weg möglich (Referenzparameter), wenn man "const" nicht verwenden würde.

    Das ist bei Übergabe von Parametern an Funktionen aber höchst verwirrend formuliert, wie ich finde. Es geht bei dem const da drum, dass trotz der Referenzübergabe (bzw. hier durch Pointer) das dahinter stehende Objekt nicht verändert wird. Mit dem Parameter selbst (also dem Pointer) kann die Funktion machen was sie möchte. Das const bezieht sich auf das, wo drauf die Referenz/Pointer verweist.



  • SeppJ schrieb:

    Mit dem Parameter selbst (also dem Pointer) kann die Funktion machen was sie möchte. Das const bezieht sich auf das, wo drauf die Referenz/Pointer verweist.

    Was ist daran verwirrend? Auch ohne einen Funktionsaufruf kann ich

    const char* str1 = "abc";
    const char* str2 = "def";
    
    str1 = str2;
    

    machen. Wenn auch der Zeiger konstant sein soll, muss man das halt entsprechend definieren, sowohl wenn es um einen Funktionsparameter geht, als auch sonst:

    const char* const str1 = "abc";
    const char* str2 = "def";
    
    str1 = str2; //geht nicht
    


  • Danke für die ausführliche Erläuterung!

    Hat nun auch alles bestens funktioniert 😉



  • Hi,
    um auf deine Fragen kurz und knapp zu antworten:

    Dryn schrieb:

    Wenn ich das richtig verstanden habe wird also ein Array aus Chars mit einem konstanten Pointer erzeugt?!

    Ja, aus deinem std::string wird ein konstanter Zeiger auf das erste Element des C-String-Arrays erzeugt. (ich glaube, std::string arbeitet intern auch mit Zeigern, aber es ist eine andere Geschichte).

    Dryn schrieb:

    Wieso funktioniert das ganze nicht auch einfach mit einem c_string bzw. String?

    Na mit C-Strings funktioniert das schon. Es muss nur ein konstanter Zeiger auf char sein. Was std::string angeht: die C-Sprache kennt so etwas nicht.



  • [Rewind] schrieb:

    Es muss nur ein konstanter Zeiger auf char sein.

    *Zeiger auf konstanten char 😉



  • 314159265358979 schrieb:

    [Rewind] schrieb:

    Es muss nur ein konstanter Zeiger auf char sein.

    *Zeiger auf konstanten char 😉

    Meine ich, srry.


Anmelden zum Antworten