2012-04-06 23 views
0

Das folgende Programm stammt aus dem Buch "Cracking the coding interview" von Gayle Laakmann McDowell.Kann den Typ 'char *' nicht implizit in 'bool' umwandeln

Der ursprüngliche Code ist in C geschrieben

Hier ist der ursprüngliche Code:

void reverse(char *str) { 
    char * end = str; 
    char tmp; 
    if (str) { 
     while (*end) { 
      ++end; 
     } 
     --end; 
     while (str < end) { 
      tmp = *str; 
      *str++ = *end; 
      *end-- = tmp; 
     } 
    } 
} 

ich es in C# zu konvertieren versuchen. Nachdem ich über Google recherchiert und mit dem Code gespielt habe, habe ich Folgendes: Ich bin ein Anfänger und wirklich fest. Ich bekomme nicht den Wert, den ich erwarte. Kann mir jemand sagen, was ich falsch mache?

class Program 
{   
    unsafe void reverse(char *str) 
    { 
     char* end = str; 
     char tmp; 
     if (str) // Cannot implicitly convert type 'char*' to 'bool' 
     { 
      while(*end) // Cannot implicitly convert type 'char*' to 'bool' 
      { 
       ++end; 
      } 
      --end; 
      while(str < end) 
      { 
       tmp = *str; 
       *str += *end; 
       *end -= tmp; 
      } 
     } 
    } 

    public static void Main(string[] args) 
    { 
    } 
} 
+10

AC# Beginner und bereits versuchen, unsichere Code-Schnipsel zu tun? – RvdK

+11

Wenn Sie Anfänger sind, warum ärgern Sie sich mit Zeigern und unsicherem Code? Lerne zuerst die Grundlagen !! –

+2

Ich denke nicht, dass jemand "etwas nicht tun!" ist eine gute Möglichkeit zu helfen. – llj098

Antwort

0

C# ist nicht wie C, da Sie keinen Integer-Wert als impliziten Bool verwenden können. Sie müssen es manuell konvertieren. Ein Beispiel:

if (str != 0) 
while (*end != 0) 

Ein Wort der Warnung: Wenn Sie von C migrieren, gibt es ein paar Dinge, die Sie oben in einem Programm wie diese stolpern können. Die wichtigste ist, dass char 2 Bytes ist. Zeichenfolgen und Zeichen sind UTF-16-codiert. Das C# -Aquivalent von char ist byte. Natürlich sollten Sie string statt C-Strings verwenden.

Eine andere Sache: Wenn Sie Ihre char* durch Umwandlung einer normalen string in eine char* haben, vergessen Sie Ihren gesamten Code. Dies ist nicht C. Strings sind nicht nullterminiert.

Es sei denn, dies ist Hausaufgaben, würden Sie viel eher so etwas wie dies tun:

string foo = "Hello, World!"; 
string bar = foo.Reverse(); // bar now holds "!dlroW ,olleH"; 
+0

C# Strings sind nicht 0, null oder beendet ‚\ 0‘. Also würde das while-Bit nicht funktionieren. Mir ist keine Methode bekannt, um es zum Laufen zu bringen. Ich denke, der einzige Weg ist, die Länge als Parameter zu übergeben. –

+1

Er verwendet keine Zeichenfolge. Ich habe keine Ahnung, wo er seinen 'char *' bekommt, aber wenn es eine Saite ist, ist das nicht gut. –

+0

@VladCiobanu eigentlich Strings in .Net * sind * nullterminierte, aber ich denke, es ist nur ein Detail Implementierung und Sie sollten sich nicht darauf verlassen. – svick

0

Probieren Sie es noch deutlicher zu machen, was Sie in den Bedingungen überprüft: (! Str = null) wenn while (* end! = '\ 0')

Sie sollten auch auf den Zeichenaustausch achten: Es sieht so aus, als hätten Sie ein +/- drin. Wenn das Ihre Zeigerpositionen aktualisieren soll, würde ich vorschlagen, diese separaten Operationen durchzuführen.

+0

C# hat nicht 'NULL', aber es hat' null'. – svick

+0

Guter Punkt, ich werde das bearbeiten. – LiquidAsh

0

Ich kann mich nicht wirklich erinnern, ob das jemals in C# funktioniert hat, aber ich bin mir ziemlich sicher, dass es jetzt nicht funktionieren sollte.

Um zu beginnen, indem Sie Ihre Frage beantworten. Es gibt keine automatische Umwandlung zwischen Zeigern und Bool. Sie müssen schreiben

if(str != null) 

Zweitens können Sie Char nicht in Bool konvertieren. Darüber hinaus gibt es kein abschließendes Zeichen für C# -Strings, so dass Sie dies nicht einmal implementieren können. Normalerweise würden Sie schreiben:

while(*end != '\0') // not correct, for illustration only 

Aber es gibt kein '\ 0' char oder jede andere Magie-termination-Zeichen. Sie müssen also einen int-Parameter für die Länge nehmen.

Zurück zum großen Bild scheint diese Art von Code wie ein schrecklich unpassender Ort, um C# zu lernen. Es ist viel zu niedrig, nur wenige C# -Programmierer beschäftigen sich täglich mit Zeigern, Zeichen und unsicheren Kontexten.

...und wenn Sie wissen müssen, wie Sie Ihren aktuellen Code zu beheben, ist hier ein Arbeitsprogramm:

unsafe public static void Main(string[] args) 
{ 
    var str = "Hello, World"; 
    fixed(char* chr = str){ 
    reverse(chr, str.Length); 
    } 
} 

unsafe void reverse(char *str, int length) 
    { 
     char* end = str; 
     char tmp; 
     if (str != null) //Cannot implicitly convert type 'char*' to 'bool' 
     { 
     for(int i = 0; i < length; ++i) //Cannot implicitly convert type 'char*' to 'bool' 
     { 
      ++end; 
     } 
     --end; 
      while(str<end) 
      { 
       tmp = *str; 
       *str = *end; 
       *end = tmp; 
       --end; 
       ++str; 
      } 
     } 
    } 

Edit: entfernt, um ein paar .dump() ruft, wie ich es versuchte, in LINQPad aus :)

+0

Es gibt * ein * '\ 0''-Zeichen, aber es ist kein abschließendes Zeichen. Ich vermute allerdings, dass es in diesem Fall wäre. Das riecht nach C-Strings. –

0

Wie Sie festgestellt haben, können Sie Zeiger in C# verwenden, wenn Sie das Schlüsselwort unsafe verwenden. Aber du solltest das nur tun, wenn es wirklich notwendig ist und wenn du wirklich weißt, was du tust. Sie sollten sicherlich keine Zeiger verwenden, wenn Sie gerade mit der Sprache anfangen.

Nun zu Ihrer eigentlichen Frage: Sie haben eine Reihe von Zeichen gegeben werden, und Sie wollen es umkehren. Zeichenfolgen in C# werden als string Klasse dargestellt. Und string ist unveränderlich, so dass Sie es nicht ändern können. Aber Sie können zwischen einem string und einem Array von Zeichen konvertieren (char[]) und Sie können das ändern. Und Sie können ein Array umkehren, indem Sie the static method Array.Reverse() verwenden. Also, eine Möglichkeit, Ihre Methode zu schreiben wäre:

string Reverse(string str) 
{ 
    if (str == null) 
     return null; 

    char[] array = str.ToCharArray(); // convert the string to array 
    Array.Reverse(array);    // reverse the array 
    string result = new string(array); // create a new string out of the array 
    return result;      // and return it 
} 

Wenn Sie den Code schreiben wollen, die tatsächlich funktioniert die Umkehrung, können Sie das auch tun (als Übung, würde ich es nicht in Produktionscode):

string Reverse(string str) 
{ 
    if (str == null) 
     return null; 

    char[] array = str.ToCharArray(); 

    // use indexes instead of pointers 
    int start = 0; 
    int end = array.Length - 1; 

    while (start < end) 
    { 
     char tmp = array[start]; 
     array[start] = array[end]; 
     array[end] = tmp; 
     start++; 
     end--; 
    } 

    return new string(array); 
} 
Verwandte Themen