交换数组中两个元素的函数无法正常工作

4

我是C#的新手,但不明白为什么这段代码不能运行。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            char[] sw = "ab".ToCharArray();
            swap(sw[0], sw[1]);
            string end = new string(sw);
            Console.Write(end);
        }

        static void swap(char a, char b)
        {
            char temp = a;
            a = b;
            b = temp;
        }
    }
}

我期望在控制台上看到的是"ba",但是实际上却得到了"ab"。我找到了其他解决此问题的方法,但我想知道这段代码中的错误在哪里。 感谢您的帮助!

5个回答

12

问题在于swap方法实际上只是操作了ab的本地副本。您需要通过引用传递参数。因此,您应该像这样定义swap方法:

    static void swap(ref char a, ref char b)
    {
        char temp = a;
        a = b;
        b = temp;
    }

像这样调用:

    swap(ref sw[0], ref sw[1]);

这可能是正确的方式! - Alexander Bell
@AlexBell 我同意这可能是交换的最佳方式,因为它非常简单。但我通常尝试避免使用 ref 关键字,因为在我看来它往往会导致 API 更加混乱。 - Steven Wexler
这正是我会做的事情,但要使Swap成为通用的,以便它适用于任何数组,然后将其放入某些实用程序类中。 - Lukazoid

3
应该像下面这样修改(注意:在此示例中,ref char[] arr 前缀为 ref 主要是为了教学目的:数组默认将通过 ref 传递)
namespace ConsoleApplication1
{

        class Program
        {
            static void Main(string[] args)
            {
                char[] sw = "ab".ToCharArray();
                swap(0, 1, ref sw );
                string end = new string(sw);
                Console.Write(end);
            }

            static void swap(int indexA, int indexB, ref char[] arr)
            {
                char temp = arr[indexA];
                arr[indexA] = arr[indexB];
                arr[indexB] =temp;
            }
        }
    }

3

一个更通用的数组交换函数:

    public static void Swap<T>(this T[] array, int indexA, int indexB)
    {
        T temp        = array[indexA];
        array[indexA] = array[indexB];
        array[indexB] = temp;
    }

此外还有一个通用的函数,可以交换多个数组元素:

    public static void Swap<T>(this T[] array, int indexA, int indexB, int length)
    {
        while (length-- > 0)
            Swap(array, indexA++, indexB++);
    }

1
你的交换函数接受两个值类型并交换变量之间的值。这里没有任何会修改原始数组的内容。你需要将你的交换方法修改为以下形式:
static void Swap(char[] array, int a, int b)
{
    char temp = array[a];
    array[a] = array[b];
    array[b] = temp;
}

您可以像这样从Main()调用它:

Swap(array, 0, 1);

0

你正在通过值传递参数ab
请参阅按引用传递与按值传递有什么区别?以获取更多信息。

以下是两种解决方案来修复你的问题。

//Pass by value and return the values
static Tuple<char, char> swap2(char a, char b)
{
    char temp = a;
    a = b;
    b = temp;
    return new Tuple<char, char>(a, b);
}

//Pass by reference
static void swap3(ref char a, ref char b)
{
    char temp = a;
    a = b;
    b = temp;
}

public static void Main(string[] args)
{
    char[] sw2 = "ab".ToCharArray();
    var chars2 = swap2(sw2[0], sw2[1]);
    sw2[0] = chars2.Item1;
    sw2[1] = chars2.Item2;
    //Will print "ba"
    Console.WriteLine(sw2);

    char[] sw3 = "ab".ToCharArray();
    swap3(ref sw3[0], ref sw3[1]);
    //Will print "ba"
    Console.WriteLine(sw3);
}

这是一个关于是否应该使用或避免 ref 关键字的问题。除了最简单的用法外,通常建议在可能的情况下避免使用 ref。交换属于“最简单的用法”类别,但我建议在大多数实际情况下都尽量避免使用 ref。
什么时候使用 C# 的 ref 关键字是个好主意?

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接