如何在c#中实现strlen()?

如何在c#中实现strlen()?,c#,string,C#,String,我正在考虑一个解决方案,在不使用length属性的情况下计算c#中字符串的长度 我能想到的是完成这件事 程序是C# 但这是非常幼稚的编程,它还使用了一个额外的temp变量 你们能想出比这更好的解决办法吗 public static int strlen2 (string s) { int length = 0; foreach (char c in s) length++; return length } 我不知道这样做的意义何在。如果您想要最有效的方式,可以尝试模仿M

我正在考虑一个解决方案,在不使用
length
属性的情况下计算c#中字符串的长度

我能想到的是完成这件事

程序是C#

但这是非常幼稚的编程,它还使用了一个额外的temp变量 你们能想出比这更好的解决办法吗

public static int strlen2 (string s) {
    int length = 0;
    foreach (char c in s) length++;
    return length
}

我不知道这样做的意义何在。

如果您想要最有效的方式,可以尝试模仿Microsoft自己的String.Length函数。启动并加载一个名为String.Length的小样本解决方案。然后,您可以简单地深入到依赖项中,甚至进行一些反汇编


问题在于字符串在C#中的存储方式。在某些语言中,计算字符串的长度需要计算,而在C#中,计算字符串长度的唯一方法是通过其length属性。如果你想知道字符串是如何存储的,那么有一个字符数组和一个长度。现在,字符串不是以null结尾的,因此在开始读取不属于数组的内存之前,需要使用长度字段来知道可以访问多少数组。不过,您可以通过抽象来隐藏您正在做的事情。例如,您可以调用ToCharArray函数,但为了生成您使用的以null结尾的字符串,它首先必须访问长度值,以便为char[]数组分配适当数量的内存,并复制适当数量的字符。或者你可以用一个 对于每个(字符c/s)长度++


正如其他人建议的那样。这是另一种隐藏正在访问长度值的事实的方法。为了以这种方式迭代字符,必须首先访问长度值以查看迭代的字符数。无论它是在库调用中执行此操作,还是将其编译为不同的构造,我不确定,但最终结果是相同的。

我认为要优化Leiz的答案,我会在第3行使用预增量而不是后增量来阅读:

foreach(char c in s) ++length

这会压缩一点性能。

您可以使用不安全的代码以O(1)的速度获取长度,因为C#字符串的前缀是长度-这可能是get#u length函数内部的功能(这就是为什么您应该使用内置方式而不是编写自己的代码):

或者,如果您更喜欢传统的学校式方法:

public static unsafe int strlen(string s) 
{
    if(s == null) {
        // Handle the error here
    }

    int length = 0;

    fixed(char *pStr = s) {
        char *pEnd   = pStr;    
        while(*pEnd++ != '\0'); 
        length = (int)((pEnd - pStr) - 1);            
    }

    return length;
}

关于在C中实现strlen有很多面试问题……我想在C中实现它……因为我对C不太了解……因此问这个问题听起来很像是从C/C++中“迁移”过来的C作业问题。您的代码可以工作,但产生了错误的结果。当字符串接近“/0”字符时,将不必要地减去长度。这是因为当您达到这一点时,代码不会增加长度。它将返回一个与实际长度相差-1的结果。@Nippysaurus这肯定是有史以来最愚蠢的问题之一。投票被否决,因为在C#中考虑字符串,尤其是Unicode,这确实是错误的。只需使用.Length属性,然后转到更有趣的内容。不,字节码不会相同。增量长度。如果++是表达式的一部分,则会生成不同的字节码,但在您的示例中,结果是相同的。使用preincrement不会浪费时间创建临时变量,使原始变量递增,然后返回temp吗?内部字符串null以c#?..结尾吗?不,您如何使用以下内容语句while(*pEnd++!='\0')?是的,.NET字符串基本上都是BSTR的长度前缀、双字节和以空结尾的。这种“老派”的方法是行不通的。我刚刚用“d\0g”(embedded null)尝试了第二个示例,它返回了1。这是正确的。您不能将空字符嵌入到以空结尾的字符串中,而期望算法神奇地将其提取。@arul-我的观点是,它不能安全地视为以空结尾的字符串,因为.NET字符串允许嵌入空字符(并且在使用标准属性/方法时,仍然可以正常工作)。您所做的假设(没有嵌入null)在.NET中并不总是有效。NET字符串以null结尾。但终止字符有点透明。@anul-内存是否以0字节结尾无关紧要。它们可以包含空字符。这将打印3:char numl='\0';字符串embeddedNull=“1”+nul+“3”;Console.WriteLine(embeddedNull.Length);
public static unsafe int strlen(string s) 
{
    if(s == null) {
        // Handle the error here
    }

    int length = 0;

    fixed(char *pStr = s) {
        length = *(((int *)pStr) - 1);
    }

    return length;
}
public static unsafe int strlen(string s) 
{
    if(s == null) {
        // Handle the error here
    }

    int length = 0;

    fixed(char *pStr = s) {
        char *pEnd   = pStr;    
        while(*pEnd++ != '\0'); 
        length = (int)((pEnd - pStr) - 1);            
    }

    return length;
}