C:自定义strlen()库函数

时间:2016-09-11 17:51:48

标签: c types char sizeof strlen

我创建了strlen()函数的版本。

unsigned int my_strlen(char *p)
{
    unsigned int i = 0;

    while(*p!='\0')
    {
        i++;
        p++;
    }

    return i;
}

每次运行时它都会给我正确的输出。但我的同事们说这段代码可能会导致字符长度大于1 byte的系统出现问题。是这样吗??

所以他们修改了如下代码:

unsigned int my_strlen(char *p)
{
    unsigned int i = 0;
    char *start = p;

    while(*p!='\0')
    {
        i++;
        p++;
    }

    return p - start;
}

我一直认为在C中一个字符长1个字节。

前片段是否优于后者,反之亦然?

6 个答案:

答案 0 :(得分:6)

C保证sizeof(char)为1,所以你是对的。

要添加一些真实性,请直接引用C11,章节§6.5.3.4, sizeof_Alignof运算符

  

sizeof应用于类型为charunsigned char的操作数时,或者   signed char,(或其合格版本),结果为1. [....]

也就是说,指针算术尊重数据类型,所以第二种方法在期望的方面没有任何意义。两种情况都是pchar*,因此效果会相同。

答案 1 :(得分:1)

当您使用sizeof(char)时,您将指针递增sizeof(char)。因此,它与stormpath: application_name: APPLICATION_NAME api_key_id: KEY_ID api_key_secret: SECRET_KEY 无关,即使它在不同机器之间是可变的。你的同事错了。

注意:如果你想计算字节数而不是字符数,那么你的同事可能是正确的(如果char不能保证是1个字节,但确实如此)。如果你想计算角色数量,那么你的同事们就错了。

答案 2 :(得分:0)

虽然其他人回答了您关于字符大小的问题,但您的版本仍然不正确。

现行标准(ISO / IEC 9899:2011)简短而精确:

  

7.24.6.3 strlen功能

     

<强>概要

    #include <string.h>`<br>
    size_t strlen(const char *s);
     

<强>描述

     

2 strlen函数计算s指向的字符串的长度。

     

<强>返回

     

3 strlen函数返回前面的字符数   终止空字符。

因此完全兼容的功能将是

size_t stringlength(const char *s){
  size_t i = 0;
  while(s && *s != '\0'){
      s++;
      i++;
  }
  return i;
}

主要区别在于它检查输入(可能是NULL,但是例如:glibc的strlen段错误。如果你想要它是段错误的,请删除s == NULL中的size_t Segfaulting可能是更好的选择,否则你会得到我们喜欢称之为“Heisenbugs”的那种bug。当你看到它们并且它们的波形崩溃时,它们会消失,并使用wsclen()作为输出。

如果可能的话,Glibc版本会同时处理几个字节 - 不知道这样的优化是否有用。

如果你想要等同于#include <wchar.h> size_t wstringlength(const wchar_t *s){ size_t i = 0; while(s[i] != L'\0'){ i++; } return i; } ,你可以这样做:

mbrlen()

计算多字节字符(mbrtowc()仅检查一个字符,但您可以使用QString text = model()->headerData(logicalIndex, orientation(), Qt::DisplayRole).toString(); )非常复杂,超出了这篇短文的范围。

答案 3 :(得分:0)

OP发布了“字符的长度大于1个字节”,而不是char。当将字符限制为charsigned charunsigned char时,OP是正确的。那3个总是的大小为1。

OP的同事们可能并非都认为具有限制性意义。 C规范有许多字符类型:单字节字符多字节字符扩展字符宽字符,不是全1字节。

修改后的代码有弱点。它与“字符长度大于1个字节”无关。而且,i++;毫无意义。返回类型unsigned可能不足。使用size_t表示既不太宽也不窄的无符号类型。

// simplify
size_t my_strlen2(const char *p) {
    const char *start = p;
    while(*p) p++;
    return (size_t) (p - start);
}
  

前片段是否优于后者,反之亦然?

不会返回不会溢出的类型。

答案 4 :(得分:0)

strlen函数,使用for

size_t my_strlen(const char *s) {

    size_t n;

    for (n = 0; *s; s++)
        n++;
    return n;
}

或者:

size_t n;

for (n = 0; *s != '\0'; s++)
    n++;
return n;

或者:

size_t n;

for (n = 0; *(s++); )
    n++;
return n;

或者:

size_t n;

for (n = 0; *s; n++)
    s++;
return n;

或者:

size_t n = 0;
int i;

for (i = 0; s[i]; i++)
    n++;
return n;

答案 5 :(得分:-2)

就指针算法而言,在使用char为2个字节的平台上,它不会给你不同的结果,因为你正在处理指针和指针算术总是坚持数据类型。 这是另一种查找字符串len的方法,它不使用指针airthmetic -

int len  = -1;
while(p[++len] != '\0');
return len;