【问题标题】:Rewriting strlen() in C [closed]在 C 中重写 strlen() [关闭]
【发布时间】:2014-11-14 04:52:12
【问题描述】:

如果有人想尝试重写C 中的字符串函数,那么这段代码是否可以替换标准的strlen() 函数? 我无法运行此代码,因为我正坐在车里在 iPhone 上输入它。

int strlen(char * s) {
      int i = 0, sum = 0;
      char c = s[0];

      while(c != '\0') {
            sum++;
            c = s[++i];
      }
      return sum;
}

非常感谢您的反馈!

【问题讨论】:

  • 只改名字,因为真正的函数同名!还有什么问题?你开始了一个问题,而不是一个博客!
  • strlen 返回size_t。从性能的角度来看,您的函数要击败标准函数还有很多工作要做。阅读How the glibc strlen() implementation works
  • Code Review上询问代码审查功能。
  • 你的车在动吗?如果是,我建议你停止编程。
  • 这个问题似乎跑题了,因为它是关于代码审查的。

标签: c string function


【解决方案1】:

如果你想重写标准C函数strlen,那么你应该关注函数的the declaration conventions

size_t strlen(const char *s);

首先,它应该有返回类型size_t,并且参数应该有限定符const,你可以使用带有常量字符数组的函数。 像sum 这样的名字也不太适合这个功能。在你的函数中,你有太多的局部变量。

我会这样写函数

size_t strlen( const char *s ) 
{
    size_t n = 0;

    while ( s[n] ) ++n;

    return n;
}

另一种方法是只使用指针。例如

size_t strlen( const char *s ) 
{
    const char *p = s;

    while ( *p ) ++p;

    return p - s;
}

【讨论】:

  • 不清楚为什么有人DV这个? +1 最佳答案。
  • @chux 不要寻求任何理由。只是有人不希望我的回答被赞成。:)
【解决方案2】:

看起来它可以工作,但你不需要 2 个整数,所以它过于复杂。 [] 查找可能很慢 - 指针操作可能会更快。

int myStrlen(char *s)
{
    int len = 0;
    while(*s != 0) {
        s++;
        len++;
    }
    return len;
}

【讨论】:

  • 这点非常正确。谢谢!!
  • @John 一个疑问...字符串以 '/0' 结尾,那么我们为什么要将 *s 与 0 进行比较?
  • 如果你想明确一点,你可以使用'\0',但0也可以。
【解决方案3】:

不需要int 计数器。

size_t myStrlen(char *s)
{
 char *e=s;
 while(*e!='\0')e++;
 return e-s;
}

【讨论】:

    【解决方案4】:

    它应该工作。同时功能可以优化。类似的东西

     int my_strlen(char *s) {
        int sum = 0;
        while (*s++) sum++;
        return sum;
     }
    

    【讨论】:

      【解决方案5】:

      以下是为 strlen 编写代码的不同方法:

      不使用指针:

      int mystrlen(char s[]) {

      int i = 0;
      
      while (s[i]!='\0')
       {
        i++;
       }
      

      返回 i;

      }

      使用指针:

      int strlength(char const *s) {

      int l=0;                                                    
      
      while(*s1!='\0')                                      
      {
        l++;
        s++;
      }
      
      return l;                                              
      

      }

      无计数器:

      int my_strlen(char const *s) {

      char *p=s;
      
      while(*p!='\0')
           p++;
      
      return(p-s);
      

      }

      使用递归:

      int mystrlen(char const *s) {

       if(*s==0) 
            return 0;
      
       return mystrlen(s+1)+1;
      

      }

      【讨论】:

        【解决方案6】:

        实际的功能比你写的要多得多。

        • 考虑一个场景,您为指针分配了 100 的大小。而且您忘记添加 '\0' 作为数组的最后一个字符。你将如何处理这种情况?你不能继续增加计数器并继续寻找'\0'

        • 数组有一个最大尺寸。您的指针字符串长度函数也应该具有实际长度。你不能继续迭代计数器并寻找'\0'。如果您进入另一个进程的内存位置并开始读取和写入该应用程序内存怎么办?您最终会弄乱多个应用程序。

        • 根据编译器的类型,它可能会也可能不会按顺序分配内存。你将如何处理这种情况?

        简而言之,您应该首先处理 malloc/new。端到端地理解它,然后尝试解决这个问题。

        【讨论】:

        • 边界检查通常不使用 C 数组和字符串来完成......这取决于程序员来跟踪。即使没有 home-rolled 函数,在未终止的字符串上调用 strlen() 引起的崩溃也并不罕见。
        • C always 中的 string 有一个终止 '\0',否则它不是字符串。 OP 说“字符串函数”,所以char * s 总是指向以'\0' 结尾的内存。 OTOH,OP 本可以要求 char 数组的长度,正如这个答案所建议的那样。不错的主意,但函数名不应该是str..()
        • 如果我创建了一个 char 数组,并且如果我没有将最后一个 char 指定为 '\0',那么当我尝试访问分配的内存时,编译器会抛出相关警告。没有handlig如何实现?
        • @kris123456 如果strlen() 进行边界检查,它会给出运行时错误,而不是编译器错误......但它不可能,因为数组长度不可用在运行时给它。确实使用数组长度的函数需要将其作为附加参数显式传递(strlen() 或 C 中的大多数其他字符串函数不这样做)。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-23
        • 1970-01-01
        • 2013-12-24
        • 2018-11-12
        相关资源
        最近更新 更多