0

以下のプログラムは、Gayle Laakmann McDowell 著「Cracking thecoding 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#でそれを変換しようとしています。Google で調査し、コードで遊んだ後、以下が私が持っているものです。私は初心者で、本当に立ち往生しています。期待する値が得られません。誰かが私が間違っていることを教えてもらえますか?

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不変なので、変更することはできません。stringただし、 aと文字の配列 ( ) の間で変換することはchar[]でき、それを変更することもできます。また、静的メソッドArray.Reverse()を使用して配列を逆にすることもできます。したがって、メソッドを記述する 1 つの方法は次のようになります。

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

条件でチェックしていることをより明確にしてみてください: if(str != null) while(*end != '\0')

また、その文字スワッピング コードに注意することもできます。そこに +/- があるようです。それがポインターの位置を更新することになっている場合は、それらの個別の操作を行うことをお勧めします。

于 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 に答える