[英]C: Custom strlen() library function
我创建了我的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 个字节长。
前一个片段比后者好还是反之亦然??
在 C 中保证sizeof(char)
为 1,所以你是对的。
为了增加一些真实性,直接引用C11
,章节 §6.5.3.4, sizeof
和_Alignof
运算符
当
sizeof
应用于具有char
、unsigned char
或signed char
类型(或其限定版本)的操作数时,结果为 1。 [....]
也就是说,指针算术尊重数据类型,所以无论如何,第二种方法在预期做什么方面没有任何意义。 在这两种情况下,您都在p
操作,即char*
,因此效果是相同的。
当您使用p++
,您将指针增加sizeof(char)
。 因此,即使sizeof(char)
在不同机器之间是可变的,它也无关紧要。 你的同事错了。
注意:如果你想计算字节数,而不是字符数,那么你的同事可能是正确的(如果不能保证 char 是 1 个字节,但它确实是)。 如果你要数字,那你的同事根本就错了。
尽管其他人回答了您有关字符大小的问题,但您的版本仍然不正确。
当前的标准 (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
segfaults。如果您希望它进行 segfault,请在循环中去除s == NULL
的测试。Segfaulting 可能是更好的选择,否则您会得到那种我们喜欢称之为“Heisenbugs”的错误。当你查看它们并且它们的波形崩溃时往往会消失的错误)并使用size_t
作为输出。
Glibc 版本在可能的情况下一次处理多个字节——不知道这样的优化是否有用。
如果你想要等效的wsclen()
你可以做这样的事情:
#include <wchar.h>
size_t wstringlength(const wchar_t *s){
size_t i = 0;
while(s[i] != L'\0'){
i++;
}
return i;
}
计算多字节字符( mbrlen()
检查一个字符,但您可以使用mbrtowc()
)非常复杂,超出了这篇短文的范围。
OP 发布了“字符长度大于 1 个字节”,而不是char
。 当将字符限制为仅char
、 signed char
、 unsigned 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);
}
前一个片段比后者好还是反之亦然??
两者都不返回不会溢出的类型。
使用for
strlen
函数:
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;
在指针算术方面,只要您处理指针和指针算术始终坚持数据类型,它就不会在具有 char 为 2 个字节的平台上给您不同的结果。 这是另一种查找字符串 len 的方法,它不使用指针 airthmetic-
int len = -1;
while(p[++len] != '\0');
return len;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.