一行代码实现 C strlen()

问题描述 投票:0回答:9

昨天我参加面试,被要求在不使用任何标准函数的情况下用 C 语言实现 strlen(),全部用手实现。作为一个绝对的业余爱好者,我用 while 循环实现了原始版本。看到这个我的面试官说只需一行代码就可以实现。当时我无法使用该术语生成此代码。面试后我问了我的同事,他们中最有经验的给了我这个作品,效果真的很好:

size_t str_len (const char *str)
{
    return (*str) ? str_len(++str) + 1 : 0;
}

那么有一个问题,不使用递归是否可以,如果可以,如何实现? 条款:

  • 无需任何汇编器
  • 库中不存在任何 C 函数
  • 不只是拼写几串代码

请注意,这不是优化或实际使用的问题,只是完成任务的可能性。

c algorithm strlen
9个回答
16
投票

与@DanielKamilKozar的答案类似,但是使用for循环,您可以在没有for循环体的情况下执行此操作,并且

len
在函数中正确初始化:

void my_strlen(const char *str, size_t *len)
{
    for (*len = 0; str[*len]; (*len)++);
}

9
投票

我能想到的最好的就是这个,但这不是标准

strlen
,因为函数本身有不同的原型。此外,它假设
*len
在开始时为零。

void my_strlen(const char *str, size_t *len)
{
        while(*(str++)) (*len)++;
}

我很好奇如何在“一行代码”中实现标准

strlen
,因为根据您发布的内容判断,它需要一个
return
,即“一行代码”。

也就是说,我确实同意评论说这是一个非常愚蠢的面试问题。


7
投票
size_t str_len (const char *str)
{
    for (size_t len = 0;;++len) if (str[len]==0) return len;
}

2
投票

如果这不一定是一个函数,那么这个一行可能是计算任何以 null 结尾的数组的长度的最简单、最短的方法(不包括变量声明和打印):

int main() {
    const char *s = "hello world";
    int n = 0;

    while (s[++n]);

    printf ("%i\n", n);
    return 0;
}

如果它必须是一个函数,那么你不能有一个像 strlen() 那样精确的函数签名,因为返回必须在单独的行中。否则你可以这样做:

void my_strlen(int* n, const char* s) {
    while (s[++(*n)]);
}

int main() {
    const char *s = "hello world";
    int n = 0;

    my_strlen(&n, s);

    printf ("%i\n", n);
    return 0;
}

1
投票

空的 for 循环怎么样?喜欢

int i=0;
for(; str[i]!=0; ++i);

1
投票

这似乎工作正常。

unsigned short strlen4(char *str)
{
    for (int i = 0; ; i++) if (str[i] == '\0') return i;
}

有什么想法吗?

更新!

这可能是实现 strlen 最有效的方法。大多数编译器都使用这种以某种方式实现的编译器。

这可能有点难以理解,尤其是如果没有学习指针的话。

size_t strlen(char *str)
{
    register const char *s;
    for (s = str; *s; ++s);
    return(s - str);
}

0
投票

与其他人所说的相反,如果遵循一些合理的限制,这是“不可能”的。限制是:

一个非空语句
  • 函数体中的声明(具有非空体的复合语句总共至少有两条语句) 与真实签名相同
  • strlen
  • 无递归
  • 任何具有
strlen

签名的函数都必须有一个 return 语句。 return 语句由

return
关键字和表达式组成。 C 语言没有执行循环的表达式。为此需要一个声明,但这个位置是为 return 声明保留的。

如果放宽这些限制(例如,更改签名,或者不计算返回语句和/或声明和/或复合语句主体,只要它们是“简单”的,作为单独的“行”),那么任务就成为可能而且相当简单,正如这里和互联网上的许多示例所示。o


0
投票
与 str[i] 相比,上面递增指针的代码会执行得更好,因为索引 str[i] 的计算结果为:*(str + i),这是每个循环都会执行的加法操作,而递增操作是更快。

此外,与 strlen(const char *str, size_t *len) 相比,调用者不需要提供额外的参数。

最后,按照最初的要求,它在一行上。


0
投票

unsigned int strlen(const char *s) { int l;for(l=0;s[l]!='\0';l++);return l; }

您可以将“ ”替换为零,但我更喜欢这样

希望有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.