4 Stimmen

Können ein Zeichenfolgenliteral und ein Zeichenliteral verkettet werden?

Warum ist name sich im folgenden C++-Code falsch verhalten?

string name =  "ab"+'c';

Wie würde sich der entsprechende Code in Java/C# verhalten?

13voto

Eclipse Punkte 43775

トライ

std::string name = "ab" "c";

oder

std::string name = std::string("ab") + c;

In C++ ist "ab" kein std::string sondern ein Zeiger auf eine Zeichenkette. Wenn Sie einem Zeiger einen ganzzahligen Wert hinzufügen, erhalten Sie einen neuen Zeiger, der weiter unten in der Zeichenfolge steht:

char *foo = "012345678910121416182022242628303234";
std::string name = foo + ' '; 

name wird auf "3234" gesetzt, da der Integer-Wert von ' ' 32 ist und 32 Zeichen hinter dem Anfang von foo vier Zeichen vor dem Ende der Zeichenkette liegen. Wäre die Zeichenkette kürzer, würden Sie versuchen, auf etwas im undefinierten Speicherbereich zuzugreifen.

Die Lösung für dieses Problem besteht darin, aus dem Zeichenarray einen std:string zu machen. std:strings erlauben es, wie erwartet Zeichen an sie anzuhängen:

std::string foo = "012345678910121416182022242628303234";
std::string name = foo + ' '; 

name wird auf "012345678910121416182022242628303234" gesetzt.

8voto

jalf Punkte 235501

Das Problem ist, dass "ab" kein C++ ist. std::string sondern ein const char[3] . Der gesuchte +-Operator lautet also operator+ (const char[3], char) . Das gibt es nicht, also versucht der Compiler, das Array in einen Zeiger zerfallen zu lassen, also sucht er nach operator+ (const char*, char) . Das gibt es, also wählt der Compiler es aus, aber er tut das Falsche. Das Hinzufügen eines ganzzahligen Wertes (char) zu einem Zeiger (const char*) ist eine ganz gewöhnliche Operation, und genau das macht dieser Operator+ natürlich auch. Der Schlüssel zum Verständnis ist die Erkenntnis, dass das erste Argument 1) ein Array ist und 2) ein Zeiger, wenn Array keinen Sinn ergibt. Es wurde auch in C als String verwendet, ja, aber es ist kein String. Es ist ein Zeiger (oder gelegentlich auch ein Array).

Es gibt eine operator+ (const std::string&, char) das verkettet, aber der Compiler sucht nicht einmal danach, weil das erste Argument kein std::string ist.

Eine Lösung besteht also darin, die Zeichenfolge manuell zu erstellen:

string name = std::string("ab")+'c';

Jetzt kann der Compiler herausfinden, welcher Operator+ aufgerufen werden muss.

5voto

greyfade Punkte 24134

In C++ sucht der Compiler nach einer Funktion mit diesem Prototyp:

T operator+ (const char*, char);

Da es keine gibt, kann es nicht herausfinden, was T ist, und kann das Problem nicht lösen. operator<< aufruft, greift er auf die einzige verbleibende Lösung zurück: die Zeigeraddition. Es gibt kein Problem mit der Verkettung zu einer Zeichenkette wie in der Antwort von Josh, da eine Funktion dafür existiert.

3voto

Tom Hawtin - tackline Punkte 142461

Angesichts des C++-Codes:

std::string name =  "ab"+'c';

Die Entsprechung in Java ist:

String name = "ab".substring('c');

Beide machen char zu int. Natürlich wird in Java der Bereich geprüft und daher eine Ausnahme ausgelöst. In C++ erhalten Sie einfach undefiniertes Verhalten (oder so ähnlich).

2voto

TofuBeer Punkte 59410

Java:

public class Main
{
    public static void main(String[] args)
    {
        System.out.println("AB" + 'c');
    }
}

Die Ausgabe ist:

ABc

編集する。

Eigentlich kodiert der Compiler den String ABc hart...

Wenn Sie "AB" + argv[0].charAt(0); eingeben, um eine Variable zu verwenden, macht der Compiler (im Grunde) genau das:

StringBuilder b = new StringBuilder;
b.append("AB");
b.append(argv[0].charAt(0));
System.out.println(b.toString());

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X