代码之家  ›  专栏  ›  技术社区  ›  Ian

通过引用传递到C中的第n个元素#

  •  2
  • Ian  · 技术社区  · 9 年前

    在C语言中,如果我们有一个数组,我们可以通过引用函数来传递它。我们还可以使用简单的 (n-1) 从开始传递引用 n -数组的第个元素如下:

    char *strArr[5];
    char *str1 = "I want that!\n";
    char *str2 = "I want this!\n";
    char *str3 = "I want those!\n";
    char *str4 = "I want these!\n";
    char *str5 = "I want them!\n";
    strArr[0] = str1;
    strArr[1] = str2;
    strArr[2] = str3;
    strArr[3] = str4;
    strArr[4] = str5;
    printPartially(strArr + 1, 4); //we can pass like this to start printing from 2nd element
    
    ....
    
    void printPartially(char** strArrPart, char size){
    int i;
    for (i = 0; i < size; ++i)
        printf(strArrPart[i]);
    }
    

    导致这些:

    I want this!
    I want those!
    I want these!
    I want them!
    
    Process returned 0 (0x0)   execution time : 0.006 s
    Press any key to continue.
    

    在C#中,我们还可以将引用传递给 object 通过 ref (或者, out ). 对象包括数组,它是 整体 数组(或者至少,我认为它是这样工作的)。但我们如何通过引用 n -数组的第个元素,以便在函数内部,只有 string[] 其元素比原始元素少一个 字符串[] 而无需创建新阵列?

    我们必须使用 unsafe ? 我正在寻找一个没有 不安全的

    编辑:

    我知道我们可以通过 Array 在C#中,没有 裁判 关键字。也许我的问题听起来很误导 裁判 当我们谈论 大堆 .我为什么要 裁判 在那里,我宁愿这样说: 裁判 例如,可以使用关键字将引用传递给 n -数组的第个元素与C一样多,除了传递对任何元素的引用 对象 (未提及 n -th元素或类似元素)?我对我问题的措辞引起的任何误解表示歉意。

    5 回复  |  直到 9 年前
        1
  •  3
  •   Chris Shain    9 年前

    “安全”的方法是通过 ArraySegment 结构。

    当然,您可以使用不安全的c#传递指向字符的指针,但是您需要担心缓冲区溢出。

    顺便说一句,C#中的数组(通常)是在堆上分配的,所以正常传递它(没有ref)并不意味着复制数组——它仍然是传递的引用(只是一个新的引用)。

        2
  •  2
  •   Yves    9 年前

    编辑:

    你不能像在C语言中那样做 安全 密码

    C#数组(即。 string[] )派生自抽象类型 Array . 它不仅仅是一个简单的内存块 C .

    所以你不能发送它的一个元素的引用并从那里开始迭代。


    但是有一些解决方案会给你同样的味道(没有 不安全的 ):

    例如:

    • 正如@Chris提到的,你可以使用 ArraySegment<T> .
    • 大堆 也是一个 IEnumerable<T> 你可以使用 .Skip 并发送返回的值。(但这会给你一个 IEnumerable<T> 而不是 大堆 ). 但它将允许您迭代。
        3
  •  0
  •   René Vogt    9 年前

    如果该方法只应从数组读取,则可以使用linq:

    string[] strings = {"str1", "str2", "str3", ...."str10"};
    print(strings.Skip(1).Take(4).ToArray());
    
        4
  •  0
  •   B.Balamanigandan    9 年前

    你的困惑很常见。关键是要认识到“引用类型”和“通过引用传递”(ref键盘)是完全独立的。在这种特定情况下,由于string[]是一种引用类型(与所有数组一样),这意味着在传递对象时不会复制该对象,因此您总是引用同一个对象。

    C#代码的修改版本:

    string[] strArr = new string[5];
    strArr[0] = "I want that!\n";
    strArr[1] = "I want this!\n";
    strArr[2] = "I want those!\n";
    strArr[3] = "I want these!\n";
    strArr[4] = "I want them!\n";
    printPartially(strArr.Skip(1).Take(4).ToArray());
    
    void printPartially(string[] strArr)
    {
        foreach (string str in strArr)
        {
            Console.WriteLine(str);
        }
    }
    
        5
  •  0
  •   Voodu    6 年前

    问题很古老,但也许答案对某人有用。 从C#7.2开始,在这种情况下可以使用更多的类型,例如。 Span Memory .
    它们完全允许你在问题中提到的事情(以及更多)。
    Here's great article about them

    目前,如果您想使用它们,请记住添加 <LangVersion>7.2</LangVersion> 在项目的.csproj文件中使用C#7.2功能