不能将类型“char*”隐式转换为“bool”

本文关键字:bool 转换 类型 char 不能 | 更新日期: 2023-09-27 18:30:20

下面的程序来自Gayle Laakmann McDowell的"破解编码访谈"一书。

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

不能将类型“char*”隐式转换为“bool”

我真的不记得这是否在 C# 中有效,但我很确定它现在应该不起作用。

首先回答您的问题。指针和布尔值之间没有自动转换。你需要写

if(str != null)

其次,您不能将字符转换为布尔值。此外,C# 字符串没有终止字符,因此您甚至无法实现这一点。通常,你会写:

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

但是没有"''0"字符或任何其他魔法终止字符。因此,您需要使用整数参数作为长度。

回到大局,这种代码似乎是一个非常不适合开始学习 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 :) 中尝试过

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

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

警告:如果你从 C 迁移,有一些事情可能会在这样的程序中绊倒你。主要的是char是 2 个字节。字符串和字符采用 UTF-16 编码。char的 C# 等效项是 byte 。当然,你应该使用string而不是 C 字符串。

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

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

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

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

现在,对于您的实际问题:您得到了一串字符,并且想要反转它。C# 中的字符串表示为 string 类。而且string是不可变的,因此您无法修改它。但是你可以在string和字符数组(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);
}

尝试更明确地说明您在条件中检查的内容: if(str != null) 而(*结束!= '''0')

您可能还需要注意该字符交换代码:看起来您那里有一个 +/-。 如果这应该更新您的指针位置,我建议进行这些单独的操作。