昨天我在接受采访时被要求在C中实现strlen()而不使用任何标准函数,所有这些都是手工完成的。作为一个绝对的业余爱好者,我用while循环实现了原始版本。看看这个,我的面试官说它可以只用一行代码实现。我当时无法使用该术语生成此代码。在采访之后,我问了我的同事,他们中最有经验的人给了我这件真的很好的作品:
size_t str_len (const char *str)
{
return (*str) ? str_len(++str) + 1 : 0;
}
所以有一个问题,是否可以不使用递归,如果是,怎么样? 术语:
请注意,这不是优化或实际使用的问题,只是完成任务的可能性。
答案 0 :(得分:10)
与@ DanielKamilKozar的答案类似,但是使用for循环,你可以在没有for-loop body的情况下执行此操作,len
在函数中正确初始化:
void my_strlen(const char *str, size_t *len)
{
for (*len = 0; str[*len]; (*len)++);
}
答案 1 :(得分:6)
我能想到的最好的是这个,但它不是标准strlen
,因为函数本身有不同的原型。此外,它假设*len
在开始时为零。
void my_strlen(const char *str, size_t *len)
{
while(*(str++)) (*len)++;
}
我很好奇标准strlen
如何在"一行代码"中实现,因为它需要return
,是"一行代码",根据您发布的内容判断。
那就是说,我同意评论说这是一个非常愚蠢的面试问题。
答案 2 :(得分:5)
size_t str_len (const char *str)
{
for (size_t len = 0;;++len) if (str[len]==0) return len;
}
答案 3 :(得分: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;
}
答案 4 :(得分:2)
这似乎工作正常。
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);
}
答案 5 :(得分:1)
空循环怎么样?像
int i=0;
for(; str[i]!=0; ++i);
答案 6 :(得分:0)
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)相比,不需要调用者提供的额外参数。
最后,根据原始请求,它在一行上。
答案 7 :(得分:0)
与其他人所说的相反,如果遵循一些合理的限制,则不可能。限制是:
strlen
签名为strlen
的任何函数都必须有return语句。 return语句由return
关键字和表达式组成。 C语言没有执行循环的表达式。需要一个声明,但这个位置是为return语句保留的。
如果放宽这些限制(例如,更改签名,或者不计算复合语句的返回语句和/或声明和/或正文,只要它们“简单”,作为单独的“行”)任务变得可能而且相当简单,正如在这里和整个互联网上的许多例子中都可以看到的那样.o
答案 8 :(得分:0)
原生代码
unsigned int strlen(const char *s)
{
int l;for(l=0;s[l]!='\0';l++);return l;
}
您可以替换' \ 0'零,但我更喜欢它
希望它有所帮助。