繁体   English   中英

C strlen()实现在一行代码中

[英]C strlen() implementation in one line of code

昨天我在面试时被要求在C中实现strlen()而不使用任何标准函数,所有这些都是手工完成的。 作为一个绝对的业余爱好者,我用while循环实现了原始版本。 看看这个,我的面试官说它可以只用一行代码实现。 我当时无法使用该术语生成此代码。 在采访之后,我问了我的同事们,他们中最有经验的人给了我这件真的很好的作品:

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

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

  • 没有任何汇编程序
  • 没有任何C函数存在于库中
  • 而不只是拼写一些代码串

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

类似于@ DanielKamilKozar的答案,但是使用for循环,你可以在没有for循环体的情况下执行此操作,并且len在函数中正确初始化:

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

我能想到的最好的是这个,但它不是标准的strlen因为函数本身有不同的原型。 此外,它假设*len在开始时为零。

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

我很好奇标准strlen如何在“一行代码”中实现,因为它需要一个return ,这是“一行代码”,从你发布的内容来判断。

也就是说,我同意评论说这是一个令人难以置信的愚蠢的面试问题。

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

如果这不是一个函数,这个单行可能是计算任何以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;
}

这似乎工作正常。

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

有什么想法吗?

UPDATE!

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

这可能有点难以理解,特别是如果没有学习指针。

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

那个空的for循环怎么样? 喜欢

int i=0;
for(; str[i]!=0; ++i);
size_t strlen (const char* str) {
    for (const char* s1 = str; ; s1++) if (!(*s1)) return s1 - str; 
}

与str [i]相比,增加指针的上述代码将表现更好,因为索引str [i]将评估为:*(str + i)这是对每个循环完成的加法运算,而增量运算更快。

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

最后,根据原始请求,它在一行上。

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

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

具有strlen签名的任何函数都必须具有return语句。 return语句由return关键字和表达式组成。 C语言没有执行循环的表达式。 需要一个声明,但这个位置是为return语句保留的。

如果放松这些限制(例如,更改签名,或者不计算复合语句的返回语句和/或声明和/或正文,只要它们是“简单”,作为单独的“行”),任务就变得可能,相当简单,正如在这里和整个互联网上的许多例子中都可以看到的那样

本地代码

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

您可以将'\\ 0'替换为零,但我更喜欢它

希望能帮助到你。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM