2012-04-06 273 views
0

下面的程序來自Gayle Laakmann McDowell編寫的「Cracking the coding interview」一書。無法將類型'char *'隱式轉換爲'bool'

原始代碼是用C寫

這裏是原代碼:

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

我想它轉換成C#。經過谷歌研究和玩代碼,下面是我的。我是一個初學者,真的陷入困境。我沒有得到我期待的價值。有人能告訴我我做錯了什麼嗎?

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並已經試圖做不安全的代碼片段? – RvdK 2012-04-06 11:26:37

+11

如果你是初學者,你爲什麼要搞亂指針和不安全的代碼?首先了解基礎知識! – 2012-04-06 11:26:43

+2

我不認爲這是告訴別人「不要做點什麼!」是一種很好的幫助方式。 – llj098 2012-04-06 11:36:05

回答

0

C#不像C那樣你不能使用整數值作爲隱式布爾值。您需要手動將其轉換。舉個例子:

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

一句警告:如果您在C遷移,有可能你絆倒在這樣的節目的幾件事情。主要的是char是2個字節。字符串和字符是UTF-16編碼的。 C#相當於charbyte。當然,你應該使用string而不是C字符串。

另一件事:如果你通過將一個正常的string轉換爲char*來得到你的char*,忘記你的整個代碼。這不是C.字符串不是空終止的。

除非這是功課,你寧願是這樣做的事情:

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

C#字符串不是0,null或'\ 0'終止。所以,這一點是行不通的。我不知道有什麼方法可以使它工作。我認爲唯一的方法是通過傳遞參數的長度。 – 2012-04-06 11:42:08

+1

他沒有使用字符串。我不知道他在哪裏得到'char *',但如果它是一個字符串,這不好。 – 2012-04-06 11:43:36

+0

@VladCiobanu,實際上,.Net *中的字符串是*零終止的,但我認爲它只是一個實現細節,你不應該依賴它。 – svick 2012-04-06 23:19:27

0

嘗試使之更明確你所檢查的條件:(!STR = NULL) 如果 而( * end!='\ 0')

你可能還想留意那個字符交換代碼:看起來你在那裏有+/-。如果這應該更新你的指針位置,我會建議做出這些單獨的操作。

+0

C#沒有'NULL',但它確實有'null'。 – svick 2012-04-06 23:22:58

+0

好點,我會編輯它。 – LiquidAsh 2012-04-23 18:25:51

0

我真的不記得這是否曾在C#中工作過,但我相當肯定它現在不應該工作。

開始回答你的問題。指針和布爾之間沒有自動轉換。您需要編寫

if(str != null) 

其次,您不能將char轉換爲bool。而且,C#字符串沒有終止字符,所以你甚至不能實現這個。通常情況下,你會寫:

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

但沒有'\ 0'字符,或任何其他magic-termination-char。所以你將需要一個int參數的長度。

回過頭來看,這類代碼看起來像是一個非常不合適的地方開始學習C#。它的程度太低,很少有C#程序員每天處理指針,字符和不安全的上下文。

...如果你必須知道如何解決當前的代碼,這裏的工作程序:

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; 
      } 
     } 
    } 

編輯:刪除一對夫婦使用.dump()來電,因爲我想出來的LINQPad :)

+0

有*是*''\ 0''字符,但它不是終止字符。我猜,但在這種情況下,它會。這是C字符串的反射。 – 2012-04-06 11:42:36

0

正如您發現的,如果您使用unsafe關鍵字,則可以在C#中使用指針。但是,只有在真正需要的時候以及在真正瞭解自己在做什麼的時候,你才應該這樣做。如果你剛開始使用這種語言,你當然不應該使用指針。

現在,對於您的實際問題:給您一串字符並且您想要將其反轉。 C#中的字符串表示爲string類。而string是不可變的,所以你不能修改它。但是你可以在string和一個字符數組(char[])之間進行轉換,你可以修改它。並且您可以使用the static method Array.Reverse()來反轉陣列。所以,寫你的方法,一個方法是:

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 
} 

如果你想寫實際執行倒車的代碼,你也可以這樣做(作爲一個練習,我不會做它在生產代碼):

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); 
} 
相關問題