0

下面的程序来自 Gayle Laakmann McDowell 的《Cracking the coding interview》一书。

原始代码是用 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)
    {
    }
}
4

4 回答 4

0

正如您所发现的,如果您使用unsafe关键字,则可以在 C# 中使用指针。但是,只有在真正必要并且您真正知道自己在做什么时,您才应该这样做。如果您刚开始使用该语言,那么您当然不应该使用指针。

现在,对于您的实际问题:给您一个字符串,并且您想要反转它。C# 中的字符串表示为string类。并且string是不可变的,所以你不能修改它。但是您可以在 astring和字符数组 ( char[]) 之间进行转换,并且可以对其进行修改。您可以使用静态方法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);
}
于 2012-04-06T23:39:33.483 回答
0

Try making it more explicit what you are checking in the conditions: if(str != null) while(*end != '\0')

You might also want to watch out for that character swapping code: it looks like you've got a +/- in there. If that's supposed to update your pointer positions, I'd suggest making those separate operations.

于 2012-04-06T11:37:40.743 回答
0

I can't really remember if this ever worked in C#, but I am quite certain it should not work now.

To start off by answering your question. There is no automatic cast between pointers and bool. You need to write

if(str != null)

Secondly, you can't convert char to bool. Moreover, there is no terminating character for C# strings, so you can't even implement this. Normally, you would write:

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

But there is no '\0' char, or any other magic-termination-char. So you will need to take an int param for length.

Going back to the big picture, this sort of code seems like a terribly inappropriate place to start learning C#. It's way too low level, few C# programmers deal with pointers, chars and unsafe contexts on a daily basis.

... and if you must know how to fix your current code, here's a working program:

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: removed a couple of .Dump() calls, as I was trying it out in LINQPad :)

于 2012-04-06T11:40:07.033 回答
0

C# 与 C 不同,因为您不能将整数值用作隐式布尔值。您需要手动转换它。一个例子:

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

一句警告:如果你是从 C 语言迁移的,那么在这样的程序中会有一些事情会让你绊倒。主要的char是2字节。字符串和字符是 UTF-16 编码的。的 C# 等效项charbyte. 当然,您应该使用string而不是 C 字符串。

另一件事:如果您char*通过将 normal 转换为 astring来获得您的char*,请忘记您的整个代码。这不是 C。字符串不是以空值结尾的。

除非这是家庭作业,否则你宁愿做这样的事情:

string foo = "Hello, World!";
string bar = foo.Reverse(); // bar now holds "!dlroW ,olleH";
于 2012-04-06T11:31:17.660 回答